forked from TrueCloudLab/frostfs-node
Initial commit
Initial public review release v0.10.0
This commit is contained in:
commit
dadfd90dcd
276 changed files with 46331 additions and 0 deletions
346
cmd/neofs-node/defaults.go
Normal file
346
cmd/neofs-node/defaults.go
Normal file
|
@ -0,0 +1,346 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||
"github.com/nspcc-dev/neofs-node/lib/core"
|
||||
"github.com/nspcc-dev/neofs-node/modules/morph"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func setDefaults(v *viper.Viper) {
|
||||
// Logger section
|
||||
{
|
||||
v.SetDefault("logger.level", "debug")
|
||||
v.SetDefault("logger.format", "console")
|
||||
v.SetDefault("logger.trace_level", "fatal")
|
||||
v.SetDefault("logger.no_disclaimer", false) // to disable app_name and app_version
|
||||
|
||||
v.SetDefault("logger.sampling.initial", 1000) // todo: add description
|
||||
v.SetDefault("logger.sampling.thereafter", 1000) // todo: add description
|
||||
}
|
||||
|
||||
// Transport section
|
||||
{
|
||||
v.SetDefault("transport.attempts_count", 5)
|
||||
v.SetDefault("transport.attempts_ttl", "30s")
|
||||
}
|
||||
|
||||
// Peers section
|
||||
{
|
||||
v.SetDefault("peers.metrics_timeout", "5s")
|
||||
v.SetDefault("peers.connections_ttl", "30s")
|
||||
v.SetDefault("peers.connections_idle", "30s")
|
||||
v.SetDefault("peers.keep_alive.ttl", "30s")
|
||||
v.SetDefault("peers.keep_alive.ping", "100ms")
|
||||
}
|
||||
|
||||
// Muxer session
|
||||
{
|
||||
v.SetDefault("muxer.http.read_buffer_size", 0)
|
||||
v.SetDefault("muxer.http.write_buffer_size", 0)
|
||||
v.SetDefault("muxer.http.read_timeout", 0)
|
||||
v.SetDefault("muxer.http.write_timeout", 0)
|
||||
}
|
||||
|
||||
// Node section
|
||||
{
|
||||
v.SetDefault("node.proto", "tcp") // tcp or udp
|
||||
v.SetDefault("node.address", ":8080")
|
||||
v.SetDefault("node.shutdown_ttl", "30s")
|
||||
v.SetDefault("node.private_key", "keys/node_00.key")
|
||||
|
||||
v.SetDefault("node.grpc.logging", true)
|
||||
v.SetDefault("node.grpc.metrics", true)
|
||||
v.SetDefault("node.grpc.billing", true)
|
||||
|
||||
// Contains public keys, which can send requests to state.DumpConfig
|
||||
// for now, in the future, should be replaced with ACL or something else.
|
||||
v.SetDefault("node.rpc.owners", []string{
|
||||
// By default we add user.key
|
||||
// TODO should be removed before public release:
|
||||
// or add into default Dockerfile `NEOFS_NODE_RPC_OWNERS_0=`
|
||||
"031a6c6fbbdf02ca351745fa86b9ba5a9452d785ac4f7fc2b7548ca2a46c4fcf4a",
|
||||
})
|
||||
}
|
||||
|
||||
// Storage section
|
||||
{
|
||||
storageTypes := []string{
|
||||
core.BlobStore.String(),
|
||||
core.MetaStore.String(),
|
||||
core.SpaceMetricsStore.String(),
|
||||
}
|
||||
|
||||
for i := range storageTypes {
|
||||
v.SetDefault("storage."+storageTypes[i]+".bucket", "boltdb")
|
||||
v.SetDefault("storage."+storageTypes[i]+".path", "./temp/storage/"+storageTypes[i])
|
||||
v.SetDefault("storage."+storageTypes[i]+".perm", 0777)
|
||||
// v.SetDefault("storage."+storageTypes[i]+".no_grow_sync", false)
|
||||
// v.SetDefault("storage."+storageTypes[i]+".lock_timeout", "30s")
|
||||
}
|
||||
}
|
||||
|
||||
// Object section
|
||||
{
|
||||
v.SetDefault("object.max_processing_size", 100) // size in MB, use 0 to remove restriction
|
||||
v.SetDefault("object.workers_count", 5)
|
||||
v.SetDefault("object.assembly", true)
|
||||
v.SetDefault("object.window_size", 3)
|
||||
|
||||
v.SetDefault("object.transformers.payload_limiter.max_payload_size", 5000) // size in KB
|
||||
|
||||
// algorithm used for salt applying in range hash, for now only xor is available
|
||||
v.SetDefault("object.salitor", "xor")
|
||||
|
||||
// set true to check container ACL rules
|
||||
v.SetDefault("object.check_acl", true)
|
||||
|
||||
v.SetDefault("object.dial_timeout", "500ms")
|
||||
rpcs := []string{"put", "get", "delete", "head", "search", "range", "range_hash"}
|
||||
for i := range rpcs {
|
||||
v.SetDefault("object."+rpcs[i]+".timeout", "5s")
|
||||
v.SetDefault("object."+rpcs[i]+".log_errs", false)
|
||||
}
|
||||
}
|
||||
|
||||
// Replication section
|
||||
{
|
||||
v.SetDefault("replication.manager.pool_size", 100)
|
||||
v.SetDefault("replication.manager.pool_expansion_rate", 0.1)
|
||||
v.SetDefault("replication.manager.read_pool_interval", "500ms")
|
||||
v.SetDefault("replication.manager.push_task_timeout", "1s")
|
||||
v.SetDefault("replication.manager.placement_honorer_enabled", true)
|
||||
v.SetDefault("replication.manager.capacities.replicate", 1)
|
||||
v.SetDefault("replication.manager.capacities.restore", 1)
|
||||
v.SetDefault("replication.manager.capacities.garbage", 1)
|
||||
|
||||
v.SetDefault("replication.placement_honorer.chan_capacity", 1)
|
||||
v.SetDefault("replication.placement_honorer.result_timeout", "1s")
|
||||
v.SetDefault("replication.placement_honorer.timeouts.put", "5s")
|
||||
v.SetDefault("replication.placement_honorer.timeouts.get", "5s")
|
||||
|
||||
v.SetDefault("replication.location_detector.chan_capacity", 1)
|
||||
v.SetDefault("replication.location_detector.result_timeout", "1s")
|
||||
v.SetDefault("replication.location_detector.timeouts.search", "5s")
|
||||
|
||||
v.SetDefault("replication.storage_validator.chan_capacity", 1)
|
||||
v.SetDefault("replication.storage_validator.result_timeout", "1s")
|
||||
v.SetDefault("replication.storage_validator.salt_size", 64) // size in bytes
|
||||
v.SetDefault("replication.storage_validator.max_payload_range_size", 64) // size in bytes
|
||||
v.SetDefault("replication.storage_validator.payload_range_count", 3)
|
||||
v.SetDefault("replication.storage_validator.salitor", "xor")
|
||||
v.SetDefault("replication.storage_validator.timeouts.get", "5s")
|
||||
v.SetDefault("replication.storage_validator.timeouts.head", "5s")
|
||||
v.SetDefault("replication.storage_validator.timeouts.range_hash", "5s")
|
||||
|
||||
v.SetDefault("replication.replicator.chan_capacity", 1)
|
||||
v.SetDefault("replication.replicator.result_timeout", "1s")
|
||||
v.SetDefault("replication.replicator.timeouts.put", "5s")
|
||||
|
||||
v.SetDefault("replication.restorer.chan_capacity", 1)
|
||||
v.SetDefault("replication.restorer.result_timeout", "1s")
|
||||
v.SetDefault("replication.restorer.timeouts.get", "5s")
|
||||
v.SetDefault("replication.restorer.timeouts.head", "5s")
|
||||
}
|
||||
|
||||
// PPROF section
|
||||
{
|
||||
v.SetDefault("pprof.enabled", true)
|
||||
v.SetDefault("pprof.address", ":6060")
|
||||
v.SetDefault("pprof.shutdown_ttl", "10s")
|
||||
// v.SetDefault("pprof.read_timeout", "10s")
|
||||
// v.SetDefault("pprof.read_header_timeout", "10s")
|
||||
// v.SetDefault("pprof.write_timeout", "10s")
|
||||
// v.SetDefault("pprof.idle_timeout", "10s")
|
||||
// v.SetDefault("pprof.max_header_bytes", 1024)
|
||||
}
|
||||
|
||||
// Metrics section
|
||||
{
|
||||
v.SetDefault("metrics.enabled", true)
|
||||
v.SetDefault("metrics.address", ":8090")
|
||||
v.SetDefault("metrics.shutdown_ttl", "10s")
|
||||
// v.SetDefault("metrics.read_header_timeout", "10s")
|
||||
// v.SetDefault("metrics.write_timeout", "10s")
|
||||
// v.SetDefault("metrics.idle_timeout", "10s")
|
||||
// v.SetDefault("metrics.max_header_bytes", 1024)
|
||||
}
|
||||
|
||||
// Workers section
|
||||
{
|
||||
workers := []string{
|
||||
"peers",
|
||||
"boot",
|
||||
"replicator",
|
||||
"metrics",
|
||||
"event_listener",
|
||||
}
|
||||
|
||||
for i := range workers {
|
||||
v.SetDefault("workers."+workers[i]+".immediately", true)
|
||||
v.SetDefault("workers."+workers[i]+".disabled", false)
|
||||
// v.SetDefault("workers."+workers[i]+".timer", "5s") // run worker every 5sec and reset timer after job
|
||||
// v.SetDefault("workers."+workers[i]+".ticker", "5s") // run worker every 5sec
|
||||
}
|
||||
}
|
||||
|
||||
// Morph section
|
||||
{
|
||||
|
||||
// Endpoint
|
||||
v.SetDefault(
|
||||
morph.EndpointOptPath(),
|
||||
"http://morph_chain.localtest.nspcc.ru:30333",
|
||||
)
|
||||
|
||||
// Dial timeout
|
||||
v.SetDefault(
|
||||
morph.DialTimeoutOptPath(),
|
||||
5*time.Second,
|
||||
)
|
||||
|
||||
v.SetDefault(
|
||||
morph.MagicNumberOptPath(),
|
||||
uint32(netmode.PrivNet),
|
||||
)
|
||||
|
||||
{ // Event listener
|
||||
// Endpoint
|
||||
v.SetDefault(
|
||||
morph.ListenerEndpointOptPath(),
|
||||
"ws://morph_chain.localtest.nspcc.ru:30333/ws",
|
||||
)
|
||||
|
||||
// Dial timeout
|
||||
v.SetDefault(
|
||||
morph.ListenerDialTimeoutOptPath(),
|
||||
5*time.Second,
|
||||
)
|
||||
}
|
||||
|
||||
{ // Common parameters
|
||||
for _, name := range morph.ContractNames {
|
||||
// Script hash
|
||||
v.SetDefault(
|
||||
morph.ScriptHashOptPath(name),
|
||||
"c77ecae9773ad0c619ad59f7f2dd6f585ddc2e70", // LE
|
||||
)
|
||||
|
||||
// Invocation fee
|
||||
v.SetDefault(
|
||||
morph.InvocationFeeOptPath(name),
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
{ // Container
|
||||
// Set EACL method name
|
||||
v.SetDefault(
|
||||
morph.ContainerContractSetEACLOptPath(),
|
||||
"SetEACL",
|
||||
)
|
||||
|
||||
// Get EACL method name
|
||||
v.SetDefault(
|
||||
morph.ContainerContractEACLOptPath(),
|
||||
"EACL",
|
||||
)
|
||||
|
||||
// Put method name
|
||||
v.SetDefault(
|
||||
morph.ContainerContractPutOptPath(),
|
||||
"Put",
|
||||
)
|
||||
|
||||
// Get method name
|
||||
v.SetDefault(
|
||||
morph.ContainerContractGetOptPath(),
|
||||
"Get",
|
||||
)
|
||||
|
||||
// Delete method name
|
||||
v.SetDefault(
|
||||
morph.ContainerContractDelOptPath(),
|
||||
"Delete",
|
||||
)
|
||||
|
||||
// List method name
|
||||
v.SetDefault(
|
||||
morph.ContainerContractListOptPath(),
|
||||
"List",
|
||||
)
|
||||
}
|
||||
|
||||
{ // Reputation
|
||||
// Put method name
|
||||
v.SetDefault(
|
||||
morph.ReputationContractPutOptPath(),
|
||||
"Put",
|
||||
)
|
||||
|
||||
// List method name
|
||||
v.SetDefault(
|
||||
morph.ReputationContractListOptPath(),
|
||||
"List",
|
||||
)
|
||||
}
|
||||
|
||||
{ // Netmap
|
||||
// AddPeer method name
|
||||
v.SetDefault(
|
||||
morph.NetmapContractAddPeerOptPath(),
|
||||
"AddPeer",
|
||||
)
|
||||
|
||||
// New epoch method name
|
||||
v.SetDefault(
|
||||
morph.NetmapContractNewEpochOptPath(),
|
||||
"NewEpoch",
|
||||
)
|
||||
|
||||
// Netmap method name
|
||||
v.SetDefault(
|
||||
morph.NetmapContractNetmapOptPath(),
|
||||
"Netmap",
|
||||
)
|
||||
|
||||
// Update state method name
|
||||
v.SetDefault(
|
||||
morph.NetmapContractUpdateStateOptPath(),
|
||||
"UpdateState",
|
||||
)
|
||||
|
||||
// IR list method name
|
||||
v.SetDefault(
|
||||
morph.NetmapContractIRListOptPath(),
|
||||
"InnerRingList",
|
||||
)
|
||||
|
||||
// New epoch event type
|
||||
v.SetDefault(
|
||||
morph.ContractEventOptPath(
|
||||
morph.NetmapContractName,
|
||||
morph.NewEpochEventType,
|
||||
),
|
||||
"NewEpoch",
|
||||
)
|
||||
}
|
||||
|
||||
{ // Balance
|
||||
// balanceOf method name
|
||||
v.SetDefault(
|
||||
morph.BalanceContractBalanceOfOptPath(),
|
||||
"balanceOf",
|
||||
)
|
||||
|
||||
// decimals method name
|
||||
v.SetDefault(
|
||||
morph.BalanceContractDecimalsOfOptPath(),
|
||||
"decimals",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
146
cmd/neofs-node/main.go
Normal file
146
cmd/neofs-node/main.go
Normal file
|
@ -0,0 +1,146 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"flag"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/service"
|
||||
state2 "github.com/nspcc-dev/neofs-api-go/state"
|
||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||
"github.com/nspcc-dev/neofs-node/lib/fix"
|
||||
"github.com/nspcc-dev/neofs-node/lib/fix/config"
|
||||
"github.com/nspcc-dev/neofs-node/lib/fix/web"
|
||||
"github.com/nspcc-dev/neofs-node/lib/fix/worker"
|
||||
"github.com/nspcc-dev/neofs-node/lib/muxer"
|
||||
"github.com/nspcc-dev/neofs-node/misc"
|
||||
"github.com/nspcc-dev/neofs-node/modules/node"
|
||||
"github.com/nspcc-dev/neofs-node/services/public/state"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type params struct {
|
||||
dig.In
|
||||
|
||||
Debug web.Profiler `optional:"true"`
|
||||
Metric web.Metrics `optional:"true"`
|
||||
Worker worker.Workers `optional:"true"`
|
||||
Muxer muxer.Mux
|
||||
Logger *zap.Logger
|
||||
}
|
||||
|
||||
var (
|
||||
healthCheck bool
|
||||
configFile string
|
||||
)
|
||||
|
||||
func runner(ctx context.Context, p params) error {
|
||||
// create combined service, that would start/stop all
|
||||
svc := fix.NewServices(p.Debug, p.Metric, p.Muxer, p.Worker)
|
||||
|
||||
p.Logger.Info("start services")
|
||||
svc.Start(ctx)
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
p.Logger.Info("stop services")
|
||||
svc.Stop()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: this is a copypaste from node settings constructor
|
||||
func keyFromCfg(v *viper.Viper) (*ecdsa.PrivateKey, error) {
|
||||
switch key := v.GetString("node.private_key"); key {
|
||||
case "":
|
||||
return nil, errors.New("`node.private_key` could not be empty")
|
||||
case "generated":
|
||||
return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
default:
|
||||
return crypto.LoadPrivateKey(key)
|
||||
}
|
||||
}
|
||||
|
||||
func runHealthCheck() {
|
||||
if !healthCheck {
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
cfg, err := config.NewConfig(config.Params{
|
||||
File: configFile,
|
||||
Prefix: misc.Prefix,
|
||||
Name: misc.NodeName,
|
||||
Version: misc.Version,
|
||||
|
||||
AppDefaults: setDefaults,
|
||||
})
|
||||
check(err)
|
||||
|
||||
addr := cfg.GetString("node.address")
|
||||
|
||||
key, err := keyFromCfg(cfg)
|
||||
if err != nil {
|
||||
check(err)
|
||||
}
|
||||
|
||||
con, err := grpc.DialContext(ctx, addr,
|
||||
// TODO: we must provide grpc.WithInsecure() or set credentials
|
||||
grpc.WithInsecure())
|
||||
check(err)
|
||||
|
||||
req := new(state.HealthRequest)
|
||||
req.SetTTL(service.NonForwardingTTL)
|
||||
if err := service.SignRequestData(key, req); err != nil {
|
||||
check(err)
|
||||
}
|
||||
|
||||
res, err := state2.NewStatusClient(con).
|
||||
HealthCheck(ctx, req)
|
||||
check(errors.Wrapf(err, "address: %q", addr))
|
||||
|
||||
var exitCode int
|
||||
|
||||
if !res.Healthy {
|
||||
exitCode = 2
|
||||
}
|
||||
_, _ = os.Stdout.Write([]byte(res.Status + "\n"))
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.BoolVar(&healthCheck, "health", healthCheck, "run health-check")
|
||||
|
||||
// todo: if configFile is empty, we can check './config.yml' manually
|
||||
flag.StringVar(&configFile, "config", configFile, "use config.yml file")
|
||||
flag.Parse()
|
||||
|
||||
runHealthCheck()
|
||||
|
||||
fix.New(&fix.Settings{
|
||||
File: configFile,
|
||||
Name: misc.NodeName,
|
||||
Prefix: misc.Prefix,
|
||||
Runner: runner,
|
||||
Build: misc.Build,
|
||||
Version: misc.Version,
|
||||
|
||||
AppDefaults: setDefaults,
|
||||
}, node.Module).RunAndCatch()
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue