Add Inner Ring code
This commit is contained in:
parent
dadfd90dcd
commit
b7b5079934
400 changed files with 11420 additions and 8690 deletions
65
cmd/neofs-node/modules/node/audit.go
Normal file
65
cmd/neofs-node/modules/node/audit.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/session"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/network/peers"
|
||||
object "github.com/nspcc-dev/neofs-node/pkg/network/transport/object/grpc"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/placement"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/replication/storage"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/transport"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
cnrHandlerParams struct {
|
||||
*viper.Viper
|
||||
*zap.Logger
|
||||
Placer *placement.PlacementWrapper
|
||||
PeerStore peers.Store
|
||||
Peers peers.Interface
|
||||
TimeoutsPrefix string
|
||||
Key *ecdsa.PrivateKey
|
||||
|
||||
TokenStore session.PrivateTokenStore
|
||||
}
|
||||
)
|
||||
|
||||
func newObjectsContainerHandler(p cnrHandlerParams) (transport.SelectiveContainerExecutor, error) {
|
||||
as, err := storage.NewAddressStore(p.PeerStore, p.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
multiTransport, err := object.NewMultiTransport(object.MultiTransportParams{
|
||||
AddressStore: as,
|
||||
EpochReceiver: p.Placer,
|
||||
RemoteService: object.NewRemoteService(p.Peers),
|
||||
Logger: p.Logger,
|
||||
Key: p.Key,
|
||||
PutTimeout: p.Viper.GetDuration(p.TimeoutsPrefix + ".timeouts.put"),
|
||||
GetTimeout: p.Viper.GetDuration(p.TimeoutsPrefix + ".timeouts.get"),
|
||||
HeadTimeout: p.Viper.GetDuration(p.TimeoutsPrefix + ".timeouts.head"),
|
||||
SearchTimeout: p.Viper.GetDuration(p.TimeoutsPrefix + ".timeouts.search"),
|
||||
RangeHashTimeout: p.Viper.GetDuration(p.TimeoutsPrefix + ".timeouts.range_hash"),
|
||||
DialTimeout: p.Viper.GetDuration("object.dial_timeout"),
|
||||
|
||||
PrivateTokenStore: p.TokenStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exec, err := transport.NewContainerTraverseExecutor(multiTransport)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return transport.NewObjectContainerHandler(transport.ObjectContainerHandlerParams{
|
||||
NodeLister: p.Placer,
|
||||
Executor: exec,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
}
|
31
cmd/neofs-node/modules/node/container.go
Normal file
31
cmd/neofs-node/modules/node/container.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
svc "github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/bootstrap"
|
||||
eacl "github.com/nspcc-dev/neofs-node/pkg/core/container/acl/extended/storage"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/container/storage"
|
||||
container "github.com/nspcc-dev/neofs-node/pkg/network/transport/container/grpc"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type cnrParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
|
||||
Healthy svc.HealthyClient
|
||||
|
||||
ExtendedACLStore eacl.Storage
|
||||
|
||||
ContainerStorage storage.Storage
|
||||
}
|
||||
|
||||
func newContainerService(p cnrParams) (container.Service, error) {
|
||||
return container.New(container.Params{
|
||||
Logger: p.Logger,
|
||||
Healthy: p.Healthy,
|
||||
Store: p.ContainerStorage,
|
||||
ExtendedACLStore: p.ExtendedACLStore,
|
||||
})
|
||||
}
|
35
cmd/neofs-node/modules/node/core.go
Normal file
35
cmd/neofs-node/modules/node/core.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket/boltdb"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket/fsbucket"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Buckets map[string]bucket.Bucket
|
||||
|
||||
const (
|
||||
fsBucket = "fsbucket"
|
||||
boltBucket = "bolt"
|
||||
)
|
||||
|
||||
func newBuckets(v *viper.Viper) (Buckets, error) {
|
||||
var (
|
||||
err error
|
||||
mBuckets = make(Buckets)
|
||||
)
|
||||
|
||||
if mBuckets[fsBucket], err = fsbucket.NewBucket(v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
boltOpts, err := boltdb.NewOptions(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if mBuckets[boltBucket], err = boltdb.NewBucket(&boltOpts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mBuckets, nil
|
||||
}
|
53
cmd/neofs-node/modules/node/localstore.go
Normal file
53
cmd/neofs-node/modules/node/localstore.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore"
|
||||
meta2 "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/meta"
|
||||
metrics2 "github.com/nspcc-dev/neofs-node/pkg/services/metrics"
|
||||
"go.uber.org/atomic"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
localstoreParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
Buckets Buckets
|
||||
Counter *atomic.Float64
|
||||
Collector metrics2.Collector
|
||||
}
|
||||
|
||||
metaIterator struct {
|
||||
iter localstore.Iterator
|
||||
}
|
||||
)
|
||||
|
||||
func newMetaIterator(iter localstore.Iterator) meta2.Iterator {
|
||||
return &metaIterator{iter: iter}
|
||||
}
|
||||
|
||||
func (m *metaIterator) Iterate(handler meta2.IterateFunc) error {
|
||||
return m.iter.Iterate(nil, func(objMeta *localstore.ObjectMeta) bool {
|
||||
return handler == nil || handler(objMeta.Object) != nil
|
||||
})
|
||||
}
|
||||
|
||||
func newLocalstore(p localstoreParams) (localstore.Localstore, error) {
|
||||
local, err := localstore.New(localstore.Params{
|
||||
BlobBucket: p.Buckets[fsBucket],
|
||||
MetaBucket: p.Buckets[boltBucket],
|
||||
Logger: p.Logger,
|
||||
Collector: p.Collector,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iter := newMetaIterator(local)
|
||||
p.Collector.SetCounter(local)
|
||||
p.Collector.SetIterator(iter)
|
||||
|
||||
return local, nil
|
||||
}
|
46
cmd/neofs-node/modules/node/metrics.go
Normal file
46
cmd/neofs-node/modules/node/metrics.go
Normal file
|
@ -0,0 +1,46 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
metrics "github.com/nspcc-dev/neofs-node/pkg/network/transport/metrics/grpc"
|
||||
metrics2 "github.com/nspcc-dev/neofs-node/pkg/services/metrics"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/atomic"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
metricsParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
Options []string `name:"node_options"`
|
||||
Viper *viper.Viper
|
||||
Buckets Buckets
|
||||
}
|
||||
|
||||
metricsServiceParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
Collector metrics2.Collector
|
||||
}
|
||||
)
|
||||
|
||||
func newObjectCounter() *atomic.Float64 { return atomic.NewFloat64(0) }
|
||||
|
||||
func newMetricsService(p metricsServiceParams) (metrics.Service, error) {
|
||||
return metrics.New(metrics.Params{
|
||||
Logger: p.Logger,
|
||||
Collector: p.Collector,
|
||||
})
|
||||
}
|
||||
|
||||
func newMetricsCollector(p metricsParams) (metrics2.Collector, error) {
|
||||
return metrics2.New(metrics2.Params{
|
||||
Options: p.Options,
|
||||
Logger: p.Logger,
|
||||
Interval: p.Viper.GetDuration("metrics_collector.interval"),
|
||||
MetricsStore: p.Buckets[fsBucket],
|
||||
})
|
||||
}
|
89
cmd/neofs-node/modules/node/module.go
Normal file
89
cmd/neofs-node/modules/node/module.go
Normal file
|
@ -0,0 +1,89 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-api-go/session"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/bootstrap"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/fix/module"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/fix/worker"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/grpc"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/morph"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/network"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/settings"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/workers"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||
libboot "github.com/nspcc-dev/neofs-node/pkg/network/bootstrap"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/network/peers"
|
||||
metrics2 "github.com/nspcc-dev/neofs-node/pkg/services/metrics"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/replication"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type jobParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
Viper *viper.Viper
|
||||
Peers peers.Store
|
||||
|
||||
Replicator replication.Manager
|
||||
PeersInterface peers.Interface
|
||||
Metrics metrics2.Collector
|
||||
|
||||
MorphEventListener event.Listener
|
||||
|
||||
NodeRegisterer *libboot.Registerer
|
||||
}
|
||||
|
||||
// Module is a NeoFS node module.
|
||||
var Module = module.Module{
|
||||
{Constructor: attachJobs},
|
||||
{Constructor: newPeerstore},
|
||||
{Constructor: attachServices},
|
||||
{Constructor: newBuckets},
|
||||
{Constructor: newMetricsCollector},
|
||||
{Constructor: newObjectCounter},
|
||||
|
||||
// -- Container gRPC handlers -- //
|
||||
{Constructor: newContainerService},
|
||||
|
||||
// -- gRPC Services -- //
|
||||
|
||||
// -- Local store -- //
|
||||
{Constructor: newLocalstore},
|
||||
|
||||
// -- Object manager -- //
|
||||
{Constructor: newObjectManager},
|
||||
|
||||
// -- Replication manager -- //
|
||||
{Constructor: newReplicationManager},
|
||||
|
||||
// -- Session service -- //
|
||||
{Constructor: session.NewMapTokenStore},
|
||||
{Constructor: newSessionService},
|
||||
|
||||
// -- Placement tool -- //
|
||||
{Constructor: newPlacementTool},
|
||||
|
||||
// metrics service -- //
|
||||
{Constructor: newMetricsService},
|
||||
}.Append(
|
||||
// app specific modules:
|
||||
grpc.Module,
|
||||
network.Module,
|
||||
workers.Module,
|
||||
settings.Module,
|
||||
bootstrap.Module,
|
||||
morph.Module,
|
||||
)
|
||||
|
||||
func attachJobs(p jobParams) worker.Jobs {
|
||||
return worker.Jobs{
|
||||
"peers": p.PeersInterface.Job,
|
||||
"metrics": p.Metrics.Start,
|
||||
"event_listener": p.MorphEventListener.Listen,
|
||||
"replicator": p.Replicator.Process,
|
||||
"boot": p.NodeRegisterer.Bootstrap,
|
||||
}
|
||||
}
|
201
cmd/neofs-node/modules/node/objectmanager.go
Normal file
201
cmd/neofs-node/modules/node/objectmanager.go
Normal file
|
@ -0,0 +1,201 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/bootstrap"
|
||||
"github.com/nspcc-dev/neofs-api-go/hash"
|
||||
apiobj "github.com/nspcc-dev/neofs-api-go/object"
|
||||
"github.com/nspcc-dev/neofs-api-go/session"
|
||||
eacl "github.com/nspcc-dev/neofs-node/pkg/core/container/acl/extended/storage"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/container/storage"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore"
|
||||
contract "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/network/peers"
|
||||
object "github.com/nspcc-dev/neofs-node/pkg/network/transport/object/grpc"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/placement"
|
||||
storage2 "github.com/nspcc-dev/neofs-node/pkg/services/object_manager/replication/storage"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/transformer"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/transport"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/transport/storagegroup"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
objectManagerParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
Viper *viper.Viper
|
||||
LocalStore localstore.Localstore
|
||||
|
||||
PeersInterface peers.Interface
|
||||
|
||||
Peers peers.Store
|
||||
Placement placement.Component
|
||||
TokenStore session.PrivateTokenStore
|
||||
Options []string `name:"node_options"`
|
||||
Key *ecdsa.PrivateKey
|
||||
|
||||
NetMapClient *contract.Wrapper
|
||||
|
||||
Placer *placement.PlacementWrapper
|
||||
|
||||
ExtendedACLStore eacl.Storage
|
||||
|
||||
ContainerStorage storage.Storage
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
transformersSectionPath = "object.transformers."
|
||||
)
|
||||
|
||||
const xorSalitor = "xor"
|
||||
|
||||
func newObjectManager(p objectManagerParams) (object.Service, error) {
|
||||
var sltr object.Salitor
|
||||
|
||||
if p.Viper.GetString("object.salitor") == xorSalitor {
|
||||
sltr = hash.SaltXOR
|
||||
}
|
||||
|
||||
as, err := storage2.NewAddressStore(p.Peers, p.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rs := object.NewRemoteService(p.PeersInterface)
|
||||
|
||||
pto := p.Viper.GetDuration("object.put.timeout")
|
||||
gto := p.Viper.GetDuration("object.get.timeout")
|
||||
hto := p.Viper.GetDuration("object.head.timeout")
|
||||
sto := p.Viper.GetDuration("object.search.timeout")
|
||||
rhto := p.Viper.GetDuration("object.range_hash.timeout")
|
||||
dto := p.Viper.GetDuration("object.dial_timeout")
|
||||
|
||||
tr, err := object.NewMultiTransport(object.MultiTransportParams{
|
||||
AddressStore: as,
|
||||
EpochReceiver: p.Placer,
|
||||
RemoteService: rs,
|
||||
Logger: p.Logger,
|
||||
Key: p.Key,
|
||||
PutTimeout: pto,
|
||||
GetTimeout: gto,
|
||||
HeadTimeout: hto,
|
||||
SearchTimeout: sto,
|
||||
RangeHashTimeout: rhto,
|
||||
DialTimeout: dto,
|
||||
|
||||
PrivateTokenStore: p.TokenStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
exec, err := transport.NewContainerTraverseExecutor(tr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
selectiveExec, err := transport.NewObjectContainerHandler(transport.ObjectContainerHandlerParams{
|
||||
NodeLister: p.Placer,
|
||||
Executor: exec,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sgInfoRecv, err := storagegroup.NewStorageGroupInfoReceiver(storagegroup.StorageGroupInfoReceiverParams{
|
||||
SelectiveContainerExecutor: selectiveExec,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
verifier, err := storage2.NewLocalIntegrityVerifier()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
trans, err := transformer.NewTransformer(transformer.Params{
|
||||
SGInfoReceiver: sgInfoRecv,
|
||||
EpochReceiver: p.Placer,
|
||||
SizeLimit: uint64(p.Viper.GetInt64(transformersSectionPath+"payload_limiter.max_payload_size") * apiobj.UnitsKB),
|
||||
Verifier: verifier,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
verifier, err = storage2.NewLocalHeadIntegrityVerifier()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return object.New(&object.Params{
|
||||
Verifier: verifier,
|
||||
Salitor: sltr,
|
||||
LocalStore: p.LocalStore,
|
||||
MaxProcessingSize: p.Viper.GetUint64("object.max_processing_size") * uint64(apiobj.UnitsMB),
|
||||
StorageCapacity: bootstrap.NodeInfo{Options: p.Options}.Capacity() * uint64(apiobj.UnitsGB),
|
||||
PoolSize: p.Viper.GetInt("object.workers_count"),
|
||||
Placer: p.Placer,
|
||||
Transformer: trans,
|
||||
ObjectRestorer: transformer.NewRestorePipeline(
|
||||
transformer.SplitRestorer(),
|
||||
),
|
||||
RemoteService: rs,
|
||||
AddressStore: as,
|
||||
Logger: p.Logger,
|
||||
TokenStore: p.TokenStore,
|
||||
EpochReceiver: p.Placer,
|
||||
PlacementWrapper: p.Placer,
|
||||
Key: p.Key,
|
||||
CheckACL: p.Viper.GetBool("object.check_acl"),
|
||||
DialTimeout: p.Viper.GetDuration("object.dial_timeout"),
|
||||
MaxPayloadSize: p.Viper.GetUint64("object.transformers.payload_limiter.max_payload_size") * uint64(apiobj.UnitsKB),
|
||||
PutParams: object.OperationParams{
|
||||
Timeout: pto,
|
||||
LogErrors: p.Viper.GetBool("object.put.log_errs"),
|
||||
},
|
||||
GetParams: object.OperationParams{
|
||||
Timeout: gto,
|
||||
LogErrors: p.Viper.GetBool("object.get.log_errs"),
|
||||
},
|
||||
HeadParams: object.OperationParams{
|
||||
Timeout: hto,
|
||||
LogErrors: p.Viper.GetBool("object.head.log_errs"),
|
||||
},
|
||||
DeleteParams: object.OperationParams{
|
||||
Timeout: p.Viper.GetDuration("object.delete.timeout"),
|
||||
LogErrors: p.Viper.GetBool("object.get.log_errs"),
|
||||
},
|
||||
SearchParams: object.OperationParams{
|
||||
Timeout: sto,
|
||||
LogErrors: p.Viper.GetBool("object.search.log_errs"),
|
||||
},
|
||||
RangeParams: object.OperationParams{
|
||||
Timeout: p.Viper.GetDuration("object.range.timeout"),
|
||||
LogErrors: p.Viper.GetBool("object.range.log_errs"),
|
||||
},
|
||||
RangeHashParams: object.OperationParams{
|
||||
Timeout: rhto,
|
||||
LogErrors: p.Viper.GetBool("object.range_hash.log_errs"),
|
||||
},
|
||||
Assembly: p.Viper.GetBool("object.assembly"),
|
||||
|
||||
WindowSize: p.Viper.GetInt("object.window_size"),
|
||||
|
||||
ContainerStorage: p.ContainerStorage,
|
||||
NetmapClient: p.NetMapClient,
|
||||
|
||||
SGInfoReceiver: sgInfoRecv,
|
||||
|
||||
ExtendedACLSource: p.ExtendedACLStore,
|
||||
})
|
||||
}
|
28
cmd/neofs-node/modules/node/peerstore.go
Normal file
28
cmd/neofs-node/modules/node/peerstore.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/network/peers"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type peerstoreParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
PrivateKey *ecdsa.PrivateKey
|
||||
Address multiaddr.Multiaddr
|
||||
Store peers.Storage `optional:"true"`
|
||||
}
|
||||
|
||||
func newPeerstore(p peerstoreParams) (peers.Store, error) {
|
||||
return peers.NewStore(peers.StoreParams{
|
||||
Storage: p.Store,
|
||||
Logger: p.Logger,
|
||||
Addr: p.Address,
|
||||
Key: p.PrivateKey,
|
||||
})
|
||||
}
|
28
cmd/neofs-node/modules/node/placement.go
Normal file
28
cmd/neofs-node/modules/node/placement.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/placement"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
type (
|
||||
placementToolParams struct {
|
||||
dig.In
|
||||
|
||||
Placement placement.Component
|
||||
}
|
||||
|
||||
placementToolResult struct {
|
||||
dig.Out
|
||||
|
||||
Placer *placement.PlacementWrapper
|
||||
}
|
||||
)
|
||||
|
||||
func newPlacementTool(p placementToolParams) (res placementToolResult, err error) {
|
||||
if res.Placer, err = placement.NewObjectPlacer(p.Placement); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
385
cmd/neofs-node/modules/node/replication.go
Normal file
385
cmd/neofs-node/modules/node/replication.go
Normal file
|
@ -0,0 +1,385 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/hash"
|
||||
"github.com/nspcc-dev/neofs-api-go/session"
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/morph"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/localstore"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event/netmap"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/network/peers"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/placement"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/replication"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/replication/storage"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
replicationManagerParams struct {
|
||||
dig.In
|
||||
|
||||
Viper *viper.Viper
|
||||
|
||||
PeersInterface peers.Interface
|
||||
|
||||
LocalStore localstore.Localstore
|
||||
Peers peers.Store
|
||||
Placement placement.Component
|
||||
Logger *zap.Logger
|
||||
Key *ecdsa.PrivateKey
|
||||
|
||||
Placer *placement.PlacementWrapper
|
||||
|
||||
TokenStore session.PrivateTokenStore
|
||||
|
||||
MorphEventListener event.Listener
|
||||
MorphEventHandlers morph.EventHandlers
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
mainReplicationPrefix = "replication"
|
||||
managerPrefix = "manager"
|
||||
placementHonorerPrefix = "placement_honorer"
|
||||
locationDetectorPrefix = "location_detector"
|
||||
storageValidatorPrefix = "storage_validator"
|
||||
replicatorPrefix = "replicator"
|
||||
restorerPrefix = "restorer"
|
||||
)
|
||||
|
||||
func newReplicationManager(p replicationManagerParams) (replication.Manager, error) {
|
||||
as, err := storage.NewAddressStore(p.Peers, p.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ms, err := replication.NewMultiSolver(replication.MultiSolverParams{
|
||||
AddressStore: as,
|
||||
Placement: p.Placement,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
op := replication.NewObjectPool()
|
||||
|
||||
schd, err := replication.NewReplicationScheduler(replication.SchedulerParams{
|
||||
ContainerActualityChecker: ms,
|
||||
Iterator: p.LocalStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
integrityVerifier, err := storage.NewLocalIntegrityVerifier()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
verifier, err := storage.NewObjectValidator(&storage.ObjectValidatorParams{
|
||||
AddressStore: ms,
|
||||
Localstore: p.LocalStore,
|
||||
Logger: p.Logger,
|
||||
Verifier: integrityVerifier,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
placementHonorer, err := newPlacementHonorer(p, ms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
locationDetector, err := newLocationDetector(p, ms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
storageValidator, err := newStorageValidator(p, ms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
replicator, err := newObjectReplicator(p, ms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
restorer, err := newRestorer(p, ms)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prefix := mainReplicationPrefix + "." + managerPrefix + "."
|
||||
capPrefix := prefix + "capacities."
|
||||
|
||||
mngr, err := replication.NewManager(replication.ManagerParams{
|
||||
Interval: p.Viper.GetDuration(prefix + "read_pool_interval"),
|
||||
PushTaskTimeout: p.Viper.GetDuration(prefix + "push_task_timeout"),
|
||||
InitPoolSize: p.Viper.GetInt(prefix + "pool_size"),
|
||||
ExpansionRate: p.Viper.GetFloat64(prefix + "pool_expansion_rate"),
|
||||
PlacementHonorerEnabled: p.Viper.GetBool(prefix + "placement_honorer_enabled"),
|
||||
ReplicateTaskChanCap: p.Viper.GetInt(capPrefix + "replicate"),
|
||||
RestoreTaskChanCap: p.Viper.GetInt(capPrefix + "restore"),
|
||||
GarbageChanCap: p.Viper.GetInt(capPrefix + "garbage"),
|
||||
ObjectPool: op,
|
||||
ObjectVerifier: verifier,
|
||||
PlacementHonorer: placementHonorer,
|
||||
ObjectLocationDetector: locationDetector,
|
||||
StorageValidator: storageValidator,
|
||||
ObjectReplicator: replicator,
|
||||
ObjectRestorer: restorer,
|
||||
Scheduler: schd,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if handlerInfo, ok := p.MorphEventHandlers[morph.ContractEventOptPath(
|
||||
morph.NetmapContractName,
|
||||
morph.NewEpochEventType,
|
||||
)]; ok {
|
||||
handlerInfo.SetHandler(func(ev event.Event) {
|
||||
mngr.HandleEpoch(
|
||||
context.Background(),
|
||||
ev.(netmap.NewEpoch).EpochNumber(),
|
||||
)
|
||||
})
|
||||
|
||||
p.MorphEventListener.RegisterHandler(handlerInfo)
|
||||
}
|
||||
|
||||
return mngr, nil
|
||||
}
|
||||
|
||||
func newPlacementHonorer(p replicationManagerParams, rss replication.RemoteStorageSelector) (replication.PlacementHonorer, error) {
|
||||
prefix := mainReplicationPrefix + "." + placementHonorerPrefix
|
||||
|
||||
och, err := newObjectsContainerHandler(cnrHandlerParams{
|
||||
Viper: p.Viper,
|
||||
Logger: p.Logger,
|
||||
Placer: p.Placer,
|
||||
PeerStore: p.Peers,
|
||||
Peers: p.PeersInterface,
|
||||
TimeoutsPrefix: prefix,
|
||||
Key: p.Key,
|
||||
|
||||
TokenStore: p.TokenStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
storage, err := storage.NewObjectStorage(storage.ObjectStorageParams{
|
||||
Localstore: p.LocalStore,
|
||||
SelectiveContainerExecutor: och,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return replication.NewPlacementHonorer(replication.PlacementHonorerParams{
|
||||
ObjectSource: storage,
|
||||
ObjectReceptacle: storage,
|
||||
RemoteStorageSelector: rss,
|
||||
PresenceChecker: p.LocalStore,
|
||||
Logger: p.Logger,
|
||||
TaskChanCap: p.Viper.GetInt(prefix + ".chan_capacity"),
|
||||
ResultTimeout: p.Viper.GetDuration(prefix + ".result_timeout"),
|
||||
})
|
||||
}
|
||||
|
||||
func newLocationDetector(p replicationManagerParams, ms replication.MultiSolver) (replication.ObjectLocationDetector, error) {
|
||||
prefix := mainReplicationPrefix + "." + locationDetectorPrefix
|
||||
|
||||
och, err := newObjectsContainerHandler(cnrHandlerParams{
|
||||
Viper: p.Viper,
|
||||
Logger: p.Logger,
|
||||
Placer: p.Placer,
|
||||
PeerStore: p.Peers,
|
||||
Peers: p.PeersInterface,
|
||||
TimeoutsPrefix: prefix,
|
||||
Key: p.Key,
|
||||
|
||||
TokenStore: p.TokenStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
locator, err := storage.NewObjectLocator(storage.LocatorParams{
|
||||
SelectiveContainerExecutor: och,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return replication.NewLocationDetector(&replication.LocationDetectorParams{
|
||||
WeightComparator: ms,
|
||||
ObjectLocator: locator,
|
||||
ReservationRatioReceiver: ms,
|
||||
PresenceChecker: p.LocalStore,
|
||||
Logger: p.Logger,
|
||||
TaskChanCap: p.Viper.GetInt(prefix + ".chan_capacity"),
|
||||
ResultTimeout: p.Viper.GetDuration(prefix + ".result_timeout"),
|
||||
})
|
||||
}
|
||||
|
||||
func newStorageValidator(p replicationManagerParams, as replication.AddressStore) (replication.StorageValidator, error) {
|
||||
prefix := mainReplicationPrefix + "." + storageValidatorPrefix
|
||||
|
||||
var sltr storage.Salitor
|
||||
|
||||
switch v := p.Viper.GetString(prefix + ".salitor"); v {
|
||||
case xorSalitor:
|
||||
sltr = hash.SaltXOR
|
||||
default:
|
||||
return nil, errors.Errorf("unsupported salitor: %s", v)
|
||||
}
|
||||
|
||||
och, err := newObjectsContainerHandler(cnrHandlerParams{
|
||||
Viper: p.Viper,
|
||||
Logger: p.Logger,
|
||||
Placer: p.Placer,
|
||||
PeerStore: p.Peers,
|
||||
Peers: p.PeersInterface,
|
||||
TimeoutsPrefix: prefix,
|
||||
Key: p.Key,
|
||||
|
||||
TokenStore: p.TokenStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
headVerifier, err := storage.NewLocalHeadIntegrityVerifier()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
verifier, err := storage.NewObjectValidator(&storage.ObjectValidatorParams{
|
||||
AddressStore: as,
|
||||
Localstore: p.LocalStore,
|
||||
SelectiveContainerExecutor: och,
|
||||
Logger: p.Logger,
|
||||
Salitor: sltr,
|
||||
SaltSize: p.Viper.GetInt(prefix + ".salt_size"),
|
||||
MaxPayloadRangeSize: p.Viper.GetUint64(prefix + ".max_payload_range_size"),
|
||||
PayloadRangeCount: p.Viper.GetInt(prefix + ".payload_range_count"),
|
||||
Verifier: headVerifier,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return replication.NewStorageValidator(replication.StorageValidatorParams{
|
||||
ObjectVerifier: verifier,
|
||||
PresenceChecker: p.LocalStore,
|
||||
Logger: p.Logger,
|
||||
TaskChanCap: p.Viper.GetInt(prefix + ".chan_capacity"),
|
||||
ResultTimeout: p.Viper.GetDuration(prefix + ".result_timeout"),
|
||||
AddrStore: as,
|
||||
})
|
||||
}
|
||||
|
||||
func newObjectReplicator(p replicationManagerParams, rss replication.RemoteStorageSelector) (replication.ObjectReplicator, error) {
|
||||
prefix := mainReplicationPrefix + "." + replicatorPrefix
|
||||
|
||||
och, err := newObjectsContainerHandler(cnrHandlerParams{
|
||||
Viper: p.Viper,
|
||||
Logger: p.Logger,
|
||||
Placer: p.Placer,
|
||||
PeerStore: p.Peers,
|
||||
Peers: p.PeersInterface,
|
||||
TimeoutsPrefix: prefix,
|
||||
Key: p.Key,
|
||||
|
||||
TokenStore: p.TokenStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
storage, err := storage.NewObjectStorage(storage.ObjectStorageParams{
|
||||
Localstore: p.LocalStore,
|
||||
SelectiveContainerExecutor: och,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return replication.NewReplicator(replication.ObjectReplicatorParams{
|
||||
RemoteStorageSelector: rss,
|
||||
ObjectSource: storage,
|
||||
ObjectReceptacle: storage,
|
||||
PresenceChecker: p.LocalStore,
|
||||
Logger: p.Logger,
|
||||
TaskChanCap: p.Viper.GetInt(prefix + ".chan_capacity"),
|
||||
ResultTimeout: p.Viper.GetDuration(prefix + ".result_timeout"),
|
||||
})
|
||||
}
|
||||
|
||||
func newRestorer(p replicationManagerParams, ms replication.MultiSolver) (replication.ObjectRestorer, error) {
|
||||
prefix := mainReplicationPrefix + "." + restorerPrefix
|
||||
|
||||
och, err := newObjectsContainerHandler(cnrHandlerParams{
|
||||
Viper: p.Viper,
|
||||
Logger: p.Logger,
|
||||
Placer: p.Placer,
|
||||
PeerStore: p.Peers,
|
||||
Peers: p.PeersInterface,
|
||||
TimeoutsPrefix: prefix,
|
||||
Key: p.Key,
|
||||
|
||||
TokenStore: p.TokenStore,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
integrityVerifier, err := storage.NewLocalIntegrityVerifier()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
verifier, err := storage.NewObjectValidator(&storage.ObjectValidatorParams{
|
||||
AddressStore: ms,
|
||||
Localstore: p.LocalStore,
|
||||
SelectiveContainerExecutor: och,
|
||||
Logger: p.Logger,
|
||||
Verifier: integrityVerifier,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
storage, err := storage.NewObjectStorage(storage.ObjectStorageParams{
|
||||
Localstore: p.LocalStore,
|
||||
Logger: p.Logger,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return replication.NewObjectRestorer(&replication.ObjectRestorerParams{
|
||||
ObjectVerifier: verifier,
|
||||
ObjectReceptacle: storage,
|
||||
EpochReceiver: ms,
|
||||
RemoteStorageSelector: ms,
|
||||
PresenceChecker: p.LocalStore,
|
||||
Logger: p.Logger,
|
||||
TaskChanCap: p.Viper.GetInt(prefix + ".chan_capacity"),
|
||||
ResultTimeout: p.Viper.GetDuration(prefix + ".result_timeout"),
|
||||
})
|
||||
}
|
36
cmd/neofs-node/modules/node/services.go
Normal file
36
cmd/neofs-node/modules/node/services.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
"github.com/nspcc-dev/neofs-node/cmd/neofs-node/modules/grpc"
|
||||
accounting "github.com/nspcc-dev/neofs-node/pkg/network/transport/accounting/grpc"
|
||||
container "github.com/nspcc-dev/neofs-node/pkg/network/transport/container/grpc"
|
||||
metrics "github.com/nspcc-dev/neofs-node/pkg/network/transport/metrics/grpc"
|
||||
object "github.com/nspcc-dev/neofs-node/pkg/network/transport/object/grpc"
|
||||
session "github.com/nspcc-dev/neofs-node/pkg/network/transport/session/grpc"
|
||||
state "github.com/nspcc-dev/neofs-node/pkg/network/transport/state/grpc"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
type servicesParams struct {
|
||||
dig.In
|
||||
|
||||
Status state.Service
|
||||
Container container.Service
|
||||
Object object.Service
|
||||
Session session.Service
|
||||
Accounting accounting.Service
|
||||
Metrics metrics.Service
|
||||
}
|
||||
|
||||
func attachServices(p servicesParams) grpc.ServicesResult {
|
||||
return grpc.ServicesResult{
|
||||
Services: []grpc.Service{
|
||||
p.Status,
|
||||
p.Container,
|
||||
p.Accounting,
|
||||
p.Metrics,
|
||||
p.Session,
|
||||
p.Object,
|
||||
},
|
||||
}
|
||||
}
|
26
cmd/neofs-node/modules/node/session.go
Normal file
26
cmd/neofs-node/modules/node/session.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package node
|
||||
|
||||
import (
|
||||
session "github.com/nspcc-dev/neofs-node/pkg/network/transport/session/grpc"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/services/object_manager/placement"
|
||||
"go.uber.org/dig"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type sessionParams struct {
|
||||
dig.In
|
||||
|
||||
Logger *zap.Logger
|
||||
|
||||
TokenStore session.TokenStore
|
||||
|
||||
EpochReceiver *placement.PlacementWrapper
|
||||
}
|
||||
|
||||
func newSessionService(p sessionParams) (session.Service, error) {
|
||||
return session.New(session.Params{
|
||||
TokenStore: p.TokenStore,
|
||||
Logger: p.Logger,
|
||||
EpochReceiver: p.EpochReceiver,
|
||||
}), nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue