Compare commits

..

No commits in common. "master" and "master" have entirely different histories.

660 changed files with 7499 additions and 9212 deletions

View file

@ -1,4 +1,4 @@
FROM golang:1.23 AS builder FROM golang:1.22 AS builder
ARG BUILD=now ARG BUILD=now
ARG VERSION=dev ARG VERSION=dev
ARG REPO=repository ARG REPO=repository

View file

@ -1,4 +1,4 @@
FROM golang:1.23 FROM golang:1.22
WORKDIR /tmp WORKDIR /tmp

View file

@ -1,4 +1,4 @@
FROM golang:1.23 AS builder FROM golang:1.22 AS builder
ARG BUILD=now ARG BUILD=now
ARG VERSION=dev ARG VERSION=dev
ARG REPO=repository ARG REPO=repository

View file

@ -1,4 +1,4 @@
FROM golang:1.23 AS builder FROM golang:1.22 AS builder
ARG BUILD=now ARG BUILD=now
ARG VERSION=dev ARG VERSION=dev
ARG REPO=repository ARG REPO=repository

View file

@ -1,4 +1,4 @@
FROM golang:1.23 AS builder FROM golang:1.22 AS builder
ARG BUILD=now ARG BUILD=now
ARG VERSION=dev ARG VERSION=dev
ARG REPO=repository ARG REPO=repository

View file

@ -106,6 +106,4 @@ jobs:
run: make fumpt-install run: make fumpt-install
- name: Run gofumpt - name: Run gofumpt
run: | run: make fumpt
make fumpt
git diff --exit-code --quiet

View file

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View file

@ -38,10 +38,6 @@ linters-settings:
alias: alias:
pkg: git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object pkg: git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object
alias: objectSDK alias: objectSDK
unused:
field-writes-are-uses: false
exported-fields-are-used: false
local-variables-are-used: false
custom: custom:
truecloudlab-linters: truecloudlab-linters:
path: bin/linters/external_linters.so path: bin/linters/external_linters.so
@ -87,7 +83,5 @@ linters:
- perfsprint - perfsprint
- testifylint - testifylint
- protogetter - protogetter
- intrange
- tenv
disable-all: true disable-all: true
fast: false fast: false

View 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

View file

@ -4,14 +4,14 @@ SHELL = bash
REPO ?= $(shell go list -m) REPO ?= $(shell go list -m)
VERSION ?= $(shell git describe --tags --dirty --match "v*" --always --abbrev=8 2>/dev/null || cat VERSION 2>/dev/null || echo "develop") VERSION ?= $(shell git describe --tags --dirty --match "v*" --always --abbrev=8 2>/dev/null || cat VERSION 2>/dev/null || echo "develop")
HUB_IMAGE ?= git.frostfs.info/truecloudlab/frostfs HUB_IMAGE ?= truecloudlab/frostfs
HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')" HUB_TAG ?= "$(shell echo ${VERSION} | sed 's/^v//')"
GO_VERSION ?= 1.22 GO_VERSION ?= 1.22
LINT_VERSION ?= 1.62.0 LINT_VERSION ?= 1.60.3
TRUECLOUDLAB_LINT_VERSION ?= 0.0.8 TRUECLOUDLAB_LINT_VERSION ?= 0.0.7
PROTOC_VERSION ?= 25.0 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 PROTOC_OS_VERSION=osx-x86_64
ifeq ($(shell uname), Linux) ifeq ($(shell uname), Linux)
PROTOC_OS_VERSION=linux-x86_64 PROTOC_OS_VERSION=linux-x86_64
@ -27,6 +27,12 @@ DIRS = $(BIN) $(RELEASE)
CMDS = $(notdir $(basename $(wildcard cmd/frostfs-*))) CMDS = $(notdir $(basename $(wildcard cmd/frostfs-*)))
BINS = $(addprefix $(BIN)/, $(CMDS)) 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 OUTPUT_LINT_DIR ?= $(abspath $(BIN))/linters
LINT_DIR = $(OUTPUT_LINT_DIR)/golangci-lint-$(LINT_VERSION)-v$(TRUECLOUDLAB_LINT_VERSION) LINT_DIR = $(OUTPUT_LINT_DIR)/golangci-lint-$(LINT_VERSION)-v$(TRUECLOUDLAB_LINT_VERSION)
TMP_DIR := .cache TMP_DIR := .cache
@ -52,7 +58,7 @@ LOCODE_DB_PATH=$(abspath ./.cache/locode_db)
LOCODE_DB_VERSION=v0.4.0 LOCODE_DB_VERSION=v0.4.0
.PHONY: help all images dep clean fmts fumpt imports test lint docker/lint .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 # 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 # 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) @unzip -q -o $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip -d $(PROTOC_DIR)
@rm $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip @rm $(PROTOBUF_DIR)/protoc-$(PROTOC_VERSION).zip
@echo "⇒ Instaling protogen FrostFS plugin..." @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 # Build FrostFS component's docker image
image-%: image-%:
@ -257,6 +263,19 @@ clean:
rm -rf $(BIN) rm -rf $(BIN)
rm -rf $(RELEASE) 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 # Download locode database
locode-download: locode-download:
mkdir -p $(TMP_DIR) mkdir -p $(TMP_DIR)
@ -282,6 +301,7 @@ env-up: all
# Shutdown dev environment # Shutdown dev environment
env-down: 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)/state
rm -rf ./$(TMP_DIR)/storage rm -rf ./$(TMP_DIR)/storage

View file

@ -1,5 +1,5 @@
<p align="center"> <p align="center">
<img src="./.forgejo/logo.svg" width="500px" alt="FrostFS"> <img src="./.github/logo.svg" width="500px" alt="FrostFS">
</p> </p>
<p align="center"> <p align="center">
@ -7,8 +7,9 @@
</p> </p>
--- ---
[![Report](https://goreportcard.com/badge/git.frostfs.info/TrueCloudLab/frostfs-node)](https://goreportcard.com/report/git.frostfs.info/TrueCloudLab/frostfs-node) [![Report](https://goreportcard.com/badge/github.com/TrueCloudLab/frostfs-node)](https://goreportcard.com/report/github.com/TrueCloudLab/frostfs-node)
![Release (latest)](https://git.frostfs.info/TrueCloudLab/frostfs-node/badges/release.svg) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/TrueCloudLab/frostfs-node?sort=semver)
![License](https://img.shields.io/github/license/TrueCloudLab/frostfs-node.svg?style=popout)
# Overview # Overview
@ -32,8 +33,8 @@ manipulate large amounts of data without paying a prohibitive price.
FrostFS has a native [gRPC API](https://git.frostfs.info/TrueCloudLab/frostfs-api) and has FrostFS has a native [gRPC API](https://git.frostfs.info/TrueCloudLab/frostfs-api) and has
protocol gateways for popular protocols such as [AWS protocol gateways for popular protocols such as [AWS
S3](https://git.frostfs.info/TrueCloudLab/frostfs-s3-gw), S3](https://github.com/TrueCloudLab/frostfs-s3-gw),
[HTTP](https://git.frostfs.info/TrueCloudLab/frostfs-http-gw), [HTTP](https://github.com/TrueCloudLab/frostfs-http-gw),
[FUSE](https://wikipedia.org/wiki/Filesystem_in_Userspace) and [FUSE](https://wikipedia.org/wiki/Filesystem_in_Userspace) and
[sFTP](https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol) allowing [sFTP](https://en.wikipedia.org/wiki/SSH_File_Transfer_Protocol) allowing
developers to integrate applications without rewriting their code. developers to integrate applications without rewriting their code.
@ -44,7 +45,7 @@ Now, we only support GNU/Linux on amd64 CPUs with AVX/AVX2 instructions. More
platforms will be officially supported after release `1.0`. platforms will be officially supported after release `1.0`.
The latest version of frostfs-node works with frostfs-contract The latest version of frostfs-node works with frostfs-contract
[v0.19.2](https://git.frostfs.info/TrueCloudLab/frostfs-contract/releases/tag/v0.19.2). [v0.16.0](https://github.com/TrueCloudLab/frostfs-contract/releases/tag/v0.16.0).
# Building # Building
@ -70,7 +71,7 @@ make docker/bin/frostfs-<name> # build a specific binary
## Docker images ## Docker images
To make docker images suitable for use in [frostfs-dev-env](https://git.frostfs.info/TrueCloudLab/frostfs-dev-env/) use: To make docker images suitable for use in [frostfs-dev-env](https://github.com/TrueCloudLab/frostfs-dev-env/) use:
``` ```
make images make images
``` ```
@ -98,7 +99,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): 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 Enter password > <- press ENTER, the is no password for wallet
CID: CfPhEuHQ2PRvM4gfBQDC4dWZY3NccovyfcnEdiq2ixju CID: CfPhEuHQ2PRvM4gfBQDC4dWZY3NccovyfcnEdiq2ixju
@ -124,7 +125,7 @@ the feature/topic you are going to implement.
# Credits # Credits
FrostFS is maintained by [True Cloud Lab](https://git.frostfs.info/TrueCloudLab/) with the help and FrostFS is maintained by [True Cloud Lab](https://github.com/TrueCloudLab/) with the help and
contributions from community members. contributions from community members.
Please see [CREDITS](CREDITS.md) for details. Please see [CREDITS](CREDITS.md) for details.

View file

@ -9,8 +9,8 @@ related configuration details.
To follow this guide you need: To follow this guide you need:
- latest released version of [neo-go](https://github.com/nspcc-dev/neo-go/releases) (v0.97.2 at the moment), - latest released version of [neo-go](https://github.com/nspcc-dev/neo-go/releases) (v0.97.2 at the moment),
- latest released version of [frostfs-adm](https://git.frostfs.info/TrueCloudLab/frostfs-node/releases) utility (v0.42.9 at the moment), - latest released version of [frostfs-adm](https://github.com/TrueCloudLab/frostfs-node/releases) utility (v0.25.1 at the moment),
- latest released version of compiled [frostfs-contract](https://git.frostfs.info/TrueCloudLab/frostfs-contract/releases) (v0.19.2 at the moment). - latest released version of compiled [frostfs-contract](https://github.com/TrueCloudLab/frostfs-contract/releases) (v0.11.0 at the moment).
## Step 1: Prepare network configuration ## Step 1: Prepare network configuration

View file

@ -128,7 +128,7 @@ func generateConfigExample(appDir string, credSize int) (string, error) {
tmpl.AlphabetDir = filepath.Join(appDir, "alphabet-wallets") tmpl.AlphabetDir = filepath.Join(appDir, "alphabet-wallets")
var i innerring.GlagoliticLetter 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()) tmpl.Glagolitics = append(tmpl.Glagolitics, i.String())
} }

View file

@ -1,34 +1,26 @@
package metabase package metabase
import ( import (
"context"
"errors" "errors"
"fmt" "fmt"
"sync"
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
engineconfig "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine" 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" 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" 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" "github.com/spf13/cobra"
"golang.org/x/sync/errgroup"
) )
const ( const (
pathFlag = "path"
noCompactFlag = "no-compact" noCompactFlag = "no-compact"
) )
var ( var errNoPathsFound = errors.New("no metabase paths found")
errNoPathsFound = errors.New("no metabase paths found")
errNoMorphEndpointsFound = errors.New("no morph endpoints found") var path string
)
var UpgradeCmd = &cobra.Command{ var UpgradeCmd = &cobra.Command{
Use: "upgrade", Use: "upgrade",
@ -45,10 +37,17 @@ func upgrade(cmd *cobra.Command, _ []string) error {
if err != nil { if err != nil {
return err return err
} }
noCompact, _ := cmd.Flags().GetBool(noCompactFlag)
var paths []string
if path != "" {
paths = append(paths, path)
}
appCfg := config.New(configFile, configDir, config.EnvPrefix) appCfg := config.New(configFile, configDir, config.EnvPrefix)
paths, err := getMetabasePaths(appCfg) if err := engineconfig.IterateShards(appCfg, false, func(sc *shardconfig.Config) error {
if err != nil { paths = append(paths, sc.Metabase().Path())
return err return nil
}); err != nil {
return fmt.Errorf("failed to get metabase paths: %w", err)
} }
if len(paths) == 0 { if len(paths) == 0 {
return errNoPathsFound return errNoPathsFound
@ -57,39 +56,18 @@ func upgrade(cmd *cobra.Command, _ []string) error {
for i, path := range paths { for i, path := range paths {
cmd.Println(i+1, ":", path) 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) result := make(map[string]bool)
var resultGuard sync.Mutex
eg, ctx := errgroup.WithContext(cmd.Context())
for _, path := range paths { for _, path := range paths {
eg.Go(func() error { cmd.Println("upgrading metabase", path, "...")
var success bool if err := meta.Upgrade(cmd.Context(), path, !noCompact, func(a ...any) {
cmd.Println("upgrading metabase", path, "...") cmd.Println(append([]any{time.Now().Format(time.RFC3339), ":", path, ":"}, a...)...)
if err := meta.Upgrade(ctx, path, !noCompact, civ, func(a ...any) { }); err != nil {
cmd.Println(append([]any{time.Now().Format(time.RFC3339), ":", path, ":"}, a...)...) result[path] = false
}); err != nil { cmd.Println("error: failed to upgrade metabase", path, ":", err)
cmd.Println("error: failed to upgrade metabase", path, ":", err) } else {
} else { result[path] = true
success = true cmd.Println("metabase", path, "upgraded successfully")
cmd.Println("metabase", path, "upgraded successfully") }
}
resultGuard.Lock()
result[path] = success
resultGuard.Unlock()
return nil
})
}
if err := eg.Wait(); err != nil {
return err
} }
for mb, ok := range result { for mb, ok := range result {
if ok { if ok {
@ -101,50 +79,8 @@ func upgrade(cmd *cobra.Command, _ []string) error {
return nil 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() { func initUpgradeCommand() {
flags := UpgradeCmd.Flags() flags := UpgradeCmd.Flags()
flags.StringVar(&path, pathFlag, "", "Path to metabase file")
flags.Bool(noCompactFlag, false, "Do not compact upgraded metabase file") flags.Bool(noCompactFlag, false, "Do not compact upgraded metabase file")
} }

View file

@ -139,7 +139,7 @@ func newPolicyContractInterface(cmd *cobra.Command) (*morph.ContractStorage, *he
c, err := helper.GetN3Client(viper.GetViper()) c, err := helper.GetN3Client(viper.GetViper())
commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err) 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) commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)
var ch util.Uint160 var ch util.Uint160

View file

@ -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) { func dumpSingleContainer(bw *io.BufBinWriter, ch util.Uint160, inv *invoker.Invoker, id []byte) (*Container, error) {
bw.Reset() bw.Reset()
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id) emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id)
emit.AppCall(bw.BinWriter, ch, "eACL", callflag.All, id)
res, err := inv.Run(bw.Bytes()) res, err := inv.Run(bw.Bytes())
if err != nil { if err != nil {
return nil, fmt.Errorf("can't get container info: %w", err) return nil, fmt.Errorf("can't get container info: %w", err)
} }
if len(res.Stack) != 1 { if len(res.Stack) != 2 {
return nil, fmt.Errorf("%w: expected 1 items on stack", errInvalidContainerResponse) return nil, fmt.Errorf("%w: expected 2 items on stack", errInvalidContainerResponse)
} }
cnt := new(Container) 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) 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 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) { func putContainer(bw *io.BufBinWriter, ch util.Uint160, cnt Container) {
emit.AppCall(bw.BinWriter, ch, "put", callflag.All, emit.AppCall(bw.BinWriter, ch, "put", callflag.All,
cnt.Value, cnt.Signature, cnt.PublicKey, cnt.Token) 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) { 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"` Signature []byte `json:"signature"`
PublicKey []byte `json:"public_key"` PublicKey []byte `json:"public_key"`
Token []byte `json:"token"` 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. // ToStackItem implements stackitem.Convertible.
@ -355,6 +377,50 @@ func (c *Container) FromStackItem(item stackitem.Item) error {
return nil 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. // getCIDFilterFunc returns filtering function for container IDs.
// Raw byte slices are used because it works with structures returned // Raw byte slices are used because it works with structures returned
// from contract. // from contract.

View file

@ -63,7 +63,7 @@ func TestGenerateAlphabet(t *testing.T) {
buf.Reset() buf.Reset()
v.Set(commonflags.AlphabetWalletsFlag, walletDir) v.Set(commonflags.AlphabetWalletsFlag, walletDir)
require.NoError(t, GenerateAlphabetCmd.Flags().Set(commonflags.AlphabetSizeFlag, strconv.FormatUint(size, 10))) 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") buf.WriteString(strconv.FormatUint(i, 10) + "\r")
} }

View file

@ -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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "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" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/core/state" "github.com/nspcc-dev/neo-go/pkg/core/state"
@ -30,11 +31,7 @@ type LocalActor struct {
// NewLocalActor create LocalActor with accounts form provided wallets. // NewLocalActor create LocalActor with accounts form provided wallets.
// In case of empty wallets provided created actor with dummy account only for read operation. // In case of empty wallets provided created actor with dummy account only for read operation.
// func NewLocalActor(cmd *cobra.Command, c actor.RPCActor) (*LocalActor, error) {
// 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) {
walletDir := config.ResolveHomePath(viper.GetString(commonflags.AlphabetWalletsFlag)) walletDir := config.ResolveHomePath(viper.GetString(commonflags.AlphabetWalletsFlag))
var act *actor.Actor var act *actor.Actor
var accounts []*wallet.Account 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) commonCmd.ExitOnErr(cmd, "unable to get alphabet wallets: %w", err)
for _, w := range wallets { for _, w := range wallets {
acc, err := GetWalletAccount(w, accName) acc, err := GetWalletAccount(w, constants.CommitteeAccountName)
commonCmd.ExitOnErr(cmd, fmt.Sprintf("can't find %s account: %%w", accName), err) commonCmd.ExitOnErr(cmd, "can't find committee account: %w", err)
accounts = append(accounts, acc) accounts = append(accounts, acc)
} }
act, err = actor.New(c, []actor.SignerAccount{{ act, err = actor.New(c, []actor.SignerAccount{{

View file

@ -166,6 +166,5 @@ func DeployNNS(c *InitializeContext, method string) error {
return fmt.Errorf("can't send deploy transaction: %w", err) return fmt.Errorf("can't send deploy transaction: %w", err)
} }
c.Command.Println("NNS hash:", invokeHash.StringLE())
return c.AwaitTx() return c.AwaitTx()
} }

View file

@ -72,17 +72,13 @@ func InvalidConfigValueErr(key string) error {
return fmt.Errorf("invalid %s config value from netmap contract", key) return fmt.Errorf("invalid %s config value from netmap contract", key)
} }
func EmitNewEpochCall(bw *io.BufBinWriter, wCtx *InitializeContext, nmHash util.Uint160, countEpoch int64) error { func EmitNewEpochCall(bw *io.BufBinWriter, wCtx *InitializeContext, nmHash util.Uint160) error {
if countEpoch <= 0 {
return errors.New("number of epochs cannot be less than 1")
}
curr, err := unwrap.Int64(wCtx.ReadOnlyInvoker.Call(nmHash, "epoch")) curr, err := unwrap.Int64(wCtx.ReadOnlyInvoker.Call(nmHash, "epoch"))
if err != nil { if err != nil {
return errors.New("can't fetch current epoch from the netmap contract") return errors.New("can't fetch current epoch from the netmap contract")
} }
newEpoch := curr + countEpoch newEpoch := curr + 1
wCtx.Command.Printf("Current epoch: %d, increase to %d.\n", curr, newEpoch) wCtx.Command.Printf("Current epoch: %d, increase to %d.\n", curr, newEpoch)
// In NeoFS this is done via Notary contract. Here, however, we can form the // In NeoFS this is done via Notary contract. Here, however, we can form the

View file

@ -1,8 +1,6 @@
package initialize package initialize
import ( import (
"fmt"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles" "github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
@ -31,14 +29,10 @@ func setNotaryAndAlphabetNodes(c *helper.InitializeContext) error {
callflag.States|callflag.AllowNotify, int64(noderoles.NeoFSAlphabet), pubs) callflag.States|callflag.AllowNotify, int64(noderoles.NeoFSAlphabet), pubs)
if err := c.SendCommitteeTx(w.Bytes(), false); err != nil { if err := c.SendCommitteeTx(w.Bytes(), false); err != nil {
return fmt.Errorf("send committee transaction: %w", err) return err
} }
err := c.AwaitTx() return c.AwaitTx()
if err != nil {
err = fmt.Errorf("await committee transaction: %w", err)
}
return err
} }
func setRolesFinished(c *helper.InitializeContext) (bool, error) { func setRolesFinished(c *helper.InitializeContext) (bool, error) {

View file

@ -3,7 +3,6 @@ package initialize
import ( import (
"fmt" "fmt"
"math/big" "math/big"
"strings"
"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/constants"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
@ -27,12 +26,12 @@ const (
initialAlphabetGASAmount = 10_000 * native.GASFactor initialAlphabetGASAmount = 10_000 * native.GASFactor
// initialProxyGASAmount represents the amount of GAS given to a proxy contract. // initialProxyGASAmount represents the amount of GAS given to a proxy contract.
initialProxyGASAmount = 50_000 * native.GASFactor 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 { func transferFunds(c *helper.InitializeContext) error {
ok, err := transferFundsFinished(c) ok, err := transferFundsFinished(c)
if ok || err != nil { if ok || err != nil {
@ -59,7 +58,7 @@ func transferFunds(c *helper.InitializeContext) error {
transferTarget{ transferTarget{
Token: gas.Hash, Token: gas.Hash,
Address: c.CommitteeAcc.Contract.ScriptHash(), Address: c.CommitteeAcc.Contract.ScriptHash(),
Amount: initialCommitteeGASAmount(c), Amount: (gasInitialTotalSupply - initialAlphabetGASAmount*int64(len(c.Wallets))) / 2,
}, },
transferTarget{ transferTarget{
Token: neo.Hash, Token: neo.Hash,
@ -80,19 +79,12 @@ func transferFunds(c *helper.InitializeContext) error {
return c.AwaitTx() 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) { func transferFundsFinished(c *helper.InitializeContext) (bool, error) {
acc := c.Accounts[0] acc := c.Accounts[0]
r := nep17.NewReader(c.ReadOnlyInvoker, gas.Hash) r := nep17.NewReader(c.ReadOnlyInvoker, gas.Hash)
res, err := r.BalanceOf(acc.Contract.ScriptHash()) res, err := r.BalanceOf(acc.Contract.ScriptHash())
if err != nil || res.Cmp(big.NewInt(initialAlphabetGASAmount/2)) != 1 { return res.Cmp(big.NewInt(alphabetGasRatio*native.GASFactor)) == 1, err
return false, err
}
res, err = r.BalanceOf(c.CommitteeAcc.ScriptHash())
return res != nil && res.Cmp(big.NewInt(initialCommitteeGASAmount(c)/2)) == 1, err
} }
func transferGASToProxy(c *helper.InitializeContext) error { func transferGASToProxy(c *helper.InitializeContext) error {
@ -152,17 +144,5 @@ func createNEP17MultiTransferTx(c helper.Client, acc *wallet.Account, recipients
if err != nil { if err != nil {
return nil, fmt.Errorf("can't create actor: %w", err) return nil, fmt.Errorf("can't create actor: %w", err)
} }
tx, err := act.MakeRun(w.Bytes()) return act.MakeRun(w.Bytes())
if err != nil {
sum := make(map[util.Uint160]int64)
for _, recipient := range recipients {
sum[recipient.Token] += recipient.Amount
}
detail := make([]string, 0, len(sum))
for _, value := range sum {
detail = append(detail, fmt.Sprintf("amount=%v", value))
}
err = fmt.Errorf("transfer failed: from=%s(%s) %s: %w", acc.Label, acc.Address, strings.Join(detail, " "), err)
}
return tx, err
} }

View file

@ -12,8 +12,6 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
const deltaFlag = "delta"
func ForceNewEpochCmd(cmd *cobra.Command, _ []string) error { func ForceNewEpochCmd(cmd *cobra.Command, _ []string) error {
wCtx, err := helper.NewInitializeContext(cmd, viper.GetViper()) wCtx, err := helper.NewInitializeContext(cmd, viper.GetViper())
if err != nil { if err != nil {
@ -32,8 +30,7 @@ func ForceNewEpochCmd(cmd *cobra.Command, _ []string) error {
} }
bw := io.NewBufBinWriter() bw := io.NewBufBinWriter()
delta, _ := cmd.Flags().GetInt64(deltaFlag) if err := helper.EmitNewEpochCall(bw, wCtx, nmHash); err != nil {
if err := helper.EmitNewEpochCall(bw, wCtx, nmHash, delta); err != nil {
return err return err
} }

View file

@ -35,7 +35,6 @@ func initForceNewEpochCmd() {
ForceNewEpoch.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) ForceNewEpoch.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
ForceNewEpoch.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) ForceNewEpoch.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
ForceNewEpoch.Flags().String(commonflags.LocalDumpFlag, "", "Path to the blocks dump file") ForceNewEpoch.Flags().String(commonflags.LocalDumpFlag, "", "Path to the blocks dump file")
ForceNewEpoch.Flags().Int64(deltaFlag, 1, "Number of epochs to increase the current epoch")
} }
func init() { func init() {

View file

@ -2,7 +2,6 @@ package nns
import ( import (
client "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/nns" 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" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management" "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) c, err := helper.GetN3Client(v)
commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err) 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) commonCmd.ExitOnErr(cmd, "can't create actor: %w", err)
r := management.NewReader(ac.Invoker) r := management.NewReader(ac.Invoker)

View file

@ -47,19 +47,6 @@ func initDelRecordsCmd() {
_ = cobra.MarkFlagRequired(delRecordsCmd.Flags(), nnsRecordTypeFlag) _ = 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) { func addRecord(cmd *cobra.Command, _ []string) {
c, actor, _ := getRPCClient(cmd) c, actor, _ := getRPCClient(cmd)
name, _ := cmd.Flags().GetString(nnsNameFlag) name, _ := cmd.Flags().GetString(nnsNameFlag)
@ -128,22 +115,6 @@ func delRecords(cmd *cobra.Command, _ []string) {
cmd.Println("Records removed successfully") 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) { func getRecordType(recordType string) (*big.Int, error) {
switch strings.ToUpper(recordType) { switch strings.ToUpper(recordType) {
case "A": case "A":

View file

@ -42,23 +42,3 @@ func registerDomain(cmd *cobra.Command, _ []string) {
commonCmd.ExitOnErr(cmd, "register domain error: %w", err) commonCmd.ExitOnErr(cmd, "register domain error: %w", err)
cmd.Println("Domain registered successfully") cmd.Println("Domain registered successfully")
} }
func initDeleteCmd() {
Cmd.AddCommand(deleteCmd)
deleteCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
deleteCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
deleteCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc)
_ = cobra.MarkFlagRequired(deleteCmd.Flags(), nnsNameFlag)
}
func deleteDomain(cmd *cobra.Command, _ []string) {
c, actor, _ := getRPCClient(cmd)
name, _ := cmd.Flags().GetString(nnsNameFlag)
h, vub, err := c.DeleteDomain(name)
_, err = actor.Wait(h, vub, err)
commonCmd.ExitOnErr(cmd, "delete domain error: %w", err)
cmd.Println("Domain deleted successfully")
}

View file

@ -42,15 +42,6 @@ var (
}, },
Run: registerDomain, Run: registerDomain,
} }
deleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete a domain by name",
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: deleteDomain,
}
renewCmd = &cobra.Command{ renewCmd = &cobra.Command{
Use: "renew", Use: "renew",
Short: "Increases domain expiration date", Short: "Increases domain expiration date",
@ -95,25 +86,14 @@ var (
}, },
Run: delRecords, 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() { func init() {
initTokensCmd() initTokensCmd()
initRegisterCmd() initRegisterCmd()
initDeleteCmd()
initRenewCmd() initRenewCmd()
initUpdateCmd() initUpdateCmd()
initAddRecordCmd() initAddRecordCmd()
initGetRecordsCmd() initGetRecordsCmd()
initDelRecordsCmd() initDelRecordsCmd()
initDelRecordCmd()
} }

View file

@ -1,25 +1,15 @@
package nns package nns
import ( import (
"math/big"
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
client "git.frostfs.info/TrueCloudLab/frostfs-contract/rpcclient/nns"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const (
verboseDesc = "Include additional information about CNAME record."
)
func initTokensCmd() { func initTokensCmd() {
Cmd.AddCommand(tokensCmd) Cmd.AddCommand(tokensCmd)
tokensCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) tokensCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
tokensCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) tokensCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
tokensCmd.Flags().BoolP(commonflags.Verbose, commonflags.VerboseShorthand, false, verboseDesc)
} }
func listTokens(cmd *cobra.Command, _ []string) { func listTokens(cmd *cobra.Command, _ []string) {
@ -28,39 +18,7 @@ func listTokens(cmd *cobra.Command, _ []string) {
commonCmd.ExitOnErr(cmd, "unable to get tokens: %w", err) commonCmd.ExitOnErr(cmd, "unable to get tokens: %w", err)
for toks, err := it.Next(10); err == nil && len(toks) > 0; toks, err = it.Next(10) { for toks, err := it.Next(10); err == nil && len(toks) > 0; toks, err = it.Next(10) {
for _, token := range toks { for _, token := range toks {
output := string(token) cmd.Println(string(token))
if verbose, _ := cmd.Flags().GetBool(commonflags.Verbose); verbose {
cname, err := getCnameRecord(c, token)
commonCmd.ExitOnErr(cmd, "", err)
if cname != "" {
output += " (CNAME: " + cname + ")"
}
}
cmd.Println(output)
} }
} }
} }
func getCnameRecord(c *client.Contract, token []byte) (string, error) {
items, err := c.GetRecords(string(token), big.NewInt(int64(nns.CNAME)))
// GetRecords returns the error "not an array" if the domain does not contain records.
if err != nil && strings.Contains(err.Error(), "not an array") {
return "", nil
}
if err != nil {
return "", err
}
if len(items) == 0 {
return "", nil
}
record, err := items[0].TryBytes()
if err != nil {
return "", err
}
return string(record), nil
}

View file

@ -53,7 +53,7 @@ func RemoveNodesCmd(cmd *cobra.Command, args []string) error {
int64(netmapcontract.NodeStateOffline), nodeKeys[i].Bytes()) int64(netmapcontract.NodeStateOffline), nodeKeys[i].Bytes())
} }
if err := helper.EmitNewEpochCall(bw, wCtx, nmHash, 1); err != nil { if err := helper.EmitNewEpochCall(bw, wCtx, nmHash); err != nil {
return err return err
} }

View file

@ -30,13 +30,11 @@ var (
func initProxyAddAccount() { func initProxyAddAccount() {
AddAccountCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) AddAccountCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
AddAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string") AddAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string")
AddAccountCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
} }
func initProxyRemoveAccount() { func initProxyRemoveAccount() {
RemoveAccountCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) RemoveAccountCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
RemoveAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string") RemoveAccountCmd.Flags().String(accountAddressFlag, "", "Wallet address string")
RemoveAccountCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc)
} }
func init() { func init() {

View file

@ -72,3 +72,4 @@ All other `object` sub-commands support only static sessions (2).
List of commands supporting sessions (static only): List of commands supporting sessions (static only):
- `create` - `create`
- `delete` - `delete`
- `set-eacl`

View file

@ -565,6 +565,13 @@ type HeadObjectPrm struct {
commonObjectPrm commonObjectPrm
objectAddressPrm objectAddressPrm
rawPrm rawPrm
mainOnly bool
}
// SetMainOnlyFlag sets flag to get only main fields of an object header in terms of FrostFS API.
func (x *HeadObjectPrm) SetMainOnlyFlag(v bool) {
x.mainOnly = v
} }
// HeadObjectRes groups the resulting values of HeadObject operation. // HeadObjectRes groups the resulting values of HeadObject operation.
@ -659,7 +666,9 @@ func SearchObjects(ctx context.Context, prm SearchObjectsPrm) (*SearchObjectsRes
for { for {
n, ok = rdr.Read(buf) n, ok = rdr.Read(buf)
list = append(list, buf[:n]...) for i := range n {
list = append(list, buf[i])
}
if !ok { if !ok {
break break
} }
@ -670,8 +679,9 @@ func SearchObjects(ctx context.Context, prm SearchObjectsPrm) (*SearchObjectsRes
return nil, fmt.Errorf("read object list: %w", err) return nil, fmt.Errorf("read object list: %w", err)
} }
slices.SortFunc(list, func(a, b oid.ID) int { sort.Slice(list, func(i, j int) bool {
return strings.Compare(a.EncodeToString(), b.EncodeToString()) lhs, rhs := list[i].EncodeToString(), list[j].EncodeToString()
return strings.Compare(lhs, rhs) < 0
}) })
return &SearchObjectsRes{ return &SearchObjectsRes{

View file

@ -58,7 +58,6 @@ func GetSDKClient(ctx context.Context, cmd *cobra.Command, key *ecdsa.PrivateKey
GRPCDialOptions: []grpc.DialOption{ GRPCDialOptions: []grpc.DialOption{
grpc.WithChainUnaryInterceptor(tracing.NewUnaryClientInteceptor()), grpc.WithChainUnaryInterceptor(tracing.NewUnaryClientInteceptor()),
grpc.WithChainStreamInterceptor(tracing.NewStreamClientInterceptor()), grpc.WithChainStreamInterceptor(tracing.NewStreamClientInterceptor()),
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
}, },
} }
if timeout := viper.GetDuration(commonflags.Timeout); timeout > 0 { if timeout := viper.GetDuration(commonflags.Timeout); timeout > 0 {

View file

@ -2,7 +2,7 @@ package common
import ( import (
"context" "context"
"slices" "sort"
"strings" "strings"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "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) commonCmd.ExitOnErr(cmd, "init tracing: %w", err)
var components []string var components sort.StringSlice
for c := cmd; c != nil; c = c.Parent() { for c := cmd; c != nil; c = c.Parent() {
components = append(components, c.Name()) 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, ".") operation := strings.Join(components, ".")
ctx, span := tracing.StartSpanFromContext(cmd.Context(), operation) ctx, span := tracing.StartSpanFromContext(cmd.Context(), operation)

View file

@ -31,10 +31,11 @@ const (
) )
const ( const (
namespaceTarget = "namespace" defaultNamespace = ""
containerTarget = "container" namespaceTarget = "namespace"
userTarget = "user" containerTarget = "container"
groupTarget = "group" userTarget = "user"
groupTarget = "group"
) )
var errUnknownTargetType = errors.New("unknown target type") var errUnknownTargetType = errors.New("unknown target type")

View file

@ -7,20 +7,22 @@ import (
"strings" "strings"
"time" "time"
containerApi "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" 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/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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/client"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container" "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/netmap"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
var ( var (
containerACL string
containerPolicy string containerPolicy string
containerAttributes []string containerAttributes []string
containerAwait bool containerAwait bool
@ -87,6 +89,9 @@ It will be stored in sidechain when inner ring will accepts it.`,
err = parseAttributes(&cnr, containerAttributes) err = parseAttributes(&cnr, containerAttributes)
commonCmd.ExitOnErr(cmd, "", err) commonCmd.ExitOnErr(cmd, "", err)
var basicACL acl.Basic
commonCmd.ExitOnErr(cmd, "decode basic ACL string: %w", basicACL.DecodeString(containerACL))
tok := getSession(cmd) tok := getSession(cmd)
if tok != nil { if tok != nil {
@ -100,6 +105,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
} }
cnr.SetPlacementPolicy(*placementPolicy) cnr.SetPlacementPolicy(*placementPolicy)
cnr.SetBasicACL(basicACL)
var syncContainerPrm internalclient.SyncContainerPrm var syncContainerPrm internalclient.SyncContainerPrm
syncContainerPrm.SetClient(cli) syncContainerPrm.SetClient(cli)
@ -157,6 +163,10 @@ func initContainerCreateCmd() {
flags.DurationP(commonflags.Timeout, commonflags.TimeoutShorthand, commonflags.TimeoutDefault, commonflags.TimeoutUsage) flags.DurationP(commonflags.Timeout, commonflags.TimeoutShorthand, commonflags.TimeoutDefault, commonflags.TimeoutUsage)
flags.StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, commonflags.WalletPathDefault, commonflags.WalletPathUsage) flags.StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, commonflags.WalletPathDefault, commonflags.WalletPathUsage)
flags.StringP(commonflags.Account, commonflags.AccountShorthand, commonflags.AccountDefault, commonflags.AccountUsage) 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.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.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") flags.BoolVar(&containerAwait, "await", false, "Block execution until container is persisted")

View file

@ -1,6 +1,9 @@
package container package container
import ( import (
"strings"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/container"
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" 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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
@ -81,8 +84,12 @@ var listContainersCmd = &cobra.Command{
cmd.Println(cnrID.String()) cmd.Println(cnrID.String())
if flagVarListPrintAttr { if flagVarListPrintAttr {
cnr.IterateUserAttributes(func(key, val string) { cnr.IterateAttributes(func(key, val string) {
cmd.Printf(" %s: %s\n", key, val) if !strings.HasPrefix(key, container.SysAttributePrefix) && !strings.HasPrefix(key, container.SysAttributePrefixNeoFS) {
// FIXME(@cthulhu-rider): https://git.frostfs.info/TrueCloudLab/frostfs-sdk-go/issues/97
// Use dedicated method to skip system attributes.
cmd.Printf(" %s: %s\n", key, val)
}
}) })
} }
} }

View file

@ -1,6 +1,9 @@
package container package container
import ( import (
"strings"
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" 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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
@ -64,8 +67,14 @@ var listContainerObjectsCmd = &cobra.Command{
resHead, err := internalclient.HeadObject(cmd.Context(), prmHead) resHead, err := internalclient.HeadObject(cmd.Context(), prmHead)
if err == nil { if err == nil {
for _, attr := range resHead.Header().UserAttributes() { attrs := resHead.Header().Attributes()
cmd.Printf(" %s: %s\n", attr.Key(), attr.Value()) for i := range attrs {
attrKey := attrs[i].Key()
if !strings.HasPrefix(attrKey, v2object.SysAttributePrefix) && !strings.HasPrefix(attrKey, v2object.SysAttributePrefixNeoFS) {
// FIXME(@cthulhu-rider): https://git.frostfs.info/TrueCloudLab/frostfs-sdk-go/issues/97
// Use dedicated method to skip system attributes.
cmd.Printf(" %s: %s\n", attrKey, attrs[i].Value())
}
} }
} else { } else {
cmd.Printf(" failed to read attributes: %v\n", err) cmd.Printf(" failed to read attributes: %v\n", err)

View file

@ -1,10 +1,11 @@
package container package container
import ( import (
"bufio"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io"
"os" "os"
"strings" "strings"
@ -13,7 +14,6 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"github.com/chzyer/readline"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -163,16 +163,6 @@ func (repl *policyPlaygroundREPL) netMap() netmap.NetMap {
return nm 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 { func (repl *policyPlaygroundREPL) run() error {
if len(viper.GetString(commonflags.RPC)) > 0 { if len(viper.GetString(commonflags.RPC)) > 0 {
key := key.GetOrGenerate(repl.cmd) key := key.GetOrGenerate(repl.cmd)
@ -199,38 +189,22 @@ func (repl *policyPlaygroundREPL) run() error {
"rm": repl.handleRemove, "rm": repl.handleRemove,
"eval": repl.handleEval, "eval": repl.handleEval,
} }
for reader := bufio.NewReader(os.Stdin); ; {
rl, err := readline.NewEx(&readline.Config{ fmt.Print("> ")
Prompt: "> ", line, err := reader.ReadString('\n')
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()
if err != nil { if err != nil {
if errors.Is(err, readline.ErrInterrupt) { if err == io.EOF {
if exit { return nil
return nil
}
exit = true
continue
} }
return fmt.Errorf("reading line: %w", err) return fmt.Errorf("reading line: %v", err)
} }
exit = false
parts := strings.Fields(line) parts := strings.Fields(line)
if len(parts) == 0 { if len(parts) == 0 {
continue continue
} }
cmd := parts[0] cmd := parts[0]
if handler, exists := cmdHandlers[cmd]; exists { handler, exists := cmdHandlers[cmd]
if exists {
if err := handler(parts[1:]); err != nil { if err := handler(parts[1:]); err != nil {
fmt.Printf("error: %v\n", err) fmt.Printf("error: %v\n", err)
} }

View file

@ -4,11 +4,11 @@ import (
"encoding/hex" "encoding/hex"
"errors" "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/internal/key"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
rawclient "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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
rawclient "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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -7,11 +7,11 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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/local_object_storage/shard"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control" "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" clientSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -20,10 +20,6 @@ const (
awaitFlag = "await" awaitFlag = "await"
noProgressFlag = "no-progress" noProgressFlag = "no-progress"
scopeFlag = "scope" scopeFlag = "scope"
repOneOnlyFlag = "rep-one-only"
containerWorkerCountFlag = "container-worker-count"
objectWorkerCountFlag = "object-worker-count"
scopeAll = "all" scopeAll = "all"
scopeObjects = "objects" scopeObjects = "objects"
@ -68,18 +64,12 @@ func startEvacuateShard(cmd *cobra.Command, _ []string) {
pk := key.Get(cmd) pk := key.Get(cmd)
ignoreErrors, _ := cmd.Flags().GetBool(ignoreErrorsFlag) ignoreErrors, _ := cmd.Flags().GetBool(ignoreErrorsFlag)
containerWorkerCount, _ := cmd.Flags().GetUint32(containerWorkerCountFlag)
objectWorkerCount, _ := cmd.Flags().GetUint32(objectWorkerCountFlag)
repOneOnly, _ := cmd.Flags().GetBool(repOneOnlyFlag)
req := &control.StartShardEvacuationRequest{ req := &control.StartShardEvacuationRequest{
Body: &control.StartShardEvacuationRequest_Body{ Body: &control.StartShardEvacuationRequest_Body{
Shard_ID: getShardIDList(cmd), Shard_ID: getShardIDList(cmd),
IgnoreErrors: ignoreErrors, IgnoreErrors: ignoreErrors,
Scope: getEvacuationScope(cmd), Scope: getEvacuationScope(cmd),
ContainerWorkerCount: containerWorkerCount,
ObjectWorkerCount: objectWorkerCount,
RepOneOnly: repOneOnly,
}, },
} }
@ -381,9 +371,6 @@ func initControlStartEvacuationShardCmd() {
flags.String(scopeFlag, scopeAll, fmt.Sprintf("Evacuation scope; possible values: %s, %s, %s", scopeTrees, scopeObjects, scopeAll)) flags.String(scopeFlag, scopeAll, fmt.Sprintf("Evacuation scope; possible values: %s, %s, %s", scopeTrees, scopeObjects, scopeAll))
flags.Bool(awaitFlag, false, "Block execution until evacuation is completed") flags.Bool(awaitFlag, false, "Block execution until evacuation is completed")
flags.Bool(noProgressFlag, false, fmt.Sprintf("Print progress if %s provided", awaitFlag)) flags.Bool(noProgressFlag, false, fmt.Sprintf("Print progress if %s provided", awaitFlag))
flags.Uint32(containerWorkerCountFlag, 0, "Count of concurrent container evacuation workers")
flags.Uint32(objectWorkerCountFlag, 0, "Count of concurrent object evacuation workers")
flags.Bool(repOneOnlyFlag, false, "Evacuate objects only from containers with policy 'REP 1 ...'")
startEvacuationShardCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag) startEvacuationShardCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag)
} }

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -3,11 +3,11 @@ package control
import ( import (
"encoding/hex" "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/internal/key"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -3,11 +3,11 @@ package control
import ( import (
"os" "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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -3,12 +3,12 @@ package control
import ( import (
"os" "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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server" 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" "github.com/spf13/cobra"
) )

View file

@ -1,13 +1,13 @@
package control package control
import ( 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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server" 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" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
"github.com/spf13/cobra" "github.com/spf13/cobra"

View file

@ -4,11 +4,11 @@ import (
"encoding/hex" "encoding/hex"
"errors" "errors"
rawclient "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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server" 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" "github.com/spf13/cobra"
) )

View file

@ -1,11 +1,11 @@
package control package control
import ( import (
rawclient "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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" ircontrol "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir"
ircontrolsrv "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir/server" 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" "github.com/spf13/cobra"
) )

View file

@ -5,11 +5,11 @@ import (
"fmt" "fmt"
"strings" "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/internal/key"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/cli/input"

View file

@ -7,10 +7,10 @@ import (
"strconv" "strconv"
"text/tabwriter" "text/tabwriter"
"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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"

View file

@ -3,10 +3,10 @@ package control
import ( import (
"fmt" "fmt"
rawclient "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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/mr-tron/base58" "github.com/mr-tron/base58"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -4,10 +4,10 @@ import (
"encoding/hex" "encoding/hex"
"errors" "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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -6,12 +6,12 @@ import (
"fmt" "fmt"
"time" "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/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -7,11 +7,11 @@ import (
"sort" "sort"
"strings" "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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/mr-tron/base58" "github.com/mr-tron/base58"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -6,10 +6,10 @@ import (
"slices" "slices"
"strings" "strings"
rawclient "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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
rawclient "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/mr-tron/base58" "github.com/mr-tron/base58"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -4,12 +4,12 @@ import (
"crypto/sha256" "crypto/sha256"
"errors" "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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/server/ctrlmessage" "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" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -4,11 +4,11 @@ import (
"crypto/ecdsa" "crypto/ecdsa"
"errors" "errors"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" 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/commonflags"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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-node/pkg/services/control/server/ctrlmessage"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto" frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
"github.com/spf13/cobra" "github.com/spf13/cobra"

View file

@ -1,10 +1,10 @@
package control package control
import ( import (
"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/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
"github.com/mr-tron/base58" "github.com/mr-tron/base58"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )

View file

@ -49,14 +49,14 @@ func prettyPrintNodeInfo(cmd *cobra.Command, i netmap.NodeInfo) {
cmd.Println("key:", hex.EncodeToString(i.PublicKey())) cmd.Println("key:", hex.EncodeToString(i.PublicKey()))
var stateWord string var stateWord string
switch i.Status() { switch {
default: default:
stateWord = "<undefined>" stateWord = "<undefined>"
case netmap.Online: case i.IsOnline():
stateWord = "online" stateWord = "online"
case netmap.Offline: case i.IsOffline():
stateWord = "offline" stateWord = "offline"
case netmap.Maintenance: case i.IsMaintenance():
stateWord = "maintenance" stateWord = "maintenance"
} }

View file

@ -6,12 +6,12 @@ import (
"fmt" "fmt"
"os" "os"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" 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/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
@ -38,6 +38,7 @@ func initObjectHeadCmd() {
_ = objectHeadCmd.MarkFlagRequired(commonflags.OIDFlag) _ = objectHeadCmd.MarkFlagRequired(commonflags.OIDFlag)
flags.String(fileFlag, "", "File to write header to. Default: stdout.") flags.String(fileFlag, "", "File to write header to. Default: stdout.")
flags.Bool("main-only", false, "Return only main fields")
flags.Bool(commonflags.JSON, false, "Marshal output in JSON") flags.Bool(commonflags.JSON, false, "Marshal output in JSON")
flags.Bool("proto", false, "Marshal output in Protobuf") flags.Bool("proto", false, "Marshal output in Protobuf")
flags.Bool(rawFlag, false, rawFlagDesc) flags.Bool(rawFlag, false, rawFlagDesc)
@ -48,6 +49,7 @@ func getObjectHeader(cmd *cobra.Command, _ []string) {
var obj oid.ID var obj oid.ID
objAddr := readObjectAddress(cmd, &cnr, &obj) objAddr := readObjectAddress(cmd, &cnr, &obj)
mainOnly, _ := cmd.Flags().GetBool("main-only")
pk := key.GetOrGenerate(cmd) pk := key.GetOrGenerate(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC) cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
@ -60,6 +62,7 @@ func getObjectHeader(cmd *cobra.Command, _ []string) {
raw, _ := cmd.Flags().GetBool(rawFlag) raw, _ := cmd.Flags().GetBool(rawFlag)
prm.SetRawFlag(raw) prm.SetRawFlag(raw)
prm.SetAddress(objAddr) prm.SetAddress(objAddr)
prm.SetMainOnlyFlag(mainOnly)
res, err := internalclient.HeadObject(cmd.Context(), prm) res, err := internalclient.HeadObject(cmd.Context(), prm)
if err != nil { if err != nil {

View file

@ -7,12 +7,12 @@ import (
"strconv" "strconv"
"time" "time"
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" 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/common"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id" oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"

View file

@ -195,7 +195,7 @@ func flattenComplexMembersIfECContainer(cmd *cobra.Command, cnrID cid.ID, member
prmHead.SetRawFlag(true) // to get an error instead of whole object prmHead.SetRawFlag(true) // to get an error instead of whole object
eg, egCtx := errgroup.WithContext(cmd.Context()) eg, egCtx := errgroup.WithContext(cmd.Context())
for idx := range members { for idx := range len(members) {
partObjID := members[idx] partObjID := members[idx]
eg.Go(func() error { eg.Go(func() error {

View file

@ -10,11 +10,11 @@ import (
"strings" "strings"
"time" "time"
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" 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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" 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" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"

View file

@ -21,6 +21,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/misc" "git.frostfs.info/TrueCloudLab/frostfs-node/misc"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/config" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/config"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/gendoc" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/gendoc"
"github.com/mitchellh/go-homedir"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -111,16 +112,14 @@ func initConfig() {
// Use config file from the flag. // Use config file from the flag.
viper.SetConfigFile(cfgFile) viper.SetConfigFile(cfgFile)
} else { } else {
// Find config directory. // Find home directory.
configDir, err := os.UserConfigDir() home, err := homedir.Dir()
if err != nil { commonCmd.ExitOnErr(rootCmd, "", err)
common.PrintVerbose(rootCmd, "Get config dir: %s", err)
} else { // Search config in `$HOME/.config/frostfs-cli/` with name "config.yaml"
// Search config in `$XDG_CONFIG_HOME/frostfs-cli/` with name "config.yaml" viper.AddConfigPath(filepath.Join(home, ".config", "frostfs-cli"))
viper.AddConfigPath(filepath.Join(configDir, "frostfs-cli")) viper.SetConfigName("config")
viper.SetConfigName("config") viper.SetConfigType("yaml")
viper.SetConfigType("yaml")
}
} }
viper.SetEnvPrefix(envPrefix) viper.SetEnvPrefix(envPrefix)

View file

@ -30,6 +30,8 @@ func initAddCmd() {
ff := addCmd.Flags() ff := addCmd.Flags()
ff.StringSlice(metaFlagKey, nil, "Meta pairs in the form of Key1=[0x]Value1,Key2=[0x]Value2") ff.StringSlice(metaFlagKey, nil, "Meta pairs in the form of Key1=[0x]Value1,Key2=[0x]Value2")
ff.Uint64(parentIDFlagKey, 0, "Parent node ID") ff.Uint64(parentIDFlagKey, 0, "Parent node ID")
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
} }
func add(cmd *cobra.Command, _ []string) { func add(cmd *cobra.Command, _ []string) {
@ -45,10 +47,9 @@ func add(cmd *cobra.Command, _ []string) {
meta, err := parseMeta(cmd) meta, err := parseMeta(cmd)
commonCmd.ExitOnErr(cmd, "meta data parsing: %w", err) commonCmd.ExitOnErr(cmd, "meta data parsing: %w", err)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)

View file

@ -36,6 +36,7 @@ func initAddByPathCmd() {
ff.String(pathFlagKey, "", "Path to a node") ff.String(pathFlagKey, "", "Path to a node")
ff.StringSlice(metaFlagKey, nil, "Meta pairs in the form of Key1=[0x]Value1,Key2=[0x]Value2") 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) _ = cobra.MarkFlagRequired(ff, pathFlagKey)
} }
@ -49,10 +50,9 @@ func addByPath(cmd *cobra.Command, _ []string) {
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
tid, _ := cmd.Flags().GetString(treeIDFlagKey) tid, _ := cmd.Flags().GetString(treeIDFlagKey)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)

View file

@ -2,16 +2,14 @@ package tree
import ( import (
"context" "context"
"fmt"
"strings" "strings"
"time"
"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/commonflags"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/tree" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/tree"
metrics "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics/grpc" metrics "git.frostfs.info/TrueCloudLab/frostfs-observability/metrics/grpc"
tracing "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing/grpc" tracing "git.frostfs.info/TrueCloudLab/frostfs-observability/tracing/grpc"
"github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/credentials/insecure"
@ -19,20 +17,15 @@ import (
// _client returns grpc Tree service client. Should be removed // _client returns grpc Tree service client. Should be removed
// after making Tree API public. // after making Tree API public.
func _client() (tree.TreeServiceClient, error) { func _client(ctx context.Context) (tree.TreeServiceClient, error) {
var netAddr network.Address var netAddr network.Address
err := netAddr.FromString(viper.GetString(commonflags.RPC))
rpcEndpoint := viper.GetString(commonflags.RPC)
if rpcEndpoint == "" {
return nil, fmt.Errorf("%s is not defined", commonflags.RPC)
}
err := netAddr.FromString(rpcEndpoint)
if err != nil { if err != nil {
return nil, err return nil, err
} }
opts := []grpc.DialOption{ opts := []grpc.DialOption{
grpc.WithBlock(),
grpc.WithChainUnaryInterceptor( grpc.WithChainUnaryInterceptor(
metrics.NewUnaryClientInterceptor(), metrics.NewUnaryClientInterceptor(),
tracing.NewUnaryClientInteceptor(), tracing.NewUnaryClientInteceptor(),
@ -41,21 +34,18 @@ func _client() (tree.TreeServiceClient, error) {
metrics.NewStreamClientInterceptor(), metrics.NewStreamClientInterceptor(),
tracing.NewStreamClientInterceptor(), tracing.NewStreamClientInterceptor(),
), ),
grpc.WithDefaultCallOptions(grpc.WaitForReady(true)),
} }
if !strings.HasPrefix(netAddr.URIAddr(), "grpcs:") { if !strings.HasPrefix(netAddr.URIAddr(), "grpcs:") {
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials())) opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
} }
cc, err := grpc.NewClient(netAddr.URIAddr(), opts...) // a default connection establishing timeout
const defaultClientConnectTimeout = time.Second * 2
ctx, cancel := context.WithTimeout(ctx, defaultClientConnectTimeout)
cc, err := grpc.DialContext(ctx, netAddr.URIAddr(), opts...)
cancel()
return tree.NewTreeServiceClient(cc), err return tree.NewTreeServiceClient(cc), err
} }
func contextWithTimeout(cmd *cobra.Command) (context.Context, context.CancelFunc) {
if timeout := viper.GetDuration(commonflags.Timeout); timeout > 0 {
common.PrintVerbose(cmd, "Set request timeout to %s.", timeout)
return context.WithTimeout(cmd.Context(), timeout)
}
return context.WithTimeout(cmd.Context(), commonflags.TimeoutDefault)
}

View file

@ -36,6 +36,8 @@ func initGetByPathCmd() {
ff.String(pathFlagKey, "", "Path to a node") ff.String(pathFlagKey, "", "Path to a node")
ff.Bool(latestOnlyFlagKey, false, "Look only for the latest version of 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) { func getByPath(cmd *cobra.Command, _ []string) {
@ -48,10 +50,9 @@ func getByPath(cmd *cobra.Command, _ []string) {
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
tid, _ := cmd.Flags().GetString(treeIDFlagKey) tid, _ := cmd.Flags().GetString(treeIDFlagKey)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)

View file

@ -30,6 +30,8 @@ func initGetOpLogCmd() {
ff := getOpLogCmd.Flags() ff := getOpLogCmd.Flags()
ff.Uint64(heightFlagKey, 0, "Height to start with") ff.Uint64(heightFlagKey, 0, "Height to start with")
ff.Uint64(countFlagKey, 10, "Logged operations count") ff.Uint64(countFlagKey, 10, "Logged operations count")
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
} }
func getOpLog(cmd *cobra.Command, _ []string) { func getOpLog(cmd *cobra.Command, _ []string) {
@ -42,10 +44,9 @@ func getOpLog(cmd *cobra.Command, _ []string) {
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
tid, _ := cmd.Flags().GetString(treeIDFlagKey) tid, _ := cmd.Flags().GetString(treeIDFlagKey)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)

View file

@ -20,14 +20,15 @@ var healthcheckCmd = &cobra.Command{
func initHealthcheckCmd() { func initHealthcheckCmd() {
commonflags.Init(healthcheckCmd) commonflags.Init(healthcheckCmd)
ff := healthcheckCmd.Flags()
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
} }
func healthcheck(cmd *cobra.Command, _ []string) { func healthcheck(cmd *cobra.Command, _ []string) {
pk := key.GetOrGenerate(cmd) pk := key.GetOrGenerate(cmd)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
req := &tree.HealthcheckRequest{ req := &tree.HealthcheckRequest{

View file

@ -26,6 +26,8 @@ func initListCmd() {
ff := listCmd.Flags() ff := listCmd.Flags()
ff.String(commonflags.CIDFlag, "", commonflags.CIDFlagUsage) ff.String(commonflags.CIDFlag, "", commonflags.CIDFlagUsage)
_ = listCmd.MarkFlagRequired(commonflags.CIDFlag) _ = listCmd.MarkFlagRequired(commonflags.CIDFlag)
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
} }
func list(cmd *cobra.Command, _ []string) { func list(cmd *cobra.Command, _ []string) {
@ -36,10 +38,9 @@ func list(cmd *cobra.Command, _ []string) {
err := cnr.DecodeString(cidString) err := cnr.DecodeString(cidString)
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)

View file

@ -33,6 +33,8 @@ func initMoveCmd() {
_ = getSubtreeCmd.MarkFlagRequired(nodeIDFlagKey) _ = getSubtreeCmd.MarkFlagRequired(nodeIDFlagKey)
_ = getSubtreeCmd.MarkFlagRequired(parentIDFlagKey) _ = getSubtreeCmd.MarkFlagRequired(parentIDFlagKey)
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
} }
func move(cmd *cobra.Command, _ []string) { func move(cmd *cobra.Command, _ []string) {
@ -43,10 +45,9 @@ func move(cmd *cobra.Command, _ []string) {
err := cnr.DecodeString(cidString) err := cnr.DecodeString(cidString)
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)

View file

@ -29,6 +29,8 @@ func initRemoveCmd() {
ff.Uint64(nodeIDFlagKey, 0, "Node ID.") ff.Uint64(nodeIDFlagKey, 0, "Node ID.")
_ = getSubtreeCmd.MarkFlagRequired(nodeIDFlagKey) _ = getSubtreeCmd.MarkFlagRequired(nodeIDFlagKey)
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
} }
func remove(cmd *cobra.Command, _ []string) { func remove(cmd *cobra.Command, _ []string) {
@ -39,10 +41,9 @@ func remove(cmd *cobra.Command, _ []string) {
err := cnr.DecodeString(cidString) err := cnr.DecodeString(cidString)
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)

View file

@ -49,7 +49,6 @@ const (
heightFlagKey = "height" heightFlagKey = "height"
countFlagKey = "count" countFlagKey = "count"
depthFlagKey = "depth" depthFlagKey = "depth"
orderFlagKey = "ordered"
) )
func initCTID(cmd *cobra.Command) { func initCTID(cmd *cobra.Command) {

View file

@ -30,10 +30,11 @@ func initGetSubtreeCmd() {
ff := getSubtreeCmd.Flags() ff := getSubtreeCmd.Flags()
ff.Uint64(rootIDFlagKey, 0, "Root ID to traverse from.") ff.Uint64(rootIDFlagKey, 0, "Root ID to traverse from.")
ff.Uint32(depthFlagKey, 10, "Traversal depth.") ff.Uint32(depthFlagKey, 10, "Traversal depth.")
ff.Bool(orderFlagKey, false, "Sort output by ascending FileName.")
_ = getSubtreeCmd.MarkFlagRequired(commonflags.CIDFlag) _ = getSubtreeCmd.MarkFlagRequired(commonflags.CIDFlag)
_ = getSubtreeCmd.MarkFlagRequired(treeIDFlagKey) _ = getSubtreeCmd.MarkFlagRequired(treeIDFlagKey)
_ = cobra.MarkFlagRequired(ff, commonflags.RPC)
} }
func getSubTree(cmd *cobra.Command, _ []string) { func getSubTree(cmd *cobra.Command, _ []string) {
@ -44,10 +45,9 @@ func getSubTree(cmd *cobra.Command, _ []string) {
err := cnr.DecodeString(cidString) err := cnr.DecodeString(cidString)
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
ctx, cancel := contextWithTimeout(cmd) ctx := cmd.Context()
defer cancel()
cli, err := _client() cli, err := _client(ctx)
commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err)
rawCID := make([]byte, sha256.Size) rawCID := make([]byte, sha256.Size)
@ -59,13 +59,6 @@ func getSubTree(cmd *cobra.Command, _ []string) {
depth, _ := cmd.Flags().GetUint32(depthFlagKey) depth, _ := cmd.Flags().GetUint32(depthFlagKey)
order, _ := cmd.Flags().GetBool(orderFlagKey)
bodyOrder := tree.GetSubTreeRequest_Body_Order_None
if order {
bodyOrder = tree.GetSubTreeRequest_Body_Order_Asc
}
var bt []byte var bt []byte
if t := common.ReadBearerToken(cmd, bearerFlagKey); t != nil { if t := common.ReadBearerToken(cmd, bearerFlagKey); t != nil {
bt = t.Marshal() bt = t.Marshal()
@ -78,9 +71,6 @@ func getSubTree(cmd *cobra.Command, _ []string) {
RootId: []uint64{rid}, RootId: []uint64{rid},
Depth: depth, Depth: depth,
BearerToken: bt, BearerToken: bt,
OrderBy: &tree.GetSubTreeRequest_Body_Order{
Direction: bodyOrder,
},
}, },
} }

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"context"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
@ -42,12 +41,10 @@ func reloadConfig() error {
if err != nil { if err != nil {
return err return err
} }
logPrm.PrependTimestamp = cfg.GetBool("logger.timestamp")
return logPrm.Reload() return logPrm.Reload()
} }
func watchForSignal(ctx context.Context, cancel func()) { func watchForSignal(cancel func()) {
ch := make(chan os.Signal, 1) ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
@ -59,49 +56,49 @@ func watchForSignal(ctx context.Context, cancel func()) {
// signals causing application to shut down should have priority over // signals causing application to shut down should have priority over
// reconfiguration signal // reconfiguration signal
case <-ch: case <-ch:
log.Info(ctx, logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping) log.Info(logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
cancel() cancel()
shutdown(ctx) shutdown()
log.Info(ctx, logs.FrostFSNodeTerminationSignalProcessingIsComplete) log.Info(logs.FrostFSNodeTerminationSignalProcessingIsComplete)
return return
case err := <-intErr: // internal application error 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() cancel()
shutdown(ctx) shutdown()
return return
default: default:
// block until any signal is receieved // block until any signal is receieved
select { select {
case <-ch: case <-ch:
log.Info(ctx, logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping) log.Info(logs.FrostFSNodeTerminationSignalHasBeenReceivedStopping)
cancel() cancel()
shutdown(ctx) shutdown()
log.Info(ctx, logs.FrostFSNodeTerminationSignalProcessingIsComplete) log.Info(logs.FrostFSNodeTerminationSignalProcessingIsComplete)
return return
case err := <-intErr: // internal application error 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() cancel()
shutdown(ctx) shutdown()
return return
case <-sighupCh: case <-sighupCh:
log.Info(ctx, logs.FrostFSNodeSIGHUPHasBeenReceivedRereadingConfiguration) log.Info(logs.FrostFSNodeSIGHUPHasBeenReceivedRereadingConfiguration)
if !innerRing.CompareAndSwapHealthStatus(ctx, control.HealthStatus_READY, control.HealthStatus_RECONFIGURING) { if !innerRing.CompareAndSwapHealthStatus(control.HealthStatus_READY, control.HealthStatus_RECONFIGURING) {
log.Info(ctx, logs.FrostFSNodeSIGHUPSkip) log.Info(logs.FrostFSNodeSIGHUPSkip)
break break
} }
err := reloadConfig() err := reloadConfig()
if err != nil { if err != nil {
log.Error(ctx, logs.FrostFSNodeConfigurationReading, zap.Error(err)) log.Error(logs.FrostFSNodeConfigurationReading, zap.Error(err))
} }
pprofCmp.reload(ctx) pprofCmp.reload()
metricsCmp.reload(ctx) metricsCmp.reload()
log.Info(ctx, logs.FrostFSIRReloadExtraWallets) log.Info(logs.FrostFSIRReloadExtraWallets)
err = innerRing.SetExtraWallets(cfg) err = innerRing.SetExtraWallets(cfg)
if err != nil { 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) innerRing.CompareAndSwapHealthStatus(control.HealthStatus_RECONFIGURING, control.HealthStatus_READY)
log.Info(ctx, logs.FrostFSNodeConfigurationHasBeenReloadedSuccessfully) log.Info(logs.FrostFSNodeConfigurationHasBeenReloadedSuccessfully)
} }
} }
} }

View file

@ -9,7 +9,6 @@ import (
func defaultConfiguration(cfg *viper.Viper) { func defaultConfiguration(cfg *viper.Viper) {
cfg.SetDefault("logger.level", "info") cfg.SetDefault("logger.level", "info")
cfg.SetDefault("logger.destination", "stdout") cfg.SetDefault("logger.destination", "stdout")
cfg.SetDefault("logger.timestamp", false)
setPprofDefaults(cfg) setPprofDefaults(cfg)
@ -48,8 +47,6 @@ func defaultConfiguration(cfg *viper.Viper) {
cfg.SetDefault("node.kludge_compatibility_mode", false) cfg.SetDefault("node.kludge_compatibility_mode", false)
cfg.SetDefault("audit.enabled", false) cfg.SetDefault("audit.enabled", false)
setMultinetDefaults(cfg)
} }
func setControlDefaults(cfg *viper.Viper) { func setControlDefaults(cfg *viper.Viper) {
@ -133,11 +130,3 @@ func setMorphDefaults(cfg *viper.Viper) {
cfg.SetDefault("morph.validators", []string{}) cfg.SetDefault("morph.validators", []string{})
cfg.SetDefault("morph.switch_interval", 2*time.Minute) 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", "")
}

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"context"
"net/http" "net/http"
"time" "time"
@ -25,8 +24,8 @@ const (
shutdownTimeoutKeyPostfix = ".shutdown_timeout" shutdownTimeoutKeyPostfix = ".shutdown_timeout"
) )
func (c *httpComponent) init(ctx context.Context) { func (c *httpComponent) init() {
log.Info(ctx, "init "+c.name) log.Info("init " + c.name)
c.enabled = cfg.GetBool(c.name + enabledKeyPostfix) c.enabled = cfg.GetBool(c.name + enabledKeyPostfix)
c.address = cfg.GetString(c.name + addressKeyPostfix) c.address = cfg.GetString(c.name + addressKeyPostfix)
c.shutdownDur = cfg.GetDuration(c.name + shutdownTimeoutKeyPostfix) c.shutdownDur = cfg.GetDuration(c.name + shutdownTimeoutKeyPostfix)
@ -40,14 +39,14 @@ func (c *httpComponent) init(ctx context.Context) {
httputil.WithShutdownTimeout(c.shutdownDur), httputil.WithShutdownTimeout(c.shutdownDur),
) )
} else { } else {
log.Info(ctx, c.name+" is disabled, skip") log.Info(c.name + " is disabled, skip")
c.srv = nil c.srv = nil
} }
} }
func (c *httpComponent) start(ctx context.Context) { func (c *httpComponent) start() {
if c.srv != nil { if c.srv != nil {
log.Info(ctx, "start "+c.name) log.Info("start " + c.name)
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() 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 { if c.srv != nil {
log.Info(ctx, "shutdown "+c.name) log.Info("shutdown " + c.name)
return c.srv.Shutdown(ctx) return c.srv.Shutdown()
} }
return nil return nil
} }
@ -71,17 +70,17 @@ func (c *httpComponent) needReload() bool {
return enabled != c.enabled || enabled && (address != c.address || dur != c.shutdownDur) return enabled != c.enabled || enabled && (address != c.address || dur != c.shutdownDur)
} }
func (c *httpComponent) reload(ctx context.Context) { func (c *httpComponent) reload() {
log.Info(ctx, "reload "+c.name) log.Info("reload " + c.name)
if c.needReload() { if c.needReload() {
log.Info(ctx, c.name+" config updated") log.Info(c.name + " config updated")
if err := c.shutdown(ctx); err != nil { if err := c.shutdown(); err != nil {
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer, log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
zap.String("error", err.Error()), zap.String("error", err.Error()),
) )
} else { } else {
c.init(ctx) c.init()
c.start(ctx) c.start()
} }
} }
} }

View file

@ -13,7 +13,6 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/misc" "git.frostfs.info/TrueCloudLab/frostfs-node/misc"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/innerring"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/sdnotify"
"github.com/spf13/viper" "github.com/spf13/viper"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -79,56 +78,50 @@ func main() {
) )
exitErr(err) exitErr(err)
logPrm.SamplingHook = metrics.LogMetrics().GetSamplingHook() logPrm.SamplingHook = metrics.LogMetrics().GetSamplingHook()
logPrm.PrependTimestamp = cfg.GetBool("logger.timestamp")
log, err = logger.NewLogger(logPrm) log, err = logger.NewLogger(logPrm)
exitErr(err) exitErr(err)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
pprofCmp = newPprofComponent() pprofCmp = newPprofComponent()
pprofCmp.init(ctx) pprofCmp.init()
metricsCmp = newMetricsComponent() metricsCmp = newMetricsComponent()
metricsCmp.init(ctx) metricsCmp.init()
audit.Store(cfg.GetBool("audit.enabled")) audit.Store(cfg.GetBool("audit.enabled"))
innerRing, err = innerring.New(ctx, log, cfg, intErr, metrics, cmode, audit) innerRing, err = innerring.New(ctx, log, cfg, intErr, metrics, cmode, audit)
exitErr(err) exitErr(err)
pprofCmp.start(ctx) pprofCmp.start()
metricsCmp.start(ctx) metricsCmp.start()
// start inner ring // start inner ring
err = innerRing.Start(ctx, intErr) err = innerRing.Start(ctx, intErr)
exitErr(err) exitErr(err)
log.Info(ctx, logs.CommonApplicationStarted, log.Info(logs.CommonApplicationStarted,
zap.String("version", misc.Version)) zap.String("version", misc.Version))
watchForSignal(ctx, cancel) watchForSignal(cancel)
<-ctx.Done() // graceful shutdown <-ctx.Done() // graceful shutdown
log.Debug(ctx, logs.FrostFSNodeWaitingForAllProcessesToStop) log.Debug(logs.FrostFSNodeWaitingForAllProcessesToStop)
wg.Wait() wg.Wait()
log.Info(ctx, logs.FrostFSIRApplicationStopped) log.Info(logs.FrostFSIRApplicationStopped)
} }
func shutdown(ctx context.Context) { func shutdown() {
innerRing.Stop(ctx) innerRing.Stop()
if err := metricsCmp.shutdown(ctx); err != nil { if err := metricsCmp.shutdown(); err != nil {
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer, log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
zap.String("error", err.Error()), zap.String("error", err.Error()),
) )
} }
if err := pprofCmp.shutdown(ctx); err != nil { if err := pprofCmp.shutdown(); err != nil {
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer, log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
zap.String("error", err.Error()), zap.String("error", err.Error()),
) )
} }
if err := sdnotify.ClearStatus(); err != nil {
log.Error(ctx, logs.FailedToReportStatusToSystemd, zap.Error(err))
}
} }

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"context"
"runtime" "runtime"
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs" "git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
@ -29,8 +28,8 @@ func newPprofComponent() *pprofComponent {
} }
} }
func (c *pprofComponent) init(ctx context.Context) { func (c *pprofComponent) init() {
c.httpComponent.init(ctx) c.httpComponent.init()
if c.enabled { if c.enabled {
c.blockRate = cfg.GetInt(pprofBlockRateKey) c.blockRate = cfg.GetInt(pprofBlockRateKey)
@ -52,17 +51,17 @@ func (c *pprofComponent) needReload() bool {
c.enabled && (c.blockRate != blockRate || c.mutexRate != mutexRate) c.enabled && (c.blockRate != blockRate || c.mutexRate != mutexRate)
} }
func (c *pprofComponent) reload(ctx context.Context) { func (c *pprofComponent) reload() {
log.Info(ctx, "reload "+c.name) log.Info("reload " + c.name)
if c.needReload() { if c.needReload() {
log.Info(ctx, c.name+" config updated") log.Info(c.name + " config updated")
if err := c.shutdown(ctx); err != nil { if err := c.shutdown(); err != nil {
log.Debug(ctx, logs.FrostFSIRCouldNotShutdownHTTPServer, log.Debug(logs.FrostFSIRCouldNotShutdownHTTPServer,
zap.String("error", err.Error())) zap.String("error", err.Error()))
return return
} }
c.init(ctx) c.init()
c.start(ctx) c.start()
} }
} }

View file

@ -28,7 +28,7 @@ func inspectFunc(cmd *cobra.Command, _ []string) {
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err)) common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
blz := openBlobovnicza(cmd) blz := openBlobovnicza(cmd)
defer blz.Close(cmd.Context()) defer blz.Close()
var prm blobovnicza.GetPrm var prm blobovnicza.GetPrm
prm.SetAddress(addr) prm.SetAddress(addr)

View file

@ -32,7 +32,7 @@ func listFunc(cmd *cobra.Command, _ []string) {
} }
blz := openBlobovnicza(cmd) blz := openBlobovnicza(cmd)
defer blz.Close(cmd.Context()) defer blz.Close()
err := blobovnicza.IterateAddresses(context.Background(), blz, wAddr) err := blobovnicza.IterateAddresses(context.Background(), blz, wAddr)
common.ExitOnErr(cmd, common.Errf("blobovnicza iterator failure: %w", err)) common.ExitOnErr(cmd, common.Errf("blobovnicza iterator failure: %w", err))

View file

@ -27,7 +27,7 @@ func openBlobovnicza(cmd *cobra.Command) *blobovnicza.Blobovnicza {
blobovnicza.WithPath(vPath), blobovnicza.WithPath(vPath),
blobovnicza.WithReadOnly(true), blobovnicza.WithReadOnly(true),
) )
common.ExitOnErr(cmd, blz.Open(cmd.Context())) common.ExitOnErr(cmd, blz.Open())
return blz return blz
} }

View file

@ -9,6 +9,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"go.etcd.io/bbolt"
) )
var tuiCMD = &cobra.Command{ var tuiCMD = &cobra.Command{
@ -42,7 +43,7 @@ func tuiFunc(cmd *cobra.Command, _ []string) {
} }
func runTUI(cmd *cobra.Command) error { func runTUI(cmd *cobra.Command) error {
db, err := tui.OpenDB(vPath, false) db, err := openDB(false)
if err != nil { if err != nil {
return fmt.Errorf("couldn't open database: %w", err) 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) app.SetRoot(ui, true).SetFocus(ui)
return app.Run() 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
}

View file

@ -31,7 +31,7 @@ func inspectFunc(cmd *cobra.Command, _ []string) {
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err)) common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
db := openMeta(cmd) db := openMeta(cmd)
defer db.Close(cmd.Context()) defer db.Close()
storageID := meta.StorageIDPrm{} storageID := meta.StorageIDPrm{}
storageID.SetAddress(addr) storageID.SetAddress(addr)

View file

@ -19,7 +19,7 @@ func init() {
func listGarbageFunc(cmd *cobra.Command, _ []string) { func listGarbageFunc(cmd *cobra.Command, _ []string) {
db := openMeta(cmd) db := openMeta(cmd)
defer db.Close(cmd.Context()) defer db.Close()
var garbPrm meta.GarbageIterationPrm var garbPrm meta.GarbageIterationPrm
garbPrm.SetHandler( garbPrm.SetHandler(

View file

@ -19,7 +19,7 @@ func init() {
func listGraveyardFunc(cmd *cobra.Command, _ []string) { func listGraveyardFunc(cmd *cobra.Command, _ []string) {
db := openMeta(cmd) db := openMeta(cmd)
defer db.Close(cmd.Context()) defer db.Close()
var gravePrm meta.GraveyardIterationPrm var gravePrm meta.GraveyardIterationPrm
gravePrm.SetHandler( gravePrm.SetHandler(

View file

@ -9,6 +9,7 @@ import (
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-lens/internal/tui"
"github.com/rivo/tview" "github.com/rivo/tview"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"go.etcd.io/bbolt"
) )
var tuiCMD = &cobra.Command{ var tuiCMD = &cobra.Command{
@ -43,7 +44,7 @@ func tuiFunc(cmd *cobra.Command, _ []string) {
} }
func runTUI(cmd *cobra.Command) error { func runTUI(cmd *cobra.Command) error {
db, err := tui.OpenDB(vPath, false) db, err := openDB(false)
if err != nil { if err != nil {
return fmt.Errorf("couldn't open database: %w", err) 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) app.SetRoot(ui, true).SetFocus(ui)
return app.Run() 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
}

View file

@ -7,8 +7,6 @@ import (
) )
type RawEntry struct { type RawEntry struct {
// key and value used for record dump.
// nolint:unused
key, value []byte key, value []byte
} }

View file

@ -38,7 +38,7 @@ func (r *ContainerVolumeRecord) String() string {
func (r *LockedRecord) String() string { func (r *LockedRecord) String() string {
return fmt.Sprintf( 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), common.FormatSimple(fmt.Sprintf("%-44s", r.id), tcell.ColorAqua),
tview.Borders.Vertical, tview.Borders.Vertical,
len(r.ids), len(r.ids),

View file

@ -11,7 +11,7 @@ func DecodeOIDs(data []byte) ([]oid.ID, error) {
size := r.ReadVarUint() size := r.ReadVarUint()
oids := make([]oid.ID, size) 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 { if err := oids[i].Decode(r.ReadVarBytes()); err != nil {
return nil, err return nil, err
} }

View file

@ -16,8 +16,6 @@ type (
DefaultRecord struct { DefaultRecord struct {
addr oid.Address addr oid.Address
// data used for record dump.
// nolint:unused
data []byte data []byte
} }
) )

Some files were not shown because too many files have changed in this diff Show more