Compare commits
No commits in common. "master" and "bugfix/prox-alphabet-wallets" have entirely different histories.
master
...
bugfix/pro
606 changed files with 6071 additions and 6838 deletions
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.23 AS builder
|
||||
FROM golang:1.22 AS builder
|
||||
ARG BUILD=now
|
||||
ARG VERSION=dev
|
||||
ARG REPO=repository
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.23
|
||||
FROM golang:1.22
|
||||
|
||||
WORKDIR /tmp
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.23 AS builder
|
||||
FROM golang:1.22 AS builder
|
||||
ARG BUILD=now
|
||||
ARG VERSION=dev
|
||||
ARG REPO=repository
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.23 AS builder
|
||||
FROM golang:1.22 AS builder
|
||||
ARG BUILD=now
|
||||
ARG VERSION=dev
|
||||
ARG REPO=repository
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM golang:1.23 AS builder
|
||||
FROM golang:1.22 AS builder
|
||||
ARG BUILD=now
|
||||
ARG VERSION=dev
|
||||
ARG REPO=repository
|
||||
|
|
0
.forgejo/logo.svg → .github/logo.svg
vendored
0
.forgejo/logo.svg → .github/logo.svg
vendored
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
@ -87,7 +87,5 @@ linters:
|
|||
- perfsprint
|
||||
- testifylint
|
||||
- protogetter
|
||||
- intrange
|
||||
- tenv
|
||||
disable-all: true
|
||||
fast: false
|
||||
|
|
11
.woodpecker/pre-commit.yml
Normal file
11
.woodpecker/pre-commit.yml
Normal file
|
@ -0,0 +1,11 @@
|
|||
pipeline:
|
||||
# Kludge for non-root containers under WoodPecker
|
||||
fix-ownership:
|
||||
image: alpine:latest
|
||||
commands: chown -R 1234:1234 .
|
||||
|
||||
pre-commit:
|
||||
image: git.frostfs.info/truecloudlab/frostfs-ci:v0.36
|
||||
commands:
|
||||
- export HOME="$(getent passwd $(id -u) | cut '-d:' -f6)"
|
||||
- pre-commit run --hook-stage manual
|
32
Makefile
32
Makefile
|
@ -8,10 +8,10 @@ HUB_IMAGE ?= git.frostfs.info/truecloudlab/frostfs
|
|||
HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')"
|
||||
|
||||
GO_VERSION ?= 1.22
|
||||
LINT_VERSION ?= 1.62.0
|
||||
TRUECLOUDLAB_LINT_VERSION ?= 0.0.8
|
||||
LINT_VERSION ?= 1.60.3
|
||||
TRUECLOUDLAB_LINT_VERSION ?= 0.0.7
|
||||
PROTOC_VERSION ?= 25.0
|
||||
PROTOGEN_FROSTFS_VERSION ?= $(shell go list -f '{{.Version}}' -m git.frostfs.info/TrueCloudLab/frostfs-sdk-go)
|
||||
PROTOGEN_FROSTFS_VERSION ?= $(shell go list -f '{{.Version}}' -m git.frostfs.info/TrueCloudLab/frostfs-api-go/v2)
|
||||
PROTOC_OS_VERSION=osx-x86_64
|
||||
ifeq ($(shell uname), Linux)
|
||||
PROTOC_OS_VERSION=linux-x86_64
|
||||
|
@ -27,6 +27,12 @@ DIRS = $(BIN) $(RELEASE)
|
|||
CMDS = $(notdir $(basename $(wildcard cmd/frostfs-*)))
|
||||
BINS = $(addprefix $(BIN)/, $(CMDS))
|
||||
|
||||
# .deb package versioning
|
||||
OS_RELEASE = $(shell lsb_release -cs)
|
||||
PKG_VERSION ?= $(shell echo $(VERSION) | sed "s/^v//" | \
|
||||
sed -E "s/(.*)-(g[a-fA-F0-9]{6,8})(.*)/\1\3~\2/" | \
|
||||
sed "s/-/~/")-${OS_RELEASE}
|
||||
|
||||
OUTPUT_LINT_DIR ?= $(abspath $(BIN))/linters
|
||||
LINT_DIR = $(OUTPUT_LINT_DIR)/golangci-lint-$(LINT_VERSION)-v$(TRUECLOUDLAB_LINT_VERSION)
|
||||
TMP_DIR := .cache
|
||||
|
@ -52,7 +58,7 @@ LOCODE_DB_PATH=$(abspath ./.cache/locode_db)
|
|||
LOCODE_DB_VERSION=v0.4.0
|
||||
|
||||
.PHONY: help all images dep clean fmts fumpt imports test lint docker/lint
|
||||
prepare-release pre-commit unpre-commit
|
||||
prepare-release debpackage pre-commit unpre-commit
|
||||
|
||||
# To build a specific binary, use it's name prefix with bin/ as a target
|
||||
# For example `make bin/frostfs-node` will build only storage node binary
|
||||
|
@ -121,7 +127,7 @@ protoc-install:
|
|||
@unzip -q -o $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip -d $(PROTOC_DIR)
|
||||
@rm $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip
|
||||
@echo "⇒ Instaling protogen FrostFS plugin..."
|
||||
@GOBIN=$(PROTOGEN_FROSTFS_DIR) go install -mod=mod -v git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/util/protogen@$(PROTOGEN_FROSTFS_VERSION)
|
||||
@GOBIN=$(PROTOGEN_FROSTFS_DIR) go install -mod=mod -v git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/protogen@$(PROTOGEN_FROSTFS_VERSION)
|
||||
|
||||
# Build FrostFS component's docker image
|
||||
image-%:
|
||||
|
@ -257,6 +263,19 @@ clean:
|
|||
rm -rf $(BIN)
|
||||
rm -rf $(RELEASE)
|
||||
|
||||
# Package for Debian
|
||||
debpackage:
|
||||
dch -b --package frostfs-node \
|
||||
--controlmaint \
|
||||
--newversion $(PKG_VERSION) \
|
||||
--distribution $(OS_RELEASE) \
|
||||
"Please see CHANGELOG.md for code changes for $(VERSION)"
|
||||
dpkg-buildpackage --no-sign -b
|
||||
|
||||
# Cleanup deb package build directories
|
||||
debclean:
|
||||
dh clean
|
||||
|
||||
# Download locode database
|
||||
locode-download:
|
||||
mkdir -p $(TMP_DIR)
|
||||
|
@ -282,6 +301,7 @@ env-up: all
|
|||
|
||||
# Shutdown dev environment
|
||||
env-down:
|
||||
docker compose -f dev/docker-compose.yml down -v
|
||||
docker compose -f dev/docker-compose.yml down
|
||||
docker volume rm -f frostfs-node_neo-go
|
||||
rm -rf ./$(TMP_DIR)/state
|
||||
rm -rf ./$(TMP_DIR)/storage
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<p align="center">
|
||||
<img src="./.forgejo/logo.svg" width="500px" alt="FrostFS">
|
||||
<img src="./.github/logo.svg" width="500px" alt="FrostFS">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
@ -98,7 +98,7 @@ See `frostfs-contract`'s README.md for build instructions.
|
|||
4. To create container and put object into it run (container and object IDs will be different):
|
||||
|
||||
```
|
||||
./bin/frostfs-cli container create -r 127.0.0.1:8080 --wallet ./dev/wallet.json --policy "REP 1 IN X CBF 1 SELECT 1 FROM * AS X" --await
|
||||
./bin/frostfs-cli container create -r 127.0.0.1:8080 --wallet ./dev/wallet.json --policy "REP 1 IN X CBF 1 SELECT 1 FROM * AS X" --basic-acl public-read-write --await
|
||||
Enter password > <- press ENTER, the is no password for wallet
|
||||
CID: CfPhEuHQ2PRvM4gfBQDC4dWZY3NccovyfcnEdiq2ixju
|
||||
|
||||
|
|
|
@ -39,4 +39,5 @@ const (
|
|||
CustomZoneFlag = "domain"
|
||||
AlphabetSizeFlag = "size"
|
||||
AllFlag = "all"
|
||||
DeltaFlag = "delta"
|
||||
)
|
||||
|
|
|
@ -128,7 +128,7 @@ func generateConfigExample(appDir string, credSize int) (string, error) {
|
|||
tmpl.AlphabetDir = filepath.Join(appDir, "alphabet-wallets")
|
||||
|
||||
var i innerring.GlagoliticLetter
|
||||
for i = range innerring.GlagoliticLetter(credSize) {
|
||||
for i = 0; i < innerring.GlagoliticLetter(credSize); i++ {
|
||||
tmpl.Glagolitics = append(tmpl.Glagolitics, i.String())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package metabase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
@ -11,24 +10,19 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
||||
engineconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine"
|
||||
shardconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard"
|
||||
morphconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/morph"
|
||||
nodeconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/node"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
morphcontainer "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
"github.com/spf13/cobra"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
const (
|
||||
pathFlag = "path"
|
||||
noCompactFlag = "no-compact"
|
||||
)
|
||||
|
||||
var (
|
||||
errNoPathsFound = errors.New("no metabase paths found")
|
||||
errNoMorphEndpointsFound = errors.New("no morph endpoints found")
|
||||
)
|
||||
var errNoPathsFound = errors.New("no metabase paths found")
|
||||
|
||||
var path string
|
||||
|
||||
var UpgradeCmd = &cobra.Command{
|
||||
Use: "upgrade",
|
||||
|
@ -45,10 +39,17 @@ func upgrade(cmd *cobra.Command, _ []string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
noCompact, _ := cmd.Flags().GetBool(noCompactFlag)
|
||||
var paths []string
|
||||
if path != "" {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
appCfg := config.New(configFile, configDir, config.EnvPrefix)
|
||||
paths, err := getMetabasePaths(appCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
if err := engineconfig.IterateShards(appCfg, false, func(sc *shardconfig.Config) error {
|
||||
paths = append(paths, sc.Metabase().Path())
|
||||
return nil
|
||||
}); err != nil {
|
||||
return fmt.Errorf("failed to get metabase paths: %w", err)
|
||||
}
|
||||
if len(paths) == 0 {
|
||||
return errNoPathsFound
|
||||
|
@ -57,16 +58,6 @@ func upgrade(cmd *cobra.Command, _ []string) error {
|
|||
for i, path := range paths {
|
||||
cmd.Println(i+1, ":", path)
|
||||
}
|
||||
mc, err := createMorphClient(cmd.Context(), appCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer mc.Close()
|
||||
civ, err := createContainerInfoProvider(mc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
noCompact, _ := cmd.Flags().GetBool(noCompactFlag)
|
||||
result := make(map[string]bool)
|
||||
var resultGuard sync.Mutex
|
||||
eg, ctx := errgroup.WithContext(cmd.Context())
|
||||
|
@ -74,7 +65,7 @@ func upgrade(cmd *cobra.Command, _ []string) error {
|
|||
eg.Go(func() error {
|
||||
var success bool
|
||||
cmd.Println("upgrading metabase", path, "...")
|
||||
if err := meta.Upgrade(ctx, path, !noCompact, civ, func(a ...any) {
|
||||
if err := meta.Upgrade(ctx, path, !noCompact, func(a ...any) {
|
||||
cmd.Println(append([]any{time.Now().Format(time.RFC3339), ":", path, ":"}, a...)...)
|
||||
}); err != nil {
|
||||
cmd.Println("error: failed to upgrade metabase", path, ":", err)
|
||||
|
@ -101,50 +92,8 @@ func upgrade(cmd *cobra.Command, _ []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getMetabasePaths(appCfg *config.Config) ([]string, error) {
|
||||
var paths []string
|
||||
if err := engineconfig.IterateShards(appCfg, false, func(sc *shardconfig.Config) error {
|
||||
paths = append(paths, sc.Metabase().Path())
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("get metabase paths: %w", err)
|
||||
}
|
||||
return paths, nil
|
||||
}
|
||||
|
||||
func createMorphClient(ctx context.Context, appCfg *config.Config) (*client.Client, error) {
|
||||
addresses := morphconfig.RPCEndpoint(appCfg)
|
||||
if len(addresses) == 0 {
|
||||
return nil, errNoMorphEndpointsFound
|
||||
}
|
||||
key := nodeconfig.Key(appCfg)
|
||||
cli, err := client.New(ctx,
|
||||
key,
|
||||
client.WithDialTimeout(morphconfig.DialTimeout(appCfg)),
|
||||
client.WithEndpoints(addresses...),
|
||||
client.WithSwitchInterval(morphconfig.SwitchInterval(appCfg)),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create morph client:%w", err)
|
||||
}
|
||||
return cli, nil
|
||||
}
|
||||
|
||||
func createContainerInfoProvider(cli *client.Client) (container.InfoProvider, error) {
|
||||
sh, err := cli.NNSContractAddress(client.NNSContainerContractName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("resolve container contract hash: %w", err)
|
||||
}
|
||||
cc, err := morphcontainer.NewFromMorph(cli, sh, 0, morphcontainer.TryNotary())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create morph container client: %w", err)
|
||||
}
|
||||
return container.NewInfoProvider(func() (container.Source, error) {
|
||||
return morphcontainer.AsContainerSource(cc), nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func initUpgradeCommand() {
|
||||
flags := UpgradeCmd.Flags()
|
||||
flags.StringVar(&path, pathFlag, "", "Path to metabase file")
|
||||
flags.Bool(noCompactFlag, false, "Do not compact upgraded metabase file")
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ func newPolicyContractInterface(cmd *cobra.Command) (*morph.ContractStorage, *he
|
|||
c, err := helper.GetN3Client(viper.GetViper())
|
||||
commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err)
|
||||
|
||||
ac, err := helper.NewLocalActor(cmd, c, constants.ConsensusAccountName)
|
||||
ac, err := helper.NewLocalActor(cmd, c)
|
||||
commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)
|
||||
|
||||
var ch util.Uint160
|
||||
|
|
|
@ -139,12 +139,13 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
|
|||
func dumpSingleContainer(bw *io.BufBinWriter, ch util.Uint160, inv *invoker.Invoker, id []byte) (*Container, error) {
|
||||
bw.Reset()
|
||||
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id)
|
||||
emit.AppCall(bw.BinWriter, ch, "eACL", callflag.All, id)
|
||||
res, err := inv.Run(bw.Bytes())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get container info: %w", err)
|
||||
}
|
||||
if len(res.Stack) != 1 {
|
||||
return nil, fmt.Errorf("%w: expected 1 items on stack", errInvalidContainerResponse)
|
||||
if len(res.Stack) != 2 {
|
||||
return nil, fmt.Errorf("%w: expected 2 items on stack", errInvalidContainerResponse)
|
||||
}
|
||||
|
||||
cnt := new(Container)
|
||||
|
@ -153,6 +154,14 @@ func dumpSingleContainer(bw *io.BufBinWriter, ch util.Uint160, inv *invoker.Invo
|
|||
return nil, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
|
||||
ea := new(EACL)
|
||||
err = ea.FromStackItem(res.Stack[1])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||
}
|
||||
if len(ea.Value) != 0 {
|
||||
cnt.EACL = ea
|
||||
}
|
||||
return cnt, nil
|
||||
}
|
||||
|
||||
|
@ -249,6 +258,10 @@ func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd
|
|||
func putContainer(bw *io.BufBinWriter, ch util.Uint160, cnt Container) {
|
||||
emit.AppCall(bw.BinWriter, ch, "put", callflag.All,
|
||||
cnt.Value, cnt.Signature, cnt.PublicKey, cnt.Token)
|
||||
if ea := cnt.EACL; ea != nil {
|
||||
emit.AppCall(bw.BinWriter, ch, "setEACL", callflag.All,
|
||||
ea.Value, ea.Signature, ea.PublicKey, ea.Token)
|
||||
}
|
||||
}
|
||||
|
||||
func isContainerRestored(cmd *cobra.Command, wCtx *helper.InitializeContext, containerHash util.Uint160, bw *io.BufBinWriter, hashValue util.Uint256) (bool, error) {
|
||||
|
@ -309,6 +322,15 @@ type Container struct {
|
|||
Signature []byte `json:"signature"`
|
||||
PublicKey []byte `json:"public_key"`
|
||||
Token []byte `json:"token"`
|
||||
EACL *EACL `json:"eacl"`
|
||||
}
|
||||
|
||||
// EACL represents extended ACL struct in contract storage.
|
||||
type EACL struct {
|
||||
Value []byte `json:"value"`
|
||||
Signature []byte `json:"signature"`
|
||||
PublicKey []byte `json:"public_key"`
|
||||
Token []byte `json:"token"`
|
||||
}
|
||||
|
||||
// ToStackItem implements stackitem.Convertible.
|
||||
|
@ -355,6 +377,50 @@ func (c *Container) FromStackItem(item stackitem.Item) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ToStackItem implements stackitem.Convertible.
|
||||
func (c *EACL) ToStackItem() (stackitem.Item, error) {
|
||||
return stackitem.NewStruct([]stackitem.Item{
|
||||
stackitem.NewByteArray(c.Value),
|
||||
stackitem.NewByteArray(c.Signature),
|
||||
stackitem.NewByteArray(c.PublicKey),
|
||||
stackitem.NewByteArray(c.Token),
|
||||
}), nil
|
||||
}
|
||||
|
||||
// FromStackItem implements stackitem.Convertible.
|
||||
func (c *EACL) FromStackItem(item stackitem.Item) error {
|
||||
arr, ok := item.Value().([]stackitem.Item)
|
||||
if !ok || len(arr) != 4 {
|
||||
return errors.New("invalid stack item type")
|
||||
}
|
||||
|
||||
value, err := arr[0].TryBytes()
|
||||
if err != nil {
|
||||
return errors.New("invalid eACL value")
|
||||
}
|
||||
|
||||
sig, err := arr[1].TryBytes()
|
||||
if err != nil {
|
||||
return errors.New("invalid eACL signature")
|
||||
}
|
||||
|
||||
pub, err := arr[2].TryBytes()
|
||||
if err != nil {
|
||||
return errors.New("invalid eACL public key")
|
||||
}
|
||||
|
||||
tok, err := arr[3].TryBytes()
|
||||
if err != nil {
|
||||
return errors.New("invalid eACL token")
|
||||
}
|
||||
|
||||
c.Value = value
|
||||
c.Signature = sig
|
||||
c.PublicKey = pub
|
||||
c.Token = tok
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCIDFilterFunc returns filtering function for container IDs.
|
||||
// Raw byte slices are used because it works with structures returned
|
||||
// from contract.
|
||||
|
|
|
@ -63,7 +63,7 @@ func TestGenerateAlphabet(t *testing.T) {
|
|||
buf.Reset()
|
||||
v.Set(commonflags.AlphabetWalletsFlag, walletDir)
|
||||
require.NoError(t, GenerateAlphabetCmd.Flags().Set(commonflags.AlphabetSizeFlag, strconv.FormatUint(size, 10)))
|
||||
for i := range uint64(size) {
|
||||
for i := uint64(0); i < size; i++ {
|
||||
buf.WriteString(strconv.FormatUint(i, 10) + "\r")
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/google/uuid"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||
|
@ -30,11 +31,7 @@ type LocalActor struct {
|
|||
|
||||
// NewLocalActor create LocalActor with accounts form provided wallets.
|
||||
// In case of empty wallets provided created actor with dummy account only for read operation.
|
||||
//
|
||||
// If wallets are provided, the contract client will use accounts with accName name from these wallets.
|
||||
// To determine which account name should be used in a contract client, refer to how the contract
|
||||
// verifies the transaction signature.
|
||||
func NewLocalActor(cmd *cobra.Command, c actor.RPCActor, accName string) (*LocalActor, error) {
|
||||
func NewLocalActor(cmd *cobra.Command, c actor.RPCActor) (*LocalActor, error) {
|
||||
walletDir := config.ResolveHomePath(viper.GetString(commonflags.AlphabetWalletsFlag))
|
||||
var act *actor.Actor
|
||||
var accounts []*wallet.Account
|
||||
|
@ -56,8 +53,8 @@ func NewLocalActor(cmd *cobra.Command, c actor.RPCActor, accName string) (*Local
|
|||
commonCmd.ExitOnErr(cmd, "unable to get alphabet wallets: %w", err)
|
||||
|
||||
for _, w := range wallets {
|
||||
acc, err := GetWalletAccount(w, accName)
|
||||
commonCmd.ExitOnErr(cmd, fmt.Sprintf("can't find %s account: %%w", accName), err)
|
||||
acc, err := GetWalletAccount(w, constants.CommitteeAccountName)
|
||||
commonCmd.ExitOnErr(cmd, "can't find committee account: %w", err)
|
||||
accounts = append(accounts, acc)
|
||||
}
|
||||
act, err = actor.New(c, []actor.SignerAccount{{
|
||||
|
|
|
@ -166,6 +166,5 @@ func DeployNNS(c *InitializeContext, method string) error {
|
|||
return fmt.Errorf("can't send deploy transaction: %w", err)
|
||||
}
|
||||
|
||||
c.Command.Println("NNS hash:", invokeHash.StringLE())
|
||||
return c.AwaitTx()
|
||||
}
|
||||
|
|
|
@ -27,12 +27,12 @@ const (
|
|||
initialAlphabetGASAmount = 10_000 * native.GASFactor
|
||||
// initialProxyGASAmount represents the amount of GAS given to a proxy contract.
|
||||
initialProxyGASAmount = 50_000 * native.GASFactor
|
||||
// alphabetGasRatio is a coefficient that defines the threshold below which
|
||||
// the balance of the alphabet node is considered not replenished. The value
|
||||
// of this coefficient is determined empirically.
|
||||
alphabetGasRatio = 5
|
||||
)
|
||||
|
||||
func initialCommitteeGASAmount(c *helper.InitializeContext) int64 {
|
||||
return (gasInitialTotalSupply - initialAlphabetGASAmount*int64(len(c.Wallets))) / 2
|
||||
}
|
||||
|
||||
func transferFunds(c *helper.InitializeContext) error {
|
||||
ok, err := transferFundsFinished(c)
|
||||
if ok || err != nil {
|
||||
|
@ -59,7 +59,7 @@ func transferFunds(c *helper.InitializeContext) error {
|
|||
transferTarget{
|
||||
Token: gas.Hash,
|
||||
Address: c.CommitteeAcc.Contract.ScriptHash(),
|
||||
Amount: initialCommitteeGASAmount(c),
|
||||
Amount: (gasInitialTotalSupply - initialAlphabetGASAmount*int64(len(c.Wallets))) / 2,
|
||||
},
|
||||
transferTarget{
|
||||
Token: neo.Hash,
|
||||
|
@ -80,19 +80,12 @@ func transferFunds(c *helper.InitializeContext) error {
|
|||
return c.AwaitTx()
|
||||
}
|
||||
|
||||
// transferFundsFinished checks balances of accounts we transfer GAS to.
|
||||
// The stage is considered finished if the balance is greater than the half of what we need to transfer.
|
||||
func transferFundsFinished(c *helper.InitializeContext) (bool, error) {
|
||||
acc := c.Accounts[0]
|
||||
|
||||
r := nep17.NewReader(c.ReadOnlyInvoker, gas.Hash)
|
||||
res, err := r.BalanceOf(acc.Contract.ScriptHash())
|
||||
if err != nil || res.Cmp(big.NewInt(initialAlphabetGASAmount/2)) != 1 {
|
||||
return false, err
|
||||
}
|
||||
|
||||
res, err = r.BalanceOf(c.CommitteeAcc.ScriptHash())
|
||||
return res != nil && res.Cmp(big.NewInt(initialCommitteeGASAmount(c)/2)) == 1, err
|
||||
return res.Cmp(big.NewInt(alphabetGasRatio*native.GASFactor)) == 1, err
|
||||
}
|
||||
|
||||
func transferGASToProxy(c *helper.InitializeContext) error {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -12,8 +13,6 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const deltaFlag = "delta"
|
||||
|
||||
func ForceNewEpochCmd(cmd *cobra.Command, _ []string) error {
|
||||
wCtx, err := helper.NewInitializeContext(cmd, viper.GetViper())
|
||||
if err != nil {
|
||||
|
@ -32,8 +31,7 @@ func ForceNewEpochCmd(cmd *cobra.Command, _ []string) error {
|
|||
}
|
||||
|
||||
bw := io.NewBufBinWriter()
|
||||
delta, _ := cmd.Flags().GetInt64(deltaFlag)
|
||||
if err := helper.EmitNewEpochCall(bw, wCtx, nmHash, delta); err != nil {
|
||||
if err := helper.EmitNewEpochCall(bw, wCtx, nmHash, viper.GetInt64(commonflags.DeltaFlag)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ var (
|
|||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.DeltaFlag, cmd.Flags().Lookup(commonflags.DeltaFlag))
|
||||
},
|
||||
RunE: ForceNewEpochCmd,
|
||||
}
|
||||
|
@ -35,7 +36,7 @@ func initForceNewEpochCmd() {
|
|||
ForceNewEpoch.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
ForceNewEpoch.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
ForceNewEpoch.Flags().String(commonflags.LocalDumpFlag, "", "Path to the blocks dump file")
|
||||
ForceNewEpoch.Flags().Int64(deltaFlag, 1, "Number of epochs to increase the current epoch")
|
||||
ForceNewEpoch.Flags().Int64(commonflags.DeltaFlag, 1, "Number of epochs to increase the current epoch")
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -2,7 +2,6 @@ package nns
|
|||
|
||||
import (
|
||||
client "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/nns"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
|
||||
|
@ -16,7 +15,7 @@ func getRPCClient(cmd *cobra.Command) (*client.Contract, *helper.LocalActor, uti
|
|||
c, err := helper.GetN3Client(v)
|
||||
commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err)
|
||||
|
||||
ac, err := helper.NewLocalActor(cmd, c, constants.CommitteeAccountName)
|
||||
ac, err := helper.NewLocalActor(cmd, c)
|
||||
commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)
|
||||
|
||||
r := management.NewReader(ac.Invoker)
|
||||
|
|
|
@ -47,19 +47,6 @@ func initDelRecordsCmd() {
|
|||
_ = cobra.MarkFlagRequired(delRecordsCmd.Flags(), nnsRecordTypeFlag)
|
||||
}
|
||||
|
||||
func initDelRecordCmd() {
|
||||
Cmd.AddCommand(delRecordCmd)
|
||||
delRecordCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
delRecordCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
|
||||
delRecordCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc)
|
||||
delRecordCmd.Flags().String(nnsRecordTypeFlag, "", nnsRecordTypeFlagDesc)
|
||||
delRecordCmd.Flags().String(nnsRecordDataFlag, "", nnsRecordDataFlagDesc)
|
||||
|
||||
_ = cobra.MarkFlagRequired(delRecordCmd.Flags(), nnsNameFlag)
|
||||
_ = cobra.MarkFlagRequired(delRecordCmd.Flags(), nnsRecordTypeFlag)
|
||||
_ = cobra.MarkFlagRequired(delRecordCmd.Flags(), nnsRecordDataFlag)
|
||||
}
|
||||
|
||||
func addRecord(cmd *cobra.Command, _ []string) {
|
||||
c, actor, _ := getRPCClient(cmd)
|
||||
name, _ := cmd.Flags().GetString(nnsNameFlag)
|
||||
|
@ -128,22 +115,6 @@ func delRecords(cmd *cobra.Command, _ []string) {
|
|||
cmd.Println("Records removed successfully")
|
||||
}
|
||||
|
||||
func delRecord(cmd *cobra.Command, _ []string) {
|
||||
c, actor, _ := getRPCClient(cmd)
|
||||
name, _ := cmd.Flags().GetString(nnsNameFlag)
|
||||
data, _ := cmd.Flags().GetString(nnsRecordDataFlag)
|
||||
recordType, _ := cmd.Flags().GetString(nnsRecordTypeFlag)
|
||||
typ, err := getRecordType(recordType)
|
||||
commonCmd.ExitOnErr(cmd, "unable to parse record type: %w", err)
|
||||
h, vub, err := c.DeleteRecord(name, typ, data)
|
||||
commonCmd.ExitOnErr(cmd, "unable to delete record: %w", err)
|
||||
|
||||
cmd.Println("Waiting for transaction to persist...")
|
||||
_, err = actor.Wait(h, vub, err)
|
||||
commonCmd.ExitOnErr(cmd, "delete records error: %w", err)
|
||||
cmd.Println("Record removed successfully")
|
||||
}
|
||||
|
||||
func getRecordType(recordType string) (*big.Int, error) {
|
||||
switch strings.ToUpper(recordType) {
|
||||
case "A":
|
||||
|
|
|
@ -95,15 +95,6 @@ var (
|
|||
},
|
||||
Run: delRecords,
|
||||
}
|
||||
delRecordCmd = &cobra.Command{
|
||||
Use: "delete-record",
|
||||
Short: "Removes domain record with the specified type and data",
|
||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||
_ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag))
|
||||
_ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag))
|
||||
},
|
||||
Run: delRecord,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -115,5 +106,4 @@ func init() {
|
|||
initAddRecordCmd()
|
||||
initGetRecordsCmd()
|
||||
initDelRecordsCmd()
|
||||
initDelRecordCmd()
|
||||
}
|
||||
|
|
|
@ -72,3 +72,4 @@ All other `object` sub-commands support only static sessions (2).
|
|||
List of commands supporting sessions (static only):
|
||||
- `create`
|
||||
- `delete`
|
||||
- `set-eacl`
|
||||
|
|
|
@ -659,7 +659,9 @@ func SearchObjects(ctx context.Context, prm SearchObjectsPrm) (*SearchObjectsRes
|
|||
|
||||
for {
|
||||
n, ok = rdr.Read(buf)
|
||||
list = append(list, buf[:n]...)
|
||||
for i := range n {
|
||||
list = append(list, buf[i])
|
||||
}
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
|
@ -670,8 +672,9 @@ func SearchObjects(ctx context.Context, prm SearchObjectsPrm) (*SearchObjectsRes
|
|||
return nil, fmt.Errorf("read object list: %w", err)
|
||||
}
|
||||
|
||||
slices.SortFunc(list, func(a, b oid.ID) int {
|
||||
return strings.Compare(a.EncodeToString(), b.EncodeToString())
|
||||
sort.Slice(list, func(i, j int) bool {
|
||||
lhs, rhs := list[i].EncodeToString(), list[j].EncodeToString()
|
||||
return strings.Compare(lhs, rhs) < 0
|
||||
})
|
||||
|
||||
return &SearchObjectsRes{
|
||||
|
|
|
@ -58,7 +58,6 @@ func GetSDKClient(ctx context.Context, cmd *cobra.Command, key *ecdsa.PrivateKey
|
|||
GRPCDialOptions: []grpc.DialOption{
|
||||
grpc.WithChainUnaryInterceptor(tracing.NewUnaryClientInteceptor()),
|
||||
grpc.WithChainStreamInterceptor(tracing.NewStreamClientInterceptor()),
|
||||
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
|
||||
},
|
||||
}
|
||||
if timeout := viper.GetDuration(commonflags.Timeout); timeout > 0 {
|
||||
|
|
|
@ -2,7 +2,7 @@ package common
|
|||
|
||||
import (
|
||||
"context"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
|
@ -45,11 +45,15 @@ func StartClientCommandSpan(cmd *cobra.Command) {
|
|||
})
|
||||
commonCmd.ExitOnErr(cmd, "init tracing: %w", err)
|
||||
|
||||
var components []string
|
||||
var components sort.StringSlice
|
||||
for c := cmd; c != nil; c = c.Parent() {
|
||||
components = append(components, c.Name())
|
||||
}
|
||||
slices.Reverse(components)
|
||||
for i, j := 0, len(components)-1; i < j; {
|
||||
components.Swap(i, j)
|
||||
i++
|
||||
j--
|
||||
}
|
||||
|
||||
operation := strings.Join(components, ".")
|
||||
ctx, span := tracing.StartSpanFromContext(cmd.Context(), operation)
|
||||
|
|
|
@ -31,10 +31,11 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
namespaceTarget = "namespace"
|
||||
containerTarget = "container"
|
||||
userTarget = "user"
|
||||
groupTarget = "group"
|
||||
defaultNamespace = ""
|
||||
namespaceTarget = "namespace"
|
||||
containerTarget = "container"
|
||||
userTarget = "user"
|
||||
groupTarget = "group"
|
||||
)
|
||||
|
||||
var errUnknownTargetType = errors.New("unknown target type")
|
||||
|
|
|
@ -7,20 +7,22 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
containerApi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
containerApi "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
containerACL string
|
||||
containerPolicy string
|
||||
containerAttributes []string
|
||||
containerAwait bool
|
||||
|
@ -87,6 +89,9 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
|||
err = parseAttributes(&cnr, containerAttributes)
|
||||
commonCmd.ExitOnErr(cmd, "", err)
|
||||
|
||||
var basicACL acl.Basic
|
||||
commonCmd.ExitOnErr(cmd, "decode basic ACL string: %w", basicACL.DecodeString(containerACL))
|
||||
|
||||
tok := getSession(cmd)
|
||||
|
||||
if tok != nil {
|
||||
|
@ -100,6 +105,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
|||
}
|
||||
|
||||
cnr.SetPlacementPolicy(*placementPolicy)
|
||||
cnr.SetBasicACL(basicACL)
|
||||
|
||||
var syncContainerPrm internalclient.SyncContainerPrm
|
||||
syncContainerPrm.SetClient(cli)
|
||||
|
@ -157,6 +163,10 @@ func initContainerCreateCmd() {
|
|||
flags.DurationP(commonflags.Timeout, commonflags.TimeoutShorthand, commonflags.TimeoutDefault, commonflags.TimeoutUsage)
|
||||
flags.StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, commonflags.WalletPathDefault, commonflags.WalletPathUsage)
|
||||
flags.StringP(commonflags.Account, commonflags.AccountShorthand, commonflags.AccountDefault, commonflags.AccountUsage)
|
||||
|
||||
flags.StringVar(&containerACL, "basic-acl", acl.NamePrivate, fmt.Sprintf("HEX encoded basic ACL value or keywords like '%s', '%s', '%s'",
|
||||
acl.NamePublicRW, acl.NamePrivate, acl.NamePublicROExtended,
|
||||
))
|
||||
flags.StringVarP(&containerPolicy, "policy", "p", "", "QL-encoded or JSON-encoded placement policy or path to file with it")
|
||||
flags.StringSliceVarP(&containerAttributes, "attributes", "a", nil, "Comma separated pairs of container attributes in form of Key1=Value1,Key2=Value2")
|
||||
flags.BoolVar(&containerAwait, "await", false, "Block execution until container is persisted")
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
|
@ -13,7 +14,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"github.com/chzyer/readline"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
@ -163,16 +163,6 @@ func (repl *policyPlaygroundREPL) netMap() netmap.NetMap {
|
|||
return nm
|
||||
}
|
||||
|
||||
var policyPlaygroundCompleter = readline.NewPrefixCompleter(
|
||||
readline.PcItem("list"),
|
||||
readline.PcItem("ls"),
|
||||
readline.PcItem("add"),
|
||||
readline.PcItem("load"),
|
||||
readline.PcItem("remove"),
|
||||
readline.PcItem("rm"),
|
||||
readline.PcItem("eval"),
|
||||
)
|
||||
|
||||
func (repl *policyPlaygroundREPL) run() error {
|
||||
if len(viper.GetString(commonflags.RPC)) > 0 {
|
||||
key := key.GetOrGenerate(repl.cmd)
|
||||
|
@ -199,38 +189,22 @@ func (repl *policyPlaygroundREPL) run() error {
|
|||
"rm": repl.handleRemove,
|
||||
"eval": repl.handleEval,
|
||||
}
|
||||
|
||||
rl, err := readline.NewEx(&readline.Config{
|
||||
Prompt: "> ",
|
||||
InterruptPrompt: "^C",
|
||||
AutoComplete: policyPlaygroundCompleter,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error initializing readline: %w", err)
|
||||
}
|
||||
defer rl.Close()
|
||||
|
||||
var exit bool
|
||||
for {
|
||||
line, err := rl.Readline()
|
||||
for reader := bufio.NewReader(os.Stdin); ; {
|
||||
fmt.Print("> ")
|
||||
line, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
if errors.Is(err, readline.ErrInterrupt) {
|
||||
if exit {
|
||||
return nil
|
||||
}
|
||||
exit = true
|
||||
continue
|
||||
if err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("reading line: %w", err)
|
||||
return fmt.Errorf("reading line: %v", err)
|
||||
}
|
||||
exit = false
|
||||
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) == 0 {
|
||||
continue
|
||||
}
|
||||
cmd := parts[0]
|
||||
if handler, exists := cmdHandlers[cmd]; exists {
|
||||
handler, exists := cmdHandlers[cmd]
|
||||
if exists {
|
||||
if err := handler(parts[1:]); err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
clientSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,11 +3,11 @@ package control
|
|||
import (
|
||||
"encoding/hex"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -3,11 +3,11 @@ package control
|
|||
import (
|
||||
"os"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ package control
|
|||
import (
|
||||
"os"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"github.com/spf13/cobra"
|
||||
|
|
|
@ -4,11 +4,11 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,11 +5,11 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
"strconv"
|
||||
"text/tabwriter"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/codes"
|
||||
|
|
|
@ -3,10 +3,10 @@ package control
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -4,10 +4,10 @@ import (
|
|||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -6,10 +6,10 @@ import (
|
|||
"slices"
|
||||
"strings"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -4,12 +4,12 @@ import (
|
|||
"crypto/sha256"
|
||||
"errors"
|
||||
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server/ctrlmessage"
|
||||
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -4,11 +4,11 @@ import (
|
|||
"crypto/ecdsa"
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server/ctrlmessage"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
"github.com/spf13/cobra"
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/mr-tron/base58"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
|
@ -6,12 +6,12 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
|
|
|
@ -7,12 +7,12 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/object"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
|
|
|
@ -195,7 +195,7 @@ func flattenComplexMembersIfECContainer(cmd *cobra.Command, cnrID cid.ID, member
|
|||
prmHead.SetRawFlag(true) // to get an error instead of whole object
|
||||
|
||||
eg, egCtx := errgroup.WithContext(cmd.Context())
|
||||
for idx := range members {
|
||||
for idx := range len(members) {
|
||||
partObjID := members[idx]
|
||||
|
||||
eg.Go(func() error {
|
||||
|
|
|
@ -10,11 +10,11 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/object"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/misc"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/config"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
@ -111,16 +112,14 @@ func initConfig() {
|
|||
// Use config file from the flag.
|
||||
viper.SetConfigFile(cfgFile)
|
||||
} else {
|
||||
// Find config directory.
|
||||
configDir, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
common.PrintVerbose(rootCmd, "Get config dir: %s", err)
|
||||
} else {
|
||||
// Search config in `$XDG_CONFIG_HOME/frostfs-cli/` with name "config.yaml"
|
||||
viper.AddConfigPath(filepath.Join(configDir, "frostfs-cli"))
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("yaml")
|
||||
}
|
||||
// Find home directory.
|
||||
home, err := homedir.Dir()
|
||||
commonCmd.ExitOnErr(rootCmd, "", err)
|
||||
|
||||
// Search config in `$HOME/.config/frostfs-cli/` with name "config.yaml"
|
||||
viper.AddConfigPath(filepath.Join(home, ".config", "frostfs-cli"))
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("yaml")
|
||||
}
|
||||
|
||||
viper.SetEnvPrefix(envPrefix)
|
||||
|
|
|
@ -30,6 +30,8 @@ func initAddCmd() {
|
|||
ff := addCmd.Flags()
|
||||
ff.StringSlice(metaFlagKey, nil, "Meta pairs in the form of Key1=[0x]Value1,Key2=[0x]Value2")
|
||||
ff.Uint64(parentIDFlagKey, 0, "Parent node ID")
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func add(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -36,6 +36,7 @@ func initAddByPathCmd() {
|
|||
ff.String(pathFlagKey, "", "Path to a node")
|
||||
ff.StringSlice(metaFlagKey, nil, "Meta pairs in the form of Key1=[0x]Value1,Key2=[0x]Value2")
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
_ = cobra.MarkFlagRequired(ff, pathFlagKey)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package tree
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
|
@ -21,13 +20,7 @@ import (
|
|||
// after making Tree API public.
|
||||
func _client() (tree.TreeServiceClient, error) {
|
||||
var netAddr network.Address
|
||||
|
||||
rpcEndpoint := viper.GetString(commonflags.RPC)
|
||||
if rpcEndpoint == "" {
|
||||
return nil, fmt.Errorf("%s is not defined", commonflags.RPC)
|
||||
}
|
||||
|
||||
err := netAddr.FromString(rpcEndpoint)
|
||||
err := netAddr.FromString(viper.GetString(commonflags.RPC))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -41,7 +34,6 @@ func _client() (tree.TreeServiceClient, error) {
|
|||
metrics.NewStreamClientInterceptor(),
|
||||
tracing.NewStreamClientInterceptor(),
|
||||
),
|
||||
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(netAddr.URIAddr(), "grpcs:") {
|
||||
|
|
|
@ -36,6 +36,8 @@ func initGetByPathCmd() {
|
|||
ff.String(pathFlagKey, "", "Path to a node")
|
||||
|
||||
ff.Bool(latestOnlyFlagKey, false, "Look only for the latest version of a node")
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func getByPath(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -30,6 +30,8 @@ func initGetOpLogCmd() {
|
|||
ff := getOpLogCmd.Flags()
|
||||
ff.Uint64(heightFlagKey, 0, "Height to start with")
|
||||
ff.Uint64(countFlagKey, 10, "Logged operations count")
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func getOpLog(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -20,6 +20,8 @@ var healthcheckCmd = &cobra.Command{
|
|||
|
||||
func initHealthcheckCmd() {
|
||||
commonflags.Init(healthcheckCmd)
|
||||
ff := healthcheckCmd.Flags()
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func healthcheck(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -26,6 +26,8 @@ func initListCmd() {
|
|||
ff := listCmd.Flags()
|
||||
ff.String(commonflags.CIDFlag, "", commonflags.CIDFlagUsage)
|
||||
_ = listCmd.MarkFlagRequired(commonflags.CIDFlag)
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func list(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -33,6 +33,8 @@ func initMoveCmd() {
|
|||
|
||||
_ = getSubtreeCmd.MarkFlagRequired(nodeIDFlagKey)
|
||||
_ = getSubtreeCmd.MarkFlagRequired(parentIDFlagKey)
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func move(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -29,6 +29,8 @@ func initRemoveCmd() {
|
|||
ff.Uint64(nodeIDFlagKey, 0, "Node ID.")
|
||||
|
||||
_ = getSubtreeCmd.MarkFlagRequired(nodeIDFlagKey)
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func remove(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -34,6 +34,8 @@ func initGetSubtreeCmd() {
|
|||
|
||||
_ = getSubtreeCmd.MarkFlagRequired(commonflags.CIDFlag)
|
||||
_ = getSubtreeCmd.MarkFlagRequired(treeIDFlagKey)
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
|
||||
}
|
||||
|
||||
func getSubTree(cmd *cobra.Command, _ []string) {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
@ -47,7 +46,7 @@ func reloadConfig() error {
|
|||
return logPrm.Reload()
|
||||
}
|
||||
|
||||
func watchForSignal(ctx context.Context, cancel func()) {
|
||||
func watchForSignal(cancel func()) {
|
||||
ch := make(chan os.Signal, 1)
|
||||
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
|
@ -59,49 +58,49 @@ func watchForSignal(ctx context.Context, cancel func()) {
|
|||
// signals causing application to shut down should have priority over
|
||||
// reconfiguration signal
|
||||
case <-ch:
|
||||
log.Info(ctx, logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
log.Info(logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
cancel()
|
||||
shutdown(ctx)
|
||||
log.Info(ctx, logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
shutdown()
|
||||
log.Info(logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
return
|
||||
case err := <-intErr: // internal application error
|
||||
log.Info(ctx, logs.FrostFSIRInternalError, zap.String("msg", err.Error()))
|
||||
log.Info(logs.FrostFSIRInternalError, zap.String("msg", err.Error()))
|
||||
cancel()
|
||||
shutdown(ctx)
|
||||
shutdown()
|
||||
return
|
||||
default:
|
||||
// block until any signal is receieved
|
||||
select {
|
||||
case <-ch:
|
||||
log.Info(ctx, logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
log.Info(logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
cancel()
|
||||
shutdown(ctx)
|
||||
log.Info(ctx, logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
shutdown()
|
||||
log.Info(logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
return
|
||||
case err := <-intErr: // internal application error
|
||||
log.Info(ctx, logs.FrostFSIRInternalError, zap.String("msg", err.Error()))
|
||||
log.Info(logs.FrostFSIRInternalError, zap.String("msg", err.Error()))
|
||||
cancel()
|
||||
shutdown(ctx)
|
||||
shutdown()
|
||||
return
|
||||
case <-sighupCh:
|
||||
log.Info(ctx, logs.FrostFSNodeSIGHUPHasBeenReceivedRereadingConfiguration)
|
||||
if !innerRing.CompareAndSwapHealthStatus(ctx, control.HealthStatus_READY, control.HealthStatus_RECONFIGURING) {
|
||||
log.Info(ctx, logs.FrostFSNodeSIGHUPSkip)
|
||||
log.Info(logs.FrostFSNodeSIGHUPHasBeenReceivedRereadingConfiguration)
|
||||
if !innerRing.CompareAndSwapHealthStatus(control.HealthStatus_READY, control.HealthStatus_RECONFIGURING) {
|
||||
log.Info(logs.FrostFSNodeSIGHUPSkip)
|
||||
break
|
||||
}
|
||||
err := reloadConfig()
|
||||
if err != nil {
|
||||
log.Error(ctx, logs.FrostFSNodeConfigurationReading, zap.Error(err))
|
||||
log.Error(logs.FrostFSNodeConfigurationReading, zap.Error(err))
|
||||
}
|
||||
pprofCmp.reload(ctx)
|
||||
metricsCmp.reload(ctx)
|
||||
log.Info(ctx, logs.FrostFSIRReloadExtraWallets)
|
||||
pprofCmp.reload()
|
||||
metricsCmp.reload()
|
||||
log.Info(logs.FrostFSIRReloadExtraWallets)
|
||||
err = innerRing.SetExtraWallets(cfg)
|
||||
if err != nil {
|
||||
log.Error(ctx, logs.FrostFSNodeConfigurationReading, zap.Error(err))
|
||||
log.Error(logs.FrostFSNodeConfigurationReading, zap.Error(err))
|
||||
}
|
||||
innerRing.CompareAndSwapHealthStatus(ctx, control.HealthStatus_RECONFIGURING, control.HealthStatus_READY)
|
||||
log.Info(ctx, logs.FrostFSNodeConfigurationHasBeenReloadedSuccessfully)
|
||||
innerRing.CompareAndSwapHealthStatus(control.HealthStatus_RECONFIGURING, control.HealthStatus_READY)
|
||||
log.Info(logs.FrostFSNodeConfigurationHasBeenReloadedSuccessfully)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,6 @@ func defaultConfiguration(cfg *viper.Viper) {
|
|||
cfg.SetDefault("node.kludge_compatibility_mode", false)
|
||||
|
||||
cfg.SetDefault("audit.enabled", false)
|
||||
|
||||
setMultinetDefaults(cfg)
|
||||
}
|
||||
|
||||
func setControlDefaults(cfg *viper.Viper) {
|
||||
|
@ -133,11 +131,3 @@ func setMorphDefaults(cfg *viper.Viper) {
|
|||
cfg.SetDefault("morph.validators", []string{})
|
||||
cfg.SetDefault("morph.switch_interval", 2*time.Minute)
|
||||
}
|
||||
|
||||
func setMultinetDefaults(cfg *viper.Viper) {
|
||||
cfg.SetDefault("multinet.enabled", false)
|
||||
cfg.SetDefault("multinet.balancer", "")
|
||||
cfg.SetDefault("multinet.restrict", false)
|
||||
cfg.SetDefault("multinet.fallback_delay", "0s")
|
||||
cfg.SetDefault("multinet.subnets", "")
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
@ -25,8 +24,8 @@ const (
|
|||
shutdownTimeoutKeyPostfix = ".shutdown_timeout"
|
||||
)
|
||||
|
||||
func (c *httpComponent) init(ctx context.Context) {
|
||||
log.Info(ctx, "init "+c.name)
|
||||
func (c *httpComponent) init() {
|
||||
log.Info("init " + c.name)
|
||||
c.enabled = cfg.GetBool(c.name + enabledKeyPostfix)
|
||||
c.address = cfg.GetString(c.name + addressKeyPostfix)
|
||||
c.shutdownDur = cfg.GetDuration(c.name + shutdownTimeoutKeyPostfix)
|
||||
|
@ -40,14 +39,14 @@ func (c *httpComponent) init(ctx context.Context) {
|
|||
httputil.WithShutdownTimeout(c.shutdownDur),
|
||||
)
|
||||
} else {
|
||||
log.Info(ctx, c.name+" is disabled, skip")
|
||||
log.Info(c.name + " is disabled, skip")
|
||||
c.srv = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (c *httpComponent) start(ctx context.Context) {
|
||||
func (c *httpComponent) start() {
|
||||
if c.srv != nil {
|
||||
log.Info(ctx, "start "+c.name)
|
||||
log.Info("start " + c.name)
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
@ -56,10 +55,10 @@ func (c *httpComponent) start(ctx context.Context) {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *httpComponent) shutdown(ctx context.Context) error {
|
||||
func (c *httpComponent) shutdown() error {
|
||||
if c.srv != nil {
|
||||
log.Info(ctx, "shutdown "+c.name)
|
||||
return c.srv.Shutdown(ctx)
|
||||
log.Info("shutdown " + c.name)
|
||||
return c.srv.Shutdown()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -71,17 +70,17 @@ func (c *httpComponent) needReload() bool {
|
|||
return enabled != c.enabled || enabled && (address != c.address || dur != c.shutdownDur)
|
||||
}
|
||||
|
||||
func (c *httpComponent) reload(ctx context.Context) {
|
||||
log.Info(ctx, "reload "+c.name)
|
||||
func (c *httpComponent) reload() {
|
||||
log.Info("reload " + c.name)
|
||||
if c.needReload() {
|
||||
log.Info(ctx, c.name+" config updated")
|
||||
if err := c.shutdown(ctx); err != nil {
|
||||
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
log.Info(c.name + " config updated")
|
||||
if err := c.shutdown(); err != nil {
|
||||
log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
} else {
|
||||
c.init(ctx)
|
||||
c.start(ctx)
|
||||
c.init()
|
||||
c.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,48 +87,48 @@ func main() {
|
|||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
pprofCmp = newPprofComponent()
|
||||
pprofCmp.init(ctx)
|
||||
pprofCmp.init()
|
||||
|
||||
metricsCmp = newMetricsComponent()
|
||||
metricsCmp.init(ctx)
|
||||
metricsCmp.init()
|
||||
audit.Store(cfg.GetBool("audit.enabled"))
|
||||
|
||||
innerRing, err = innerring.New(ctx, log, cfg, intErr, metrics, cmode, audit)
|
||||
exitErr(err)
|
||||
|
||||
pprofCmp.start(ctx)
|
||||
metricsCmp.start(ctx)
|
||||
pprofCmp.start()
|
||||
metricsCmp.start()
|
||||
|
||||
// start inner ring
|
||||
err = innerRing.Start(ctx, intErr)
|
||||
exitErr(err)
|
||||
|
||||
log.Info(ctx, logs.CommonApplicationStarted,
|
||||
log.Info(logs.CommonApplicationStarted,
|
||||
zap.String("version", misc.Version))
|
||||
|
||||
watchForSignal(ctx, cancel)
|
||||
watchForSignal(cancel)
|
||||
|
||||
<-ctx.Done() // graceful shutdown
|
||||
log.Debug(ctx, logs.FrostFSNodeWaitingForAllProcessesToStop)
|
||||
log.Debug(logs.FrostFSNodeWaitingForAllProcessesToStop)
|
||||
wg.Wait()
|
||||
|
||||
log.Info(ctx, logs.FrostFSIRApplicationStopped)
|
||||
log.Info(logs.FrostFSIRApplicationStopped)
|
||||
}
|
||||
|
||||
func shutdown(ctx context.Context) {
|
||||
innerRing.Stop(ctx)
|
||||
if err := metricsCmp.shutdown(ctx); err != nil {
|
||||
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
func shutdown() {
|
||||
innerRing.Stop()
|
||||
if err := metricsCmp.shutdown(); err != nil {
|
||||
log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
}
|
||||
if err := pprofCmp.shutdown(ctx); err != nil {
|
||||
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
if err := pprofCmp.shutdown(); err != nil {
|
||||
log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
}
|
||||
|
||||
if err := sdnotify.ClearStatus(); err != nil {
|
||||
log.Error(ctx, logs.FailedToReportStatusToSystemd, zap.Error(err))
|
||||
log.Error(logs.FailedToReportStatusToSystemd, zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"runtime"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
|
@ -29,8 +28,8 @@ func newPprofComponent() *pprofComponent {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *pprofComponent) init(ctx context.Context) {
|
||||
c.httpComponent.init(ctx)
|
||||
func (c *pprofComponent) init() {
|
||||
c.httpComponent.init()
|
||||
|
||||
if c.enabled {
|
||||
c.blockRate = cfg.GetInt(pprofBlockRateKey)
|
||||
|
@ -52,17 +51,17 @@ func (c *pprofComponent) needReload() bool {
|
|||
c.enabled && (c.blockRate != blockRate || c.mutexRate != mutexRate)
|
||||
}
|
||||
|
||||
func (c *pprofComponent) reload(ctx context.Context) {
|
||||
log.Info(ctx, "reload "+c.name)
|
||||
func (c *pprofComponent) reload() {
|
||||
log.Info("reload " + c.name)
|
||||
if c.needReload() {
|
||||
log.Info(ctx, c.name+" config updated")
|
||||
if err := c.shutdown(ctx); err != nil {
|
||||
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
log.Info(c.name + " config updated")
|
||||
if err := c.shutdown(); err != nil {
|
||||
log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
|
||||
zap.String("error", err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
c.init(ctx)
|
||||
c.start(ctx)
|
||||
c.init()
|
||||
c.start()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func inspectFunc(cmd *cobra.Command, _ []string) {
|
|||
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
|
||||
|
||||
blz := openBlobovnicza(cmd)
|
||||
defer blz.Close(cmd.Context())
|
||||
defer blz.Close()
|
||||
|
||||
var prm blobovnicza.GetPrm
|
||||
prm.SetAddress(addr)
|
||||
|
|
|
@ -32,7 +32,7 @@ func listFunc(cmd *cobra.Command, _ []string) {
|
|||
}
|
||||
|
||||
blz := openBlobovnicza(cmd)
|
||||
defer blz.Close(cmd.Context())
|
||||
defer blz.Close()
|
||||
|
||||
err := blobovnicza.IterateAddresses(context.Background(), blz, wAddr)
|
||||
common.ExitOnErr(cmd, common.Errf("blobovnicza iterator failure: %w", err))
|
||||
|
|
|
@ -27,7 +27,7 @@ func openBlobovnicza(cmd *cobra.Command) *blobovnicza.Blobovnicza {
|
|||
blobovnicza.WithPath(vPath),
|
||||
blobovnicza.WithReadOnly(true),
|
||||
)
|
||||
common.ExitOnErr(cmd, blz.Open(cmd.Context()))
|
||||
common.ExitOnErr(cmd, blz.Open())
|
||||
|
||||
return blz
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/spf13/cobra"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
var tuiCMD = &cobra.Command{
|
||||
|
@ -42,7 +43,7 @@ func tuiFunc(cmd *cobra.Command, _ []string) {
|
|||
}
|
||||
|
||||
func runTUI(cmd *cobra.Command) error {
|
||||
db, err := tui.OpenDB(vPath, false)
|
||||
db, err := openDB(false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't open database: %w", err)
|
||||
}
|
||||
|
@ -66,3 +67,13 @@ func runTUI(cmd *cobra.Command) error {
|
|||
app.SetRoot(ui, true).SetFocus(ui)
|
||||
return app.Run()
|
||||
}
|
||||
|
||||
func openDB(writable bool) (*bbolt.DB, error) {
|
||||
db, err := bbolt.Open(vPath, 0o600, &bbolt.Options{
|
||||
ReadOnly: !writable,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func inspectFunc(cmd *cobra.Command, _ []string) {
|
|||
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
|
||||
|
||||
db := openMeta(cmd)
|
||||
defer db.Close(cmd.Context())
|
||||
defer db.Close()
|
||||
|
||||
storageID := meta.StorageIDPrm{}
|
||||
storageID.SetAddress(addr)
|
||||
|
|
|
@ -19,7 +19,7 @@ func init() {
|
|||
|
||||
func listGarbageFunc(cmd *cobra.Command, _ []string) {
|
||||
db := openMeta(cmd)
|
||||
defer db.Close(cmd.Context())
|
||||
defer db.Close()
|
||||
|
||||
var garbPrm meta.GarbageIterationPrm
|
||||
garbPrm.SetHandler(
|
||||
|
|
|
@ -19,7 +19,7 @@ func init() {
|
|||
|
||||
func listGraveyardFunc(cmd *cobra.Command, _ []string) {
|
||||
db := openMeta(cmd)
|
||||
defer db.Close(cmd.Context())
|
||||
defer db.Close()
|
||||
|
||||
var gravePrm meta.GraveyardIterationPrm
|
||||
gravePrm.SetHandler(
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/spf13/cobra"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
var tuiCMD = &cobra.Command{
|
||||
|
@ -43,7 +44,7 @@ func tuiFunc(cmd *cobra.Command, _ []string) {
|
|||
}
|
||||
|
||||
func runTUI(cmd *cobra.Command) error {
|
||||
db, err := tui.OpenDB(vPath, false)
|
||||
db, err := openDB(false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't open database: %w", err)
|
||||
}
|
||||
|
@ -69,3 +70,13 @@ func runTUI(cmd *cobra.Command) error {
|
|||
app.SetRoot(ui, true).SetFocus(ui)
|
||||
return app.Run()
|
||||
}
|
||||
|
||||
func openDB(writable bool) (*bbolt.DB, error) {
|
||||
db, err := bbolt.Open(vPath, 0o600, &bbolt.Options{
|
||||
ReadOnly: !writable,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ func (r *ContainerVolumeRecord) String() string {
|
|||
|
||||
func (r *LockedRecord) String() string {
|
||||
return fmt.Sprintf(
|
||||
"Object OID %s %c Lockers [%d]OID {...}",
|
||||
"Locker OID %s %c Locked [%d]OID {...}",
|
||||
common.FormatSimple(fmt.Sprintf("%-44s", r.id), tcell.ColorAqua),
|
||||
tview.Borders.Vertical,
|
||||
len(r.ids),
|
||||
|
|
|
@ -11,7 +11,7 @@ func DecodeOIDs(data []byte) ([]oid.ID, error) {
|
|||
size := r.ReadVarUint()
|
||||
oids := make([]oid.ID, size)
|
||||
|
||||
for i := range size {
|
||||
for i := uint64(0); i < size; i++ {
|
||||
if err := oids[i].Decode(r.ReadVarBytes()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -3,25 +3,12 @@ package tui
|
|||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/mr-tron/base58"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
func OpenDB(path string, writable bool) (*bbolt.DB, error) {
|
||||
db, err := bbolt.Open(path, 0o600, &bbolt.Options{
|
||||
ReadOnly: !writable,
|
||||
Timeout: 100 * time.Millisecond,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func CIDParser(s string) (any, error) {
|
||||
data, err := base58.Decode(s)
|
||||
if err != nil {
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/spf13/cobra"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
||||
var tuiCMD = &cobra.Command{
|
||||
|
@ -42,7 +43,7 @@ func tuiFunc(cmd *cobra.Command, _ []string) {
|
|||
}
|
||||
|
||||
func runTUI(cmd *cobra.Command) error {
|
||||
db, err := tui.OpenDB(vPath, false)
|
||||
db, err := openDB(false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't open database: %w", err)
|
||||
}
|
||||
|
@ -66,3 +67,13 @@ func runTUI(cmd *cobra.Command) error {
|
|||
app.SetRoot(ui, true).SetFocus(ui)
|
||||
return app.Run()
|
||||
}
|
||||
|
||||
func openDB(writable bool) (*bbolt.DB, error) {
|
||||
db, err := bbolt.Open(vPath, 0o600, &bbolt.Options{
|
||||
ReadOnly: !writable,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
|
|
@ -3,18 +3,19 @@ package main
|
|||
import (
|
||||
"context"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
accountingGRPC "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/accounting/grpc"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/balance"
|
||||
accountingTransportGRPC "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network/transport/accounting/grpc"
|
||||
accountingService "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/accounting"
|
||||
accounting "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/accounting/morph"
|
||||
accountingGRPC "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/accounting/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func initAccountingService(ctx context.Context, c *cfg) {
|
||||
c.initMorphComponents(ctx)
|
||||
if c.cfgMorph.client == nil {
|
||||
initMorphComponents(ctx, c)
|
||||
}
|
||||
|
||||
balanceMorphWrapper, err := balance.NewFromMorph(c.cfgMorph.client, c.cfgAccounting.scriptHash, 0)
|
||||
fatalOnErr(err)
|
||||
|
@ -31,27 +32,5 @@ func initAccountingService(ctx context.Context, c *cfg) {
|
|||
|
||||
c.cfgGRPC.performAndSave(func(_ string, _ net.Listener, s *grpc.Server) {
|
||||
accountingGRPC.RegisterAccountingServiceServer(s, server)
|
||||
|
||||
// TODO(@aarifullin): #1487 remove the dual service support.
|
||||
s.RegisterService(frostFSServiceDesc(accountingGRPC.AccountingService_ServiceDesc), server)
|
||||
})
|
||||
}
|
||||
|
||||
// frostFSServiceDesc creates a service descriptor with the new namespace for dual service support.
|
||||
func frostFSServiceDesc(sd grpc.ServiceDesc) *grpc.ServiceDesc {
|
||||
sdLegacy := new(grpc.ServiceDesc)
|
||||
*sdLegacy = sd
|
||||
|
||||
const (
|
||||
legacyNamespace = "neo.fs.v2"
|
||||
apemanagerLegacyNamespace = "frostfs.v2"
|
||||
newNamespace = "frost.fs"
|
||||
)
|
||||
|
||||
if strings.HasPrefix(sd.ServiceName, legacyNamespace) {
|
||||
sdLegacy.ServiceName = strings.ReplaceAll(sd.ServiceName, legacyNamespace, newNamespace)
|
||||
} else if strings.HasPrefix(sd.ServiceName, apemanagerLegacyNamespace) {
|
||||
sdLegacy.ServiceName = strings.ReplaceAll(sd.ServiceName, apemanagerLegacyNamespace, newNamespace)
|
||||
}
|
||||
return sdLegacy
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@ package main
|
|||
import (
|
||||
"net"
|
||||
|
||||
apemanager_grpc "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager/grpc"
|
||||
ape_contract "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/contract_storage"
|
||||
morph "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
apemanager_transport "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network/transport/apemanager/grpc"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/apemanager"
|
||||
apemanager_grpc "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/apemanager/grpc"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
|
@ -26,8 +26,5 @@ func initAPEManagerService(c *cfg) {
|
|||
|
||||
c.cfgGRPC.performAndSave(func(_ string, _ net.Listener, s *grpc.Server) {
|
||||
apemanager_grpc.RegisterAPEManagerServiceServer(s, server)
|
||||
|
||||
// TODO(@aarifullin): #1487 remove the dual service support.
|
||||
s.RegisterService(frostFSServiceDesc(apemanager_grpc.APEManagerService_ServiceDesc), server)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -165,11 +165,13 @@ type ttlContainerStorage struct {
|
|||
delInfoCache *ttlNetCache[cid.ID, *container.DelInfo]
|
||||
}
|
||||
|
||||
func newCachedContainerStorage(v container.Source, ttl time.Duration, containerCacheSize uint32) ttlContainerStorage {
|
||||
lruCnrCache := newNetworkTTLCache(int(containerCacheSize), ttl, func(id cid.ID) (*container.Container, error) {
|
||||
func newCachedContainerStorage(v container.Source, ttl time.Duration) ttlContainerStorage {
|
||||
const containerCacheSize = 100
|
||||
|
||||
lruCnrCache := newNetworkTTLCache(containerCacheSize, ttl, func(id cid.ID) (*container.Container, error) {
|
||||
return v.Get(id)
|
||||
}, metrics.NewCacheMetrics("container"))
|
||||
lruDelInfoCache := newNetworkTTLCache(int(containerCacheSize), ttl, func(id cid.ID) (*container.DelInfo, error) {
|
||||
lruDelInfoCache := newNetworkTTLCache(containerCacheSize, ttl, func(id cid.ID) (*container.DelInfo, error) {
|
||||
return v.DeletionInfo(id)
|
||||
}, metrics.NewCacheMetrics("container_deletion_info"))
|
||||
|
||||
|
@ -196,6 +198,31 @@ func (s ttlContainerStorage) DeletionInfo(cnr cid.ID) (*container.DelInfo, error
|
|||
return s.delInfoCache.get(cnr)
|
||||
}
|
||||
|
||||
type ttlEACLStorage struct {
|
||||
*ttlNetCache[cid.ID, *container.EACL]
|
||||
}
|
||||
|
||||
func newCachedEACLStorage(v container.EACLSource, ttl time.Duration) ttlEACLStorage {
|
||||
const eaclCacheSize = 100
|
||||
|
||||
lruCnrCache := newNetworkTTLCache(eaclCacheSize, ttl, func(id cid.ID) (*container.EACL, error) {
|
||||
return v.GetEACL(id)
|
||||
}, metrics.NewCacheMetrics("eacl"))
|
||||
|
||||
return ttlEACLStorage{lruCnrCache}
|
||||
}
|
||||
|
||||
// GetEACL returns eACL value from the cache. If value is missing in the cache
|
||||
// or expired, then it returns value from side chain and updates cache.
|
||||
func (s ttlEACLStorage) GetEACL(cnr cid.ID) (*container.EACL, error) {
|
||||
return s.get(cnr)
|
||||
}
|
||||
|
||||
// InvalidateEACL removes cached eACL value.
|
||||
func (s ttlEACLStorage) InvalidateEACL(cnr cid.ID) {
|
||||
s.remove(cnr)
|
||||
}
|
||||
|
||||
type lruNetmapSource struct {
|
||||
netState netmap.State
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
netmapV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
||||
apiclientconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/apiclient"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/audit"
|
||||
|
@ -25,14 +26,12 @@ import (
|
|||
fstreeconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard/blobstor/fstree"
|
||||
loggerconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/logger"
|
||||
morphconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/morph"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/multinet"
|
||||
nodeconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/node"
|
||||
objectconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/object"
|
||||
replicatorconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/replicator"
|
||||
tracingconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/tracing"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/metrics"
|
||||
internalNet "git.frostfs.info/TrueCloudLab/frostfs-node/internal/net"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/ape/chainbase"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||
frostfsidcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/frostfsid"
|
||||
|
@ -57,7 +56,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
objectService "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object"
|
||||
getsvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object/get"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object_manager/placement"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object_manager/tombstone"
|
||||
tsourse "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object_manager/tombstone/source"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/replicator"
|
||||
|
@ -69,7 +67,6 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/state"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/logging/lokicore"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
netmapV2 "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
|
@ -108,11 +105,6 @@ type applicationConfiguration struct {
|
|||
timestamp bool
|
||||
}
|
||||
|
||||
ObjectCfg struct {
|
||||
tombstoneLifetime uint64
|
||||
priorityMetrics []placement.Metric
|
||||
}
|
||||
|
||||
EngineCfg struct {
|
||||
errorThreshold uint32
|
||||
shardPoolSize uint32
|
||||
|
@ -231,19 +223,6 @@ func (a *applicationConfiguration) readConfig(c *config.Config) error {
|
|||
a.LoggerCfg.destination = loggerconfig.Destination(c)
|
||||
a.LoggerCfg.timestamp = loggerconfig.Timestamp(c)
|
||||
|
||||
// Object
|
||||
|
||||
a.ObjectCfg.tombstoneLifetime = objectconfig.TombstoneLifetime(c)
|
||||
var pm []placement.Metric
|
||||
for _, raw := range objectconfig.Get(c).Priority() {
|
||||
m, err := placement.ParseMetric(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pm = append(pm, m)
|
||||
}
|
||||
a.ObjectCfg.priorityMetrics = pm
|
||||
|
||||
// Storage Engine
|
||||
|
||||
a.EngineCfg.errorThreshold = engineconfig.ShardErrorThreshold(c)
|
||||
|
@ -397,16 +376,16 @@ type internals struct {
|
|||
}
|
||||
|
||||
// starts node's maintenance.
|
||||
func (c *cfg) startMaintenance(ctx context.Context) {
|
||||
func (c *cfg) startMaintenance() {
|
||||
c.isMaintenance.Store(true)
|
||||
c.cfgNetmap.state.setControlNetmapStatus(control.NetmapStatus_MAINTENANCE)
|
||||
c.log.Info(ctx, logs.FrostFSNodeStartedLocalNodesMaintenance)
|
||||
c.log.Info(logs.FrostFSNodeStartedLocalNodesMaintenance)
|
||||
}
|
||||
|
||||
// stops node's maintenance.
|
||||
func (c *internals) stopMaintenance(ctx context.Context) {
|
||||
func (c *internals) stopMaintenance() {
|
||||
if c.isMaintenance.CompareAndSwap(true, false) {
|
||||
c.log.Info(ctx, logs.FrostFSNodeStoppedLocalNodesMaintenance)
|
||||
c.log.Info(logs.FrostFSNodeStoppedLocalNodesMaintenance)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -449,8 +428,6 @@ type shared struct {
|
|||
metricsCollector *metrics.NodeMetrics
|
||||
|
||||
metricsSvc *objectService.MetricCollector
|
||||
|
||||
dialerSource *internalNet.DialerSource
|
||||
}
|
||||
|
||||
// dynamicConfiguration stores parameters of the
|
||||
|
@ -586,9 +563,6 @@ func (c *cfgGRPC) dropConnection(endpoint string) {
|
|||
}
|
||||
|
||||
type cfgMorph struct {
|
||||
initialized bool
|
||||
guard sync.Mutex
|
||||
|
||||
client *client.Client
|
||||
|
||||
notaryEnabled bool
|
||||
|
@ -596,8 +570,6 @@ type cfgMorph struct {
|
|||
// TTL of Sidechain cached values. Non-positive value disables caching.
|
||||
cacheTTL time.Duration
|
||||
|
||||
containerCacheSize uint32
|
||||
|
||||
proxyScriptHash neogoutil.Uint160
|
||||
}
|
||||
|
||||
|
@ -642,13 +614,15 @@ type cfgObject struct {
|
|||
|
||||
cnrSource container.Source
|
||||
|
||||
eaclSource container.EACLSource
|
||||
|
||||
cfgAccessPolicyEngine cfgAccessPolicyEngine
|
||||
|
||||
pool cfgObjectRoutines
|
||||
|
||||
cfgLocalStorage cfgLocalStorage
|
||||
|
||||
tombstoneLifetime *atomic.Uint64
|
||||
tombstoneLifetime uint64
|
||||
|
||||
skipSessionTokenIssuerVerification bool
|
||||
}
|
||||
|
@ -705,7 +679,7 @@ func initCfg(appCfg *config.Config) *cfg {
|
|||
log, err := logger.NewLogger(logPrm)
|
||||
fatalOnErr(err)
|
||||
if loggerconfig.ToLokiConfig(appCfg).Enabled {
|
||||
log.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
|
||||
log.Logger = log.Logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core {
|
||||
lokiCore := lokicore.New(core, loggerconfig.ToLokiConfig(appCfg))
|
||||
return lokiCore
|
||||
}))
|
||||
|
@ -776,18 +750,12 @@ func initShared(appCfg *config.Config, key *keys.PrivateKey, netState *networkSt
|
|||
persistate, err := state.NewPersistentStorage(nodeconfig.PersistentState(appCfg).Path())
|
||||
fatalOnErr(err)
|
||||
|
||||
nodeMetrics := metrics.NewNodeMetrics()
|
||||
|
||||
ds, err := internalNet.NewDialerSource(internalNetConfig(appCfg, nodeMetrics.MultinetMetrics()))
|
||||
fatalOnErr(err)
|
||||
|
||||
cacheOpts := cache.ClientCacheOpts{
|
||||
DialTimeout: apiclientconfig.DialTimeout(appCfg),
|
||||
StreamTimeout: apiclientconfig.StreamTimeout(appCfg),
|
||||
Key: &key.PrivateKey,
|
||||
AllowExternal: apiclientconfig.AllowExternal(appCfg),
|
||||
ReconnectTimeout: apiclientconfig.ReconnectTimeout(appCfg),
|
||||
DialerSource: ds,
|
||||
}
|
||||
|
||||
return shared{
|
||||
|
@ -799,29 +767,10 @@ func initShared(appCfg *config.Config, key *keys.PrivateKey, netState *networkSt
|
|||
bgClientCache: cache.NewSDKClientCache(cacheOpts),
|
||||
putClientCache: cache.NewSDKClientCache(cacheOpts),
|
||||
persistate: persistate,
|
||||
metricsCollector: nodeMetrics,
|
||||
dialerSource: ds,
|
||||
metricsCollector: metrics.NewNodeMetrics(),
|
||||
}
|
||||
}
|
||||
|
||||
func internalNetConfig(appCfg *config.Config, m metrics.MultinetMetrics) internalNet.Config {
|
||||
result := internalNet.Config{
|
||||
Enabled: multinet.Enabled(appCfg),
|
||||
Balancer: multinet.Balancer(appCfg),
|
||||
Restrict: multinet.Restrict(appCfg),
|
||||
FallbackDelay: multinet.FallbackDelay(appCfg),
|
||||
Metrics: m,
|
||||
}
|
||||
sn := multinet.Subnets(appCfg)
|
||||
for _, s := range sn {
|
||||
result.Subnets = append(result.Subnets, internalNet.Subnet{
|
||||
Prefix: s.Mask,
|
||||
SourceIPs: s.SourceIPs,
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func initNetmap(appCfg *config.Config, netState *networkState, relayOnly bool) cfgNetmap {
|
||||
netmapWorkerPool, err := ants.NewPool(notificationHandlerPoolSize)
|
||||
fatalOnErr(err)
|
||||
|
@ -864,11 +813,9 @@ func initCfgGRPC() cfgGRPC {
|
|||
}
|
||||
|
||||
func initCfgObject(appCfg *config.Config) cfgObject {
|
||||
var tsLifetime atomic.Uint64
|
||||
tsLifetime.Store(objectconfig.TombstoneLifetime(appCfg))
|
||||
return cfgObject{
|
||||
pool: initObjectPool(appCfg),
|
||||
tombstoneLifetime: &tsLifetime,
|
||||
tombstoneLifetime: objectconfig.TombstoneLifetime(appCfg),
|
||||
skipSessionTokenIssuerVerification: objectconfig.Put(appCfg).SkipSessionTokenIssuerVerification(),
|
||||
}
|
||||
}
|
||||
|
@ -1089,7 +1036,7 @@ func (c *cfg) LocalAddress() network.AddressGroup {
|
|||
func initLocalStorage(ctx context.Context, c *cfg) {
|
||||
ls := engine.New(c.engineOpts()...)
|
||||
|
||||
addNewEpochAsyncNotificationHandler(c, func(ctx context.Context, ev event.Event) {
|
||||
addNewEpochAsyncNotificationHandler(c, func(ev event.Event) {
|
||||
ls.HandleNewEpoch(ctx, ev.(netmap2.NewEpoch).EpochNumber())
|
||||
})
|
||||
|
||||
|
@ -1099,14 +1046,12 @@ func initLocalStorage(ctx context.Context, c *cfg) {
|
|||
|
||||
var shardsAttached int
|
||||
for _, optsWithMeta := range c.shardOpts(ctx) {
|
||||
id, err := ls.AddShard(ctx, append(optsWithMeta.shOpts,
|
||||
shard.WithTombstoneSource(c.createTombstoneSource()),
|
||||
shard.WithContainerInfoProvider(c.createContainerInfoProvider(ctx)))...)
|
||||
id, err := ls.AddShard(ctx, append(optsWithMeta.shOpts, shard.WithTombstoneSource(c.createTombstoneSource()))...)
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeFailedToAttachShardToEngine, zap.Error(err))
|
||||
c.log.Error(logs.FrostFSNodeFailedToAttachShardToEngine, zap.Error(err))
|
||||
} else {
|
||||
shardsAttached++
|
||||
c.log.Info(ctx, logs.FrostFSNodeShardAttachedToEngine, zap.Stringer("id", id))
|
||||
c.log.Info(logs.FrostFSNodeShardAttachedToEngine, zap.Stringer("id", id))
|
||||
}
|
||||
}
|
||||
if shardsAttached == 0 {
|
||||
|
@ -1116,23 +1061,23 @@ func initLocalStorage(ctx context.Context, c *cfg) {
|
|||
c.cfgObject.cfgLocalStorage.localStorage = ls
|
||||
|
||||
c.onShutdown(func() {
|
||||
c.log.Info(ctx, logs.FrostFSNodeClosingComponentsOfTheStorageEngine)
|
||||
c.log.Info(logs.FrostFSNodeClosingComponentsOfTheStorageEngine)
|
||||
|
||||
err := ls.Close(context.WithoutCancel(ctx))
|
||||
if err != nil {
|
||||
c.log.Info(ctx, logs.FrostFSNodeStorageEngineClosingFailure,
|
||||
c.log.Info(logs.FrostFSNodeStorageEngineClosingFailure,
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
} else {
|
||||
c.log.Info(ctx, logs.FrostFSNodeAllComponentsOfTheStorageEngineClosedSuccessfully)
|
||||
c.log.Info(logs.FrostFSNodeAllComponentsOfTheStorageEngineClosedSuccessfully)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func initAccessPolicyEngine(ctx context.Context, c *cfg) {
|
||||
func initAccessPolicyEngine(_ context.Context, c *cfg) {
|
||||
var localOverrideDB chainbase.LocalOverrideDatabase
|
||||
if nodeconfig.PersistentPolicyRules(c.appCfg).Path() == "" {
|
||||
c.log.Warn(ctx, logs.FrostFSNodePersistentRuleStorageDBPathIsNotSetInmemoryWillBeUsed)
|
||||
c.log.Warn(logs.FrostFSNodePersistentRuleStorageDBPathIsNotSetInmemoryWillBeUsed)
|
||||
localOverrideDB = chainbase.NewInmemoryLocalOverrideDatabase()
|
||||
} else {
|
||||
localOverrideDB = chainbase.NewBoltLocalOverrideDatabase(
|
||||
|
@ -1157,7 +1102,7 @@ func initAccessPolicyEngine(ctx context.Context, c *cfg) {
|
|||
|
||||
c.onShutdown(func() {
|
||||
if err := ape.LocalOverrideDatabaseCore().Close(); err != nil {
|
||||
c.log.Warn(ctx, logs.FrostFSNodeAccessPolicyEngineClosingFailure,
|
||||
c.log.Warn(logs.FrostFSNodeAccessPolicyEngineClosingFailure,
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
|
@ -1188,15 +1133,17 @@ func initObjectPool(cfg *config.Config) (pool cfgObjectRoutines) {
|
|||
return pool
|
||||
}
|
||||
|
||||
func (c *cfg) LocalNodeInfo() *netmap.NodeInfo {
|
||||
var res netmap.NodeInfo
|
||||
func (c *cfg) LocalNodeInfo() (*netmapV2.NodeInfo, error) {
|
||||
var res netmapV2.NodeInfo
|
||||
|
||||
ni, ok := c.cfgNetmap.state.getNodeInfo()
|
||||
if ok {
|
||||
res = ni
|
||||
ni.WriteToV2(&res)
|
||||
} else {
|
||||
res = c.cfgNodeInfo.localInfo
|
||||
c.cfgNodeInfo.localInfo.WriteToV2(&res)
|
||||
}
|
||||
return &res
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// setContractNodeInfo rewrites local node info from the FrostFS network map.
|
||||
|
@ -1206,10 +1153,10 @@ func (c *cfg) setContractNodeInfo(ni *netmap.NodeInfo) {
|
|||
c.cfgNetmap.state.setNodeInfo(ni)
|
||||
}
|
||||
|
||||
func (c *cfg) updateContractNodeInfo(ctx context.Context, epoch uint64) {
|
||||
func (c *cfg) updateContractNodeInfo(epoch uint64) {
|
||||
ni, err := c.netmapLocalNodeState(epoch)
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeCouldNotUpdateNodeStateOnNewEpoch,
|
||||
c.log.Error(logs.FrostFSNodeCouldNotUpdateNodeStateOnNewEpoch,
|
||||
zap.Uint64("epoch", epoch),
|
||||
zap.String("error", err.Error()))
|
||||
return
|
||||
|
@ -1221,19 +1168,19 @@ func (c *cfg) updateContractNodeInfo(ctx context.Context, epoch uint64) {
|
|||
// bootstrapWithState calls "addPeer" method of the Sidechain Netmap contract
|
||||
// with the binary-encoded information from the current node's configuration.
|
||||
// The state is set using the provided setter which MUST NOT be nil.
|
||||
func (c *cfg) bootstrapWithState(ctx context.Context, stateSetter func(*netmap.NodeInfo)) error {
|
||||
func (c *cfg) bootstrapWithState(stateSetter func(*netmap.NodeInfo)) error {
|
||||
ni := c.cfgNodeInfo.localInfo
|
||||
stateSetter(&ni)
|
||||
|
||||
prm := nmClient.AddPeerPrm{}
|
||||
prm.SetNodeInfo(ni)
|
||||
|
||||
return c.cfgNetmap.wrapper.AddPeer(ctx, prm)
|
||||
return c.cfgNetmap.wrapper.AddPeer(prm)
|
||||
}
|
||||
|
||||
// bootstrapOnline calls cfg.bootstrapWithState with "online" state.
|
||||
func bootstrapOnline(ctx context.Context, c *cfg) error {
|
||||
return c.bootstrapWithState(ctx, func(ni *netmap.NodeInfo) {
|
||||
func bootstrapOnline(c *cfg) error {
|
||||
return c.bootstrapWithState(func(ni *netmap.NodeInfo) {
|
||||
ni.SetStatus(netmap.Online)
|
||||
})
|
||||
}
|
||||
|
@ -1241,21 +1188,21 @@ func bootstrapOnline(ctx context.Context, c *cfg) error {
|
|||
// bootstrap calls bootstrapWithState with:
|
||||
// - "maintenance" state if maintenance is in progress on the current node
|
||||
// - "online", otherwise
|
||||
func (c *cfg) bootstrap(ctx context.Context) error {
|
||||
func (c *cfg) bootstrap() error {
|
||||
// switch to online except when under maintenance
|
||||
st := c.cfgNetmap.state.controlNetmapStatus()
|
||||
if st == control.NetmapStatus_MAINTENANCE {
|
||||
c.log.Info(ctx, logs.FrostFSNodeBootstrappingWithTheMaintenanceState)
|
||||
return c.bootstrapWithState(ctx, func(ni *netmap.NodeInfo) {
|
||||
c.log.Info(logs.FrostFSNodeBootstrappingWithTheMaintenanceState)
|
||||
return c.bootstrapWithState(func(ni *netmap.NodeInfo) {
|
||||
ni.SetStatus(netmap.Maintenance)
|
||||
})
|
||||
}
|
||||
|
||||
c.log.Info(ctx, logs.FrostFSNodeBootstrappingWithOnlineState,
|
||||
c.log.Info(logs.FrostFSNodeBootstrappingWithOnlineState,
|
||||
zap.Stringer("previous", st),
|
||||
)
|
||||
|
||||
return bootstrapOnline(ctx, c)
|
||||
return bootstrapOnline(c)
|
||||
}
|
||||
|
||||
// needBootstrap checks if local node should be registered in network on bootup.
|
||||
|
@ -1280,19 +1227,19 @@ func (c *cfg) signalWatcher(ctx context.Context) {
|
|||
// signals causing application to shut down should have priority over
|
||||
// reconfiguration signal
|
||||
case <-ch:
|
||||
c.log.Info(ctx, logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
c.log.Info(logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
|
||||
c.shutdown(ctx)
|
||||
c.shutdown()
|
||||
|
||||
c.log.Info(ctx, logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
c.log.Info(logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
return
|
||||
case err := <-c.internalErr: // internal application error
|
||||
c.log.Warn(ctx, logs.FrostFSNodeInternalApplicationError,
|
||||
c.log.Warn(logs.FrostFSNodeInternalApplicationError,
|
||||
zap.String("message", err.Error()))
|
||||
|
||||
c.shutdown(ctx)
|
||||
c.shutdown()
|
||||
|
||||
c.log.Info(ctx, logs.FrostFSNodeInternalErrorProcessingIsComplete)
|
||||
c.log.Info(logs.FrostFSNodeInternalErrorProcessingIsComplete)
|
||||
return
|
||||
default:
|
||||
// block until any signal is receieved
|
||||
|
@ -1300,19 +1247,19 @@ func (c *cfg) signalWatcher(ctx context.Context) {
|
|||
case <-sighupCh:
|
||||
c.reloadConfig(ctx)
|
||||
case <-ch:
|
||||
c.log.Info(ctx, logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
c.log.Info(logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
|
||||
|
||||
c.shutdown(ctx)
|
||||
c.shutdown()
|
||||
|
||||
c.log.Info(ctx, logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
c.log.Info(logs.FrostFSNodeTerminationSignalProcessingIsComplete)
|
||||
return
|
||||
case err := <-c.internalErr: // internal application error
|
||||
c.log.Warn(ctx, logs.FrostFSNodeInternalApplicationError,
|
||||
c.log.Warn(logs.FrostFSNodeInternalApplicationError,
|
||||
zap.String("message", err.Error()))
|
||||
|
||||
c.shutdown(ctx)
|
||||
c.shutdown()
|
||||
|
||||
c.log.Info(ctx, logs.FrostFSNodeInternalErrorProcessingIsComplete)
|
||||
c.log.Info(logs.FrostFSNodeInternalErrorProcessingIsComplete)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -1320,17 +1267,17 @@ func (c *cfg) signalWatcher(ctx context.Context) {
|
|||
}
|
||||
|
||||
func (c *cfg) reloadConfig(ctx context.Context) {
|
||||
c.log.Info(ctx, logs.FrostFSNodeSIGHUPHasBeenReceivedRereadingConfiguration)
|
||||
c.log.Info(logs.FrostFSNodeSIGHUPHasBeenReceivedRereadingConfiguration)
|
||||
|
||||
if !c.compareAndSwapHealthStatus(ctx, control.HealthStatus_READY, control.HealthStatus_RECONFIGURING) {
|
||||
c.log.Info(ctx, logs.FrostFSNodeSIGHUPSkip)
|
||||
if !c.compareAndSwapHealthStatus(control.HealthStatus_READY, control.HealthStatus_RECONFIGURING) {
|
||||
c.log.Info(logs.FrostFSNodeSIGHUPSkip)
|
||||
return
|
||||
}
|
||||
defer c.compareAndSwapHealthStatus(ctx, control.HealthStatus_RECONFIGURING, control.HealthStatus_READY)
|
||||
defer c.compareAndSwapHealthStatus(control.HealthStatus_RECONFIGURING, control.HealthStatus_READY)
|
||||
|
||||
err := c.reloadAppConfig()
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeConfigurationReading, zap.Error(err))
|
||||
c.log.Error(logs.FrostFSNodeConfigurationReading, zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -1341,46 +1288,35 @@ func (c *cfg) reloadConfig(ctx context.Context) {
|
|||
|
||||
logPrm, err := c.loggerPrm()
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeLoggerConfigurationPreparation, zap.Error(err))
|
||||
c.log.Error(logs.FrostFSNodeLoggerConfigurationPreparation, zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
components := c.getComponents(ctx, logPrm)
|
||||
|
||||
// Object
|
||||
c.cfgObject.tombstoneLifetime.Store(c.ObjectCfg.tombstoneLifetime)
|
||||
|
||||
// Storage Engine
|
||||
|
||||
var rcfg engine.ReConfiguration
|
||||
for _, optsWithID := range c.shardOpts(ctx) {
|
||||
rcfg.AddShard(optsWithID.configID, append(optsWithID.shOpts,
|
||||
shard.WithTombstoneSource(c.createTombstoneSource()),
|
||||
shard.WithContainerInfoProvider(c.createContainerInfoProvider(ctx)),
|
||||
))
|
||||
rcfg.AddShard(optsWithID.configID, append(optsWithID.shOpts, shard.WithTombstoneSource(c.createTombstoneSource())))
|
||||
}
|
||||
|
||||
err = c.cfgObject.cfgLocalStorage.localStorage.Reload(ctx, rcfg)
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeStorageEngineConfigurationUpdate, zap.Error(err))
|
||||
c.log.Error(logs.FrostFSNodeStorageEngineConfigurationUpdate, zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
for _, component := range components {
|
||||
err = component.reloadFunc()
|
||||
if err != nil {
|
||||
c.log.Error(ctx, logs.FrostFSNodeUpdatedConfigurationApplying,
|
||||
c.log.Error(logs.FrostFSNodeUpdatedConfigurationApplying,
|
||||
zap.String("component", component.name),
|
||||
zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.dialerSource.Update(internalNetConfig(c.appCfg, c.metricsCollector.MultinetMetrics())); err != nil {
|
||||
c.log.Error(ctx, logs.FailedToUpdateMultinetConfiguration, zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
||||
c.log.Info(ctx, logs.FrostFSNodeConfigurationHasBeenReloadedSuccessfully)
|
||||
c.log.Info(logs.FrostFSNodeConfigurationHasBeenReloadedSuccessfully)
|
||||
}
|
||||
|
||||
func (c *cfg) getComponents(ctx context.Context, logPrm *logger.Prm) []dCmp {
|
||||
|
@ -1388,7 +1324,7 @@ func (c *cfg) getComponents(ctx context.Context, logPrm *logger.Prm) []dCmp {
|
|||
|
||||
components = append(components, dCmp{"logger", logPrm.Reload})
|
||||
components = append(components, dCmp{"runtime", func() error {
|
||||
setRuntimeParameters(ctx, c)
|
||||
setRuntimeParameters(c)
|
||||
return nil
|
||||
}})
|
||||
components = append(components, dCmp{"audit", func() error {
|
||||
|
@ -1403,7 +1339,7 @@ func (c *cfg) getComponents(ctx context.Context, logPrm *logger.Prm) []dCmp {
|
|||
}
|
||||
updated, err := tracing.Setup(ctx, *traceConfig)
|
||||
if updated {
|
||||
c.log.Info(ctx, logs.FrostFSNodeTracingConfigationUpdated)
|
||||
c.log.Info(logs.FrostFSNodeTracingConfigationUpdated)
|
||||
}
|
||||
return err
|
||||
}})
|
||||
|
@ -1438,7 +1374,7 @@ func (c *cfg) reloadPools() error {
|
|||
func (c *cfg) reloadPool(p *ants.Pool, newSize int, name string) {
|
||||
oldSize := p.Cap()
|
||||
if oldSize != newSize {
|
||||
c.log.Info(context.Background(), logs.FrostFSNodePoolConfigurationUpdate, zap.String("field", name),
|
||||
c.log.Info(logs.FrostFSNodePoolConfigurationUpdate, zap.String("field", name),
|
||||
zap.Int("old", oldSize), zap.Int("new", newSize))
|
||||
p.Tune(newSize)
|
||||
}
|
||||
|
@ -1463,25 +1399,14 @@ func (c *cfg) createTombstoneSource() *tombstone.ExpirationChecker {
|
|||
return tombstoneSource
|
||||
}
|
||||
|
||||
func (c *cfg) createContainerInfoProvider(ctx context.Context) container.InfoProvider {
|
||||
return container.NewInfoProvider(func() (container.Source, error) {
|
||||
c.initMorphComponents(ctx)
|
||||
cc, err := containerClient.NewFromMorph(c.cfgMorph.client, c.cfgContainer.scriptHash, 0, containerClient.TryNotary())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return containerClient.AsContainerSource(cc), nil
|
||||
})
|
||||
}
|
||||
|
||||
func (c *cfg) shutdown(ctx context.Context) {
|
||||
old := c.swapHealthStatus(ctx, control.HealthStatus_SHUTTING_DOWN)
|
||||
func (c *cfg) shutdown() {
|
||||
old := c.swapHealthStatus(control.HealthStatus_SHUTTING_DOWN)
|
||||
if old == control.HealthStatus_SHUTTING_DOWN {
|
||||
c.log.Info(ctx, logs.FrostFSNodeShutdownSkip)
|
||||
c.log.Info(logs.FrostFSNodeShutdownSkip)
|
||||
return
|
||||
}
|
||||
if old == control.HealthStatus_STARTING {
|
||||
c.log.Warn(ctx, logs.FrostFSNodeShutdownWhenNotReady)
|
||||
c.log.Warn(logs.FrostFSNodeShutdownWhenNotReady)
|
||||
}
|
||||
|
||||
c.ctxCancel()
|
||||
|
@ -1491,6 +1416,6 @@ func (c *cfg) shutdown(ctx context.Context) {
|
|||
}
|
||||
|
||||
if err := sdnotify.ClearStatus(); err != nil {
|
||||
c.log.Error(ctx, logs.FailedToReportStatusToSystemd, zap.Error(err))
|
||||
c.log.Error(logs.FailedToReportStatusToSystemd, zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package config_test
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -37,7 +38,8 @@ func TestConfigEnv(t *testing.T) {
|
|||
|
||||
envName := strings.ToUpper(
|
||||
strings.Join([]string{config.EnvPrefix, section, name}, configViper.EnvSeparator))
|
||||
t.Setenv(envName, value)
|
||||
err := os.Setenv(envName, value)
|
||||
require.NoError(t, err)
|
||||
|
||||
c := configtest.EmptyConfig()
|
||||
|
||||
|
|
|
@ -30,9 +30,6 @@ const (
|
|||
|
||||
// FrostfsIDCacheSizeDefault is a default value of APE chain cache.
|
||||
FrostfsIDCacheSizeDefault = 10_000
|
||||
|
||||
// ContainerCacheSizeDefault represents the default size for the container cache.
|
||||
ContainerCacheSizeDefault = 100
|
||||
)
|
||||
|
||||
var errNoMorphEndpoints = errors.New("no morph chain RPC endpoints, see `morph.rpc_endpoint` section")
|
||||
|
@ -106,18 +103,6 @@ func CacheTTL(c *config.Config) time.Duration {
|
|||
return CacheTTLDefault
|
||||
}
|
||||
|
||||
// ContainerCacheSize returns the value of "container_cache_size" config parameter
|
||||
// from "morph" section.
|
||||
//
|
||||
// Returns 0 if the value is not positive integer.
|
||||
// Returns ContainerCacheSizeDefault if the value is missing.
|
||||
func ContainerCacheSize(c *config.Config) uint32 {
|
||||
if c.Sub(subsection).Value("container_cache_size") == nil {
|
||||
return ContainerCacheSizeDefault
|
||||
}
|
||||
return config.Uint32Safe(c.Sub(subsection), "container_cache_size")
|
||||
}
|
||||
|
||||
// SwitchInterval returns the value of "switch_interval" config parameter
|
||||
// from "morph" section.
|
||||
//
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
package multinet
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
||||
)
|
||||
|
||||
const (
|
||||
subsection = "multinet"
|
||||
|
||||
FallbackDelayDefault = 300 * time.Millisecond
|
||||
)
|
||||
|
||||
// Enabled returns the value of "enabled" config parameter from "multinet" section.
|
||||
func Enabled(c *config.Config) bool {
|
||||
return config.BoolSafe(c.Sub(subsection), "enabled")
|
||||
}
|
||||
|
||||
type Subnet struct {
|
||||
Mask string
|
||||
SourceIPs []string
|
||||
}
|
||||
|
||||
// Subnets returns the value of "subnets" config parameter from "multinet" section.
|
||||
func Subnets(c *config.Config) []Subnet {
|
||||
var result []Subnet
|
||||
sub := c.Sub(subsection).Sub("subnets")
|
||||
for i := 0; ; i++ {
|
||||
s := sub.Sub(strconv.FormatInt(int64(i), 10))
|
||||
mask := config.StringSafe(s, "mask")
|
||||
if mask == "" {
|
||||
break
|
||||
}
|
||||
sourceIPs := config.StringSliceSafe(s, "source_ips")
|
||||
result = append(result, Subnet{
|
||||
Mask: mask,
|
||||
SourceIPs: sourceIPs,
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Balancer returns the value of "balancer" config parameter from "multinet" section.
|
||||
func Balancer(c *config.Config) string {
|
||||
return config.StringSafe(c.Sub(subsection), "balancer")
|
||||
}
|
||||
|
||||
// Restrict returns the value of "restrict" config parameter from "multinet" section.
|
||||
func Restrict(c *config.Config) bool {
|
||||
return config.BoolSafe(c.Sub(subsection), "restrict")
|
||||
}
|
||||
|
||||
// FallbackDelay returns the value of "fallback_delay" config parameter from "multinet" section.
|
||||
func FallbackDelay(c *config.Config) time.Duration {
|
||||
fd := config.DurationSafe(c.Sub(subsection), "fallback_delay")
|
||||
if fd != 0 { // negative value means no fallback
|
||||
return fd
|
||||
}
|
||||
return FallbackDelayDefault
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package multinet
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
|
||||
configtest "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/test"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMultinetSection(t *testing.T) {
|
||||
t.Run("defaults", func(t *testing.T) {
|
||||
empty := configtest.EmptyConfig()
|
||||
require.Equal(t, false, Enabled(empty))
|
||||
require.Equal(t, ([]Subnet)(nil), Subnets(empty))
|
||||
require.Equal(t, "", Balancer(empty))
|
||||
require.Equal(t, false, Restrict(empty))
|
||||
require.Equal(t, FallbackDelayDefault, FallbackDelay(empty))
|
||||
})
|
||||
|
||||
const path = "../../../../config/example/node"
|
||||
|
||||
fileConfigTest := func(c *config.Config) {
|
||||
require.Equal(t, true, Enabled(c))
|
||||
require.Equal(t, []Subnet{
|
||||
{
|
||||
Mask: "192.168.219.174/24",
|
||||
SourceIPs: []string{
|
||||
"192.168.218.185",
|
||||
"192.168.219.185",
|
||||
},
|
||||
},
|
||||
{
|
||||
Mask: "10.78.70.74/24",
|
||||
SourceIPs: []string{
|
||||
"10.78.70.185",
|
||||
"10.78.71.185",
|
||||
},
|
||||
},
|
||||
}, Subnets(c))
|
||||
require.Equal(t, "roundrobin", Balancer(c))
|
||||
require.Equal(t, false, Restrict(c))
|
||||
require.Equal(t, 350*time.Millisecond, FallbackDelay(c))
|
||||
}
|
||||
|
||||
configtest.ForEachFileType(path, fileConfigTest)
|
||||
|
||||
t.Run("ENV", func(t *testing.T) {
|
||||
configtest.ForEnvFileType(t, path, fileConfigTest)
|
||||
})
|
||||
}
|
|
@ -10,17 +10,10 @@ type PutConfig struct {
|
|||
cfg *config.Config
|
||||
}
|
||||
|
||||
// GetConfig is a wrapper over "get" config section which provides access
|
||||
// to object get pipeline configuration of object service.
|
||||
type GetConfig struct {
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
const (
|
||||
subsection = "object"
|
||||
|
||||
putSubsection = "put"
|
||||
getSubsection = "get"
|
||||
|
||||
// PutPoolSizeDefault is a default value of routine pool size to
|
||||
// process object.Put requests in object service.
|
||||
|
@ -63,16 +56,3 @@ func (g PutConfig) PoolSizeLocal() int {
|
|||
func (g PutConfig) SkipSessionTokenIssuerVerification() bool {
|
||||
return config.BoolSafe(g.cfg, "skip_session_token_issuer_verification")
|
||||
}
|
||||
|
||||
// Get returns structure that provides access to "get" subsection of
|
||||
// "object" section.
|
||||
func Get(c *config.Config) GetConfig {
|
||||
return GetConfig{
|
||||
c.Sub(subsection).Sub(getSubsection),
|
||||
}
|
||||
}
|
||||
|
||||
// Priority returns the value of "priority" config parameter.
|
||||
func (g GetConfig) Priority() []string {
|
||||
return config.StringSliceSafe(g.cfg, "priority")
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ func Address(c *config.Config) string {
|
|||
return AddressDefault
|
||||
}
|
||||
|
||||
// BlockRate returns the value of "block_rate" config parameter
|
||||
// BlockRates returns the value of "block_rate" config parameter
|
||||
// from "pprof" section.
|
||||
func BlockRate(c *config.Config) int {
|
||||
s := c.Sub(subsection)
|
||||
|
|
|
@ -11,6 +11,8 @@ import (
|
|||
)
|
||||
|
||||
func fromFile(path string) *config.Config {
|
||||
os.Clearenv() // ENVs have priority over config files, so we do this in tests
|
||||
|
||||
return config.New(path, "", "")
|
||||
}
|
||||
|
||||
|
@ -38,6 +40,15 @@ func ForEachFileType(pref string, f func(*config.Config)) {
|
|||
|
||||
// ForEnvFileType creates config from `<pref>.env` file.
|
||||
func ForEnvFileType(t testing.TB, pref string, f func(*config.Config)) {
|
||||
envs := os.Environ()
|
||||
t.Cleanup(func() {
|
||||
os.Clearenv()
|
||||
for _, env := range envs {
|
||||
keyValue := strings.Split(env, "=")
|
||||
os.Setenv(keyValue[0], keyValue[1])
|
||||
}
|
||||
})
|
||||
|
||||
f(fromEnvFile(t, pref+".env"))
|
||||
}
|
||||
|
||||
|
@ -62,6 +73,7 @@ func loadEnv(t testing.TB, path string) {
|
|||
|
||||
v = strings.Trim(v, `"`)
|
||||
|
||||
t.Setenv(k, v)
|
||||
err = os.Setenv(k, v)
|
||||
require.NoError(t, err, "can't set environment variable")
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue