forked from TrueCloudLab/frostfs-node
Compare commits
1 commit
master
...
carpawell/
Author | SHA1 | Date | |
---|---|---|---|
|
0c0a433b84 |
333 changed files with 1661 additions and 2656 deletions
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
|
@ -1 +1 @@
|
||||||
* @TrueCloudLab/storage-core @TrueCloudLab/committers
|
* @carpawell @fyrchik @acid-ant
|
||||||
|
|
20
.gitignore
vendored
20
.gitignore
vendored
|
@ -30,22 +30,4 @@ testfile
|
||||||
.neofs-cli.yml
|
.neofs-cli.yml
|
||||||
|
|
||||||
# debhelpers
|
# debhelpers
|
||||||
debian/*debhelper*
|
**/.debhelper
|
||||||
|
|
||||||
# logfiles
|
|
||||||
debian/*.log
|
|
||||||
|
|
||||||
# .substvars
|
|
||||||
debian/*.substvars
|
|
||||||
|
|
||||||
# .bash-completion
|
|
||||||
debian/*.bash-completion
|
|
||||||
|
|
||||||
# Install folders and files
|
|
||||||
debian/frostfs-cli/
|
|
||||||
debian/frostfs-ir/
|
|
||||||
debian/files
|
|
||||||
debian/frostfs-storage/
|
|
||||||
debian/changelog
|
|
||||||
man/
|
|
||||||
debs/
|
|
||||||
|
|
43
CHANGELOG.md
43
CHANGELOG.md
|
@ -6,45 +6,17 @@ Changelog for FrostFS Node
|
||||||
### Added
|
### Added
|
||||||
- Separate batching for replicated operations over the same container in pilorama (#1621)
|
- Separate batching for replicated operations over the same container in pilorama (#1621)
|
||||||
- Doc for extended headers (#2128)
|
- Doc for extended headers (#2128)
|
||||||
- New `frostfs_node_object_container_size` metric for tracking size of reqular objects in a container (#2116)
|
|
||||||
- New `frostfs_node_object_payload_size` metric for tracking size of reqular objects on a single shard (#1794)
|
|
||||||
- Add command `frostfs-adm morph netmap-candidates` (#1889)
|
|
||||||
- `object.delete.tombstone_lifetime` config parameter to set tombstone lifetime in the DELETE service (#2246)
|
|
||||||
- Reload config for pprof and metrics on SIGHUP in `neofs-node` (#1868)
|
|
||||||
- Multiple configs support (#44)
|
|
||||||
- Parameters `nns-name` and `nns-zone` for command `frostfs-cli container create` (#37)
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Change `frostfs_node_engine_container_size` to counting sizes of logical objects
|
|
||||||
- `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962)
|
- `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962)
|
||||||
- Env prefix in configuration changed to `FROSTFS_*` (#43)
|
|
||||||
- Link object is broadcast throughout the whole container now (#57)
|
|
||||||
- Pilorama now can merge multiple batches into one (#2231)
|
|
||||||
- Storage engine now can start even when some shard components are unavailable (#2238)
|
|
||||||
- `neofs-cli` buffer for object put increased from 4 KiB to 3 MiB (#2243)
|
|
||||||
- Expired locked object is available for reading (#56)
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Increase payload size metric on shards' `put` operation (#1794)
|
|
||||||
- Big object removal with non-local parts (#1978)
|
- Big object removal with non-local parts (#1978)
|
||||||
- Disable pilorama when moving to degraded mode (#2197)
|
- Disable pilorama when moving to degraded mode (#2197)
|
||||||
- Fetching blobovnicza objects that not found in write-cache (#2206)
|
- Fetching blobovnicza objects that not found in write-cache (#2206)
|
||||||
- Do not search for the small objects in FSTree (#2206)
|
- Do not search for the small objects in FSTree (#2206)
|
||||||
- Correct status error for expired session token (#2207)
|
- Correct status error for expired session token (#2207)
|
||||||
- Set flag `mode` required for `frostfs-cli control shards set-mode` (#8)
|
- Concurrent morph cache misses (#1248)
|
||||||
- Fix `dirty` suffix in debian package version (#53)
|
|
||||||
- Prevent node process from killing by systemd when shutting down (#1465)
|
|
||||||
- Restore subscriptions correctly on morph client switch (#2212)
|
|
||||||
- Expired objects could be returned if not marked with GC yet (#2213)
|
|
||||||
- `neofs-adm morph dump-hashes` now properly iterates over custom domain (#2224)
|
|
||||||
- Possible deadlock in write-cache (#2239)
|
|
||||||
- Fix `*_req_count` and `*_req_count_success` metric values (#2241)
|
|
||||||
- Storage ID update by write-cache (#2244)
|
|
||||||
- `neo-go` client deadlock on subscription restoration (#2244)
|
|
||||||
- Possible panic during write-cache initialization (#2234)
|
|
||||||
- Do not fetch an object if `meta` is missing it (#61)
|
|
||||||
- Create contract wallet only by `init` and `update-config` command (#63)
|
|
||||||
- Actually use `object.put.pool_size_local` and independent pool for local puts (#64).
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
### Updated
|
### Updated
|
||||||
|
@ -54,17 +26,11 @@ Changelog for FrostFS Node
|
||||||
- `golang.org/x/term` to `v0.3.0`
|
- `golang.org/x/term` to `v0.3.0`
|
||||||
- `google.golang.org/grpc` to `v1.51.0`
|
- `google.golang.org/grpc` to `v1.51.0`
|
||||||
- `github.com/nats-io/nats.go` to `v1.22.1`
|
- `github.com/nats-io/nats.go` to `v1.22.1`
|
||||||
- `github.com/TrueCloudLab/hrw` to `v.1.1.1`
|
|
||||||
- Minimum go version to v1.18
|
- Minimum go version to v1.18
|
||||||
|
|
||||||
### Updating from v0.35.0
|
### Updating from v0.35.0
|
||||||
|
|
||||||
You need to change configuration environment variables to `FROSTFS_*` if you use any.
|
## [0.35.0] - 2022-12-28 - Sindo (신도)
|
||||||
|
|
||||||
New config field `object.delete.tombstone_lifetime` allows to set tombstone lifetime
|
|
||||||
more appropriate for a specific deployment.
|
|
||||||
|
|
||||||
## [0.35.0] - 2022-12-28 - Sindo (신도, 信島)
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- `morph list-containers` in `neofs-adm` (#1689)
|
- `morph list-containers` in `neofs-adm` (#1689)
|
||||||
|
@ -148,6 +114,7 @@ more appropriate for a specific deployment.
|
||||||
- `spf13/viper` to `v1.8.0`
|
- `spf13/viper` to `v1.8.0`
|
||||||
- `google.golang.org/grpc` to `v1.50.1`
|
- `google.golang.org/grpc` to `v1.50.1`
|
||||||
|
|
||||||
|
|
||||||
### Updating from v0.34.0
|
### Updating from v0.34.0
|
||||||
Pass CID and OID parameters via the `--cid` and `--oid` flags, not as the command arguments.
|
Pass CID and OID parameters via the `--cid` and `--oid` flags, not as the command arguments.
|
||||||
|
|
||||||
|
@ -161,9 +128,9 @@ to match the container owner. Use `--force` (`-f`) flag to bypass this requireme
|
||||||
|
|
||||||
Tree service network replication can now be fine-tuned with `tree.replication_timeout` config field.
|
Tree service network replication can now be fine-tuned with `tree.replication_timeout` config field.
|
||||||
|
|
||||||
## [0.34.0] - 2022-10-31 - Marado (마라도, 馬羅島)
|
## [0.34.0] - 2022-10-31 - Marado (마라도, 馬羅島)
|
||||||
|
|
||||||
### Added
|
# ## Added
|
||||||
- `--timeout` flag in `neofs-cli control` commands (#1917)
|
- `--timeout` flag in `neofs-cli control` commands (#1917)
|
||||||
- Document shard modes of operation (#1909)
|
- Document shard modes of operation (#1909)
|
||||||
- `tree list` CLI command (#1332)
|
- `tree list` CLI command (#1332)
|
||||||
|
|
|
@ -38,7 +38,7 @@ $ git clone https://github.com/TrueCloudLab/frostfs-node
|
||||||
|
|
||||||
### Set up git remote as ``upstream``
|
### Set up git remote as ``upstream``
|
||||||
```sh
|
```sh
|
||||||
$ cd frostfs-node
|
$ cd neofs-node
|
||||||
$ git remote add upstream https://github.com/TrueCloudLab/frostfs-node
|
$ git remote add upstream https://github.com/TrueCloudLab/frostfs-node
|
||||||
$ git fetch upstream
|
$ git fetch upstream
|
||||||
$ git merge upstream/master
|
$ git merge upstream/master
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -16,7 +16,7 @@ RELEASE = release
|
||||||
DIRS = $(BIN) $(RELEASE)
|
DIRS = $(BIN) $(RELEASE)
|
||||||
|
|
||||||
# List of binaries to build.
|
# List of binaries to build.
|
||||||
CMDS = $(notdir $(basename $(wildcard cmd/frostfs-*)))
|
CMDS = $(notdir $(basename $(wildcard cmd/*)))
|
||||||
BINS = $(addprefix $(BIN)/, $(CMDS))
|
BINS = $(addprefix $(BIN)/, $(CMDS))
|
||||||
|
|
||||||
# .deb package versioning
|
# .deb package versioning
|
||||||
|
@ -152,7 +152,7 @@ clean:
|
||||||
|
|
||||||
# Package for Debian
|
# Package for Debian
|
||||||
debpackage:
|
debpackage:
|
||||||
dch -b --package frostfs-node \
|
dch --package frostfs-node \
|
||||||
--controlmaint \
|
--controlmaint \
|
||||||
--newversion $(PKG_VERSION) \
|
--newversion $(PKG_VERSION) \
|
||||||
--distribution $(OS_RELEASE) \
|
--distribution $(OS_RELEASE) \
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
package commonflags
|
|
||||||
|
|
||||||
const (
|
|
||||||
ConfigFlag = "config"
|
|
||||||
ConfigFlagShorthand = "c"
|
|
||||||
ConfigFlagUsage = "Config file"
|
|
||||||
|
|
||||||
ConfigDirFlag = "config-dir"
|
|
||||||
ConfigDirFlagUsage = "Config directory"
|
|
||||||
|
|
||||||
Verbose = "verbose"
|
|
||||||
VerboseShorthand = "v"
|
|
||||||
VerboseUsage = "Verbose output"
|
|
||||||
)
|
|
|
@ -140,14 +140,14 @@ func setConfigCmd(cmd *cobra.Command, args []string) error {
|
||||||
return wCtx.awaitTx()
|
return wCtx.awaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseConfigPair(kvStr string, force bool) (key string, val any, err error) {
|
func parseConfigPair(kvStr string, force bool) (key string, val interface{}, err error) {
|
||||||
k, v, found := strings.Cut(kvStr, "=")
|
kv := strings.SplitN(kvStr, "=", 2)
|
||||||
if !found {
|
if len(kv) != 2 {
|
||||||
return "", nil, fmt.Errorf("invalid parameter format: must be 'key=val', got: %s", kvStr)
|
return "", nil, fmt.Errorf("invalid parameter format: must be 'key=val', got: %s", kvStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
key = k
|
key = kv[0]
|
||||||
valRaw := v
|
valRaw := kv[1]
|
||||||
|
|
||||||
switch key {
|
switch key {
|
||||||
case netmapAuditFeeKey, netmapBasicIncomeRateKey,
|
case netmapAuditFeeKey, netmapBasicIncomeRateKey,
|
||||||
|
@ -162,7 +162,7 @@ func parseConfigPair(kvStr string, force bool) (key string, val any, err error)
|
||||||
case netmapEigenTrustAlphaKey:
|
case netmapEigenTrustAlphaKey:
|
||||||
// just check that it could
|
// just check that it could
|
||||||
// be parsed correctly
|
// be parsed correctly
|
||||||
_, err = strconv.ParseFloat(v, 64)
|
_, err = strconv.ParseFloat(kv[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("could not parse %s's value '%s' as float: %w", key, valRaw, err)
|
err = fmt.Errorf("could not parse %s's value '%s' as float: %w", key, valRaw, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package morph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
@ -108,30 +107,31 @@ func dumpContractHashes(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error {
|
func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string, c Client) error {
|
||||||
const nnsMaxTokens = 100
|
const nnsMaxTokens = 100
|
||||||
|
|
||||||
inv := invoker.New(c, nil)
|
inv := invoker.New(c, nil)
|
||||||
|
|
||||||
|
arr, err := unwrap.Array(inv.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't get a list of NNS domains: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(zone, ".") {
|
if !strings.HasPrefix(zone, ".") {
|
||||||
zone = "." + zone
|
zone = "." + zone
|
||||||
}
|
}
|
||||||
|
|
||||||
var infos []contractDumpInfo
|
var infos []contractDumpInfo
|
||||||
processItem := func(item stackitem.Item) {
|
for i := range arr {
|
||||||
bs, err := item.TryBytes()
|
bs, err := arr[i].TryBytes()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrf("Invalid NNS record: %v\n", err)
|
continue
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.HasSuffix(bs, []byte(zone)) {
|
if !bytes.HasSuffix(bs, []byte(zone)) {
|
||||||
// Related https://github.com/nspcc-dev/neofs-contract/issues/316.
|
continue
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h, err := nnsResolveHash(inv, nnsHash, string(bs))
|
h, err := nnsResolveHash(inv, nnsHash, string(bs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.PrintErrf("Could not resolve name %s: %v\n", string(bs), err)
|
continue
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
infos = append(infos, contractDumpInfo{
|
infos = append(infos, contractDumpInfo{
|
||||||
|
@ -140,39 +140,6 @@ func dumpCustomZoneHashes(cmd *cobra.Command, nnsHash util.Uint160, zone string,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionID, iter, err := unwrap.SessionIterator(inv.Call(nnsHash, "tokens"))
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, unwrap.ErrNoSessionID) {
|
|
||||||
items, err := unwrap.Array(inv.CallAndExpandIterator(nnsHash, "tokens", nnsMaxTokens))
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("can't get a list of NNS domains: %w", err)
|
|
||||||
}
|
|
||||||
if len(items) == nnsMaxTokens {
|
|
||||||
cmd.PrintErrln("Provided RPC endpoint doesn't support sessions, some hashes might be lost.")
|
|
||||||
}
|
|
||||||
for i := range items {
|
|
||||||
processItem(items[i])
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defer func() {
|
|
||||||
_ = inv.TerminateSession(sessionID)
|
|
||||||
}()
|
|
||||||
|
|
||||||
items, err := inv.TraverseIterator(sessionID, &iter, nnsMaxTokens)
|
|
||||||
for err == nil && len(items) != 0 {
|
|
||||||
for i := range items {
|
|
||||||
processItem(items[i])
|
|
||||||
}
|
|
||||||
items, err = inv.TraverseIterator(sessionID, &iter, nnsMaxTokens)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error during NNS domains iteration: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fillContractVersion(cmd, c, infos)
|
fillContractVersion(cmd, c, infos)
|
||||||
printContractInfo(cmd, infos)
|
printContractInfo(cmd, infos)
|
||||||
|
|
||||||
|
|
|
@ -115,10 +115,8 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
|
|
||||||
|
|
||||||
var w *wallet.Wallet
|
var w *wallet.Wallet
|
||||||
if needContracts {
|
if cmd.Name() != "deploy" {
|
||||||
w, err = openContractWallet(v, cmd, walletDir)
|
w, err = openContractWallet(v, cmd, walletDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -159,6 +157,7 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
needContracts := cmd.Name() == "update-contracts" || cmd.Name() == "init"
|
||||||
if needContracts {
|
if needContracts {
|
||||||
ctrPath, err = cmd.Flags().GetString(contractsInitFlag)
|
ctrPath, err = cmd.Flags().GetString(contractsInitFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -167,7 +167,7 @@ func (c *initializeContext) updateContracts() error {
|
||||||
|
|
||||||
w := io2.NewBufBinWriter()
|
w := io2.NewBufBinWriter()
|
||||||
|
|
||||||
var keysParam []any
|
var keysParam []interface{}
|
||||||
|
|
||||||
// Update script size for a single-node committee is close to the maximum allowed size of 65535.
|
// Update script size for a single-node committee is close to the maximum allowed size of 65535.
|
||||||
// Because of this we want to reuse alphabet contract NEF and manifest for different updates.
|
// Because of this we want to reuse alphabet contract NEF and manifest for different updates.
|
||||||
|
@ -299,7 +299,7 @@ func (c *initializeContext) updateContracts() error {
|
||||||
func (c *initializeContext) deployContracts() error {
|
func (c *initializeContext) deployContracts() error {
|
||||||
alphaCs := c.getContract(alphabetContract)
|
alphaCs := c.getContract(alphabetContract)
|
||||||
|
|
||||||
var keysParam []any
|
var keysParam []interface{}
|
||||||
|
|
||||||
baseGroups := alphaCs.Manifest.Groups
|
baseGroups := alphaCs.Manifest.Groups
|
||||||
|
|
||||||
|
@ -510,12 +510,12 @@ func readContractsFromArchive(file io.Reader, names []string) (map[string]*contr
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContractDeployParameters(cs *contractState, deployData []any) []any {
|
func getContractDeployParameters(cs *contractState, deployData []interface{}) []interface{} {
|
||||||
return []any{cs.RawNEF, cs.RawManifest, deployData}
|
return []interface{}{cs.RawNEF, cs.RawManifest, deployData}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getContractDeployData(ctrName string, keysParam []any) []any {
|
func (c *initializeContext) getContractDeployData(ctrName string, keysParam []interface{}) []interface{} {
|
||||||
items := make([]any, 1, 6)
|
items := make([]interface{}, 1, 6)
|
||||||
items[0] = false // notaryDisabled is false
|
items[0] = false // notaryDisabled is false
|
||||||
|
|
||||||
switch ctrName {
|
switch ctrName {
|
||||||
|
@ -551,7 +551,7 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an
|
||||||
c.Contracts[netmapContract].Hash,
|
c.Contracts[netmapContract].Hash,
|
||||||
c.Contracts[containerContract].Hash)
|
c.Contracts[containerContract].Hash)
|
||||||
case netmapContract:
|
case netmapContract:
|
||||||
configParam := []any{
|
configParam := []interface{}{
|
||||||
netmapEpochKey, viper.GetInt64(epochDurationInitFlag),
|
netmapEpochKey, viper.GetInt64(epochDurationInitFlag),
|
||||||
netmapMaxObjectSizeKey, viper.GetInt64(maxObjectSizeInitFlag),
|
netmapMaxObjectSizeKey, viper.GetInt64(maxObjectSizeInitFlag),
|
||||||
netmapAuditFeeKey, viper.GetInt64(auditFeeInitFlag),
|
netmapAuditFeeKey, viper.GetInt64(auditFeeInitFlag),
|
||||||
|
@ -580,8 +580,8 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getAlphabetDeployItems(i, n int) []any {
|
func (c *initializeContext) getAlphabetDeployItems(i, n int) []interface{} {
|
||||||
items := make([]any, 6)
|
items := make([]interface{}, 6)
|
||||||
items[0] = false
|
items[0] = false
|
||||||
items[1] = c.Contracts[netmapContract].Hash
|
items[1] = c.Contracts[netmapContract].Hash
|
||||||
items[2] = c.Contracts[proxyContract].Hash
|
items[2] = c.Contracts[proxyContract].Hash
|
||||||
|
|
|
@ -281,7 +281,7 @@ func nnsIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) {
|
||||||
case *rpcclient.Client:
|
case *rpcclient.Client:
|
||||||
return ct.NNSIsAvailable(nnsHash, name)
|
return ct.NNSIsAvailable(nnsHash, name)
|
||||||
default:
|
default:
|
||||||
b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
|
b, err := unwrap.Bool(invokeFunction(c, nnsHash, "isAvailable", []interface{}{name}, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("`isAvailable`: invalid response: %w", err)
|
return false, fmt.Errorf("`isAvailable`: invalid response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ func (c *initializeContext) setNotaryAndAlphabetNodes() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var pubs []any
|
var pubs []interface{}
|
||||||
for _, acc := range c.Accounts {
|
for _, acc := range c.Accounts {
|
||||||
pubs = append(pubs, acc.PrivateKey().PublicKey().Bytes())
|
pubs = append(pubs, acc.PrivateKey().PublicKey().Bytes())
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,6 @@ func TestInitialize(t *testing.T) {
|
||||||
// It is here for performing local testing after the changes.
|
// It is here for performing local testing after the changes.
|
||||||
t.Skip()
|
t.Skip()
|
||||||
|
|
||||||
t.Run("1 nodes", func(t *testing.T) {
|
|
||||||
testInitialize(t, 1)
|
|
||||||
})
|
|
||||||
t.Run("4 nodes", func(t *testing.T) {
|
t.Run("4 nodes", func(t *testing.T) {
|
||||||
testInitialize(t, 4)
|
testInitialize(t, 4)
|
||||||
})
|
})
|
||||||
|
@ -99,7 +96,6 @@ func generateTestData(t *testing.T, dir string, size int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := config.Config{}
|
cfg := config.Config{}
|
||||||
cfg.ProtocolConfiguration.Magic = 12345
|
|
||||||
cfg.ProtocolConfiguration.ValidatorsCount = size
|
cfg.ProtocolConfiguration.ValidatorsCount = size
|
||||||
cfg.ProtocolConfiguration.SecondsPerBlock = 1
|
cfg.ProtocolConfiguration.SecondsPerBlock = 1
|
||||||
cfg.ProtocolConfiguration.StandbyCommittee = pubs // sorted by glagolic letters
|
cfg.ProtocolConfiguration.StandbyCommittee = pubs // sorted by glagolic letters
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config"
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
||||||
|
@ -21,7 +20,6 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
"github.com/nspcc-dev/neo-go/pkg/neorpc/result"
|
||||||
|
@ -190,7 +188,7 @@ func (l *localClient) GetCommittee() (keys.PublicKeys, error) {
|
||||||
func (l *localClient) InvokeFunction(h util.Uint160, method string, sPrm []smartcontract.Parameter, ss []transaction.Signer) (*result.Invoke, error) {
|
func (l *localClient) InvokeFunction(h util.Uint160, method string, sPrm []smartcontract.Parameter, ss []transaction.Signer) (*result.Invoke, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
pp := make([]any, len(sPrm))
|
pp := make([]interface{}, len(sPrm))
|
||||||
for i, p := range sPrm {
|
for i, p := range sPrm {
|
||||||
pp[i], err = smartcontract.ExpandParameterToEmitable(p)
|
pp[i], err = smartcontract.ExpandParameterToEmitable(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -228,24 +226,7 @@ func (l *localClient) TraverseIterator(_, _ uuid.UUID, _ int) ([]stackitem.Item,
|
||||||
|
|
||||||
// GetVersion return default version.
|
// GetVersion return default version.
|
||||||
func (l *localClient) GetVersion() (*result.Version, error) {
|
func (l *localClient) GetVersion() (*result.Version, error) {
|
||||||
c := l.bc.GetConfig()
|
return &result.Version{}, nil
|
||||||
return &result.Version{
|
|
||||||
Protocol: result.Protocol{
|
|
||||||
AddressVersion: address.NEO3Prefix,
|
|
||||||
Network: c.Magic,
|
|
||||||
MillisecondsPerBlock: int(c.TimePerBlock / time.Millisecond),
|
|
||||||
MaxTraceableBlocks: c.MaxTraceableBlocks,
|
|
||||||
MaxValidUntilBlockIncrement: c.MaxValidUntilBlockIncrement,
|
|
||||||
MaxTransactionsPerBlock: c.MaxTransactionsPerBlock,
|
|
||||||
MemoryPoolMaxTransactions: c.MemPoolSize,
|
|
||||||
ValidatorsCount: byte(c.ValidatorsCount),
|
|
||||||
InitialGasDistribution: c.InitialGASSupply,
|
|
||||||
CommitteeHistory: c.CommitteeHistory,
|
|
||||||
P2PSigExtensions: c.P2PSigExtensions,
|
|
||||||
StateRootInHeader: c.StateRootInHeader,
|
|
||||||
ValidatorsHistory: c.ValidatorsHistory,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *localClient) InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
|
func (l *localClient) InvokeContractVerify(contract util.Uint160, params []smartcontract.Parameter, signers []transaction.Signer, witnesses ...transaction.Witness) (*result.Invoke, error) {
|
||||||
|
@ -346,7 +327,7 @@ func getSigners(sender *wallet.Account, cosigners []rpcclient.SignerAccount) ([]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *localClient) NEP17BalanceOf(h util.Uint160, acc util.Uint160) (int64, error) {
|
func (l *localClient) NEP17BalanceOf(h util.Uint160, acc util.Uint160) (int64, error) {
|
||||||
res, err := invokeFunction(l, h, "balanceOf", []any{acc}, nil)
|
res, err := invokeFunction(l, h, "balanceOf", []interface{}{acc}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -451,7 +432,7 @@ func (l *localClient) putTransactions() error {
|
||||||
return l.bc.AddBlock(b)
|
return l.bc.AddBlock(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func invokeFunction(c Client, h util.Uint160, method string, parameters []any, signers []transaction.Signer) (*result.Invoke, error) {
|
func invokeFunction(c Client, h util.Uint160, method string, parameters []interface{}, signers []transaction.Signer) (*result.Invoke, error) {
|
||||||
w := io.NewBufBinWriter()
|
w := io.NewBufBinWriter()
|
||||||
emit.Array(w.BinWriter, parameters...)
|
emit.Array(w.BinWriter, parameters...)
|
||||||
emit.AppCallNoArgs(w.BinWriter, h, method, callflag.All)
|
emit.AppCallNoArgs(w.BinWriter, h, method, callflag.All)
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
package morph
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
)
|
|
||||||
|
|
||||||
func listNetmapCandidatesNodes(cmd *cobra.Command, _ []string) {
|
|
||||||
c, err := getN3Client(viper.GetViper())
|
|
||||||
commonCmd.ExitOnErr(cmd, "can't create N3 client: %w", err)
|
|
||||||
|
|
||||||
inv := invoker.New(c, nil)
|
|
||||||
|
|
||||||
cs, err := c.GetContractStateByID(1)
|
|
||||||
commonCmd.ExitOnErr(cmd, "can't get NNS contract info: %w", err)
|
|
||||||
|
|
||||||
nmHash, err := nnsResolveHash(inv, cs.Hash, netmapContract+".frostfs")
|
|
||||||
commonCmd.ExitOnErr(cmd, "can't get netmap contract hash: %w", err)
|
|
||||||
|
|
||||||
res, err := inv.Call(nmHash, "netmapCandidates")
|
|
||||||
commonCmd.ExitOnErr(cmd, "can't fetch list of network config keys from the netmap contract", err)
|
|
||||||
nm, err := netmap.DecodeNetMap(res.Stack)
|
|
||||||
commonCmd.ExitOnErr(cmd, "unable to decode netmap: %w", err)
|
|
||||||
commonCmd.PrettyPrintNetMap(cmd, *nm, !viper.GetBool(commonflags.Verbose))
|
|
||||||
}
|
|
|
@ -111,7 +111,7 @@ func depositNotary(cmd *cobra.Command, _ []string) error {
|
||||||
accHash,
|
accHash,
|
||||||
notary.Hash,
|
notary.Hash,
|
||||||
big.NewInt(int64(gasAmount)),
|
big.NewInt(int64(gasAmount)),
|
||||||
[]any{nil, int64(height) + till},
|
[]interface{}{nil, int64(height) + till},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not send tx: %w", err)
|
return fmt.Errorf("could not send tx: %w", err)
|
||||||
|
|
|
@ -27,23 +27,23 @@ func setPolicyCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
for i := range args {
|
for i := range args {
|
||||||
k, v, found := strings.Cut(args[i], "=")
|
kv := strings.SplitN(args[i], "=", 2)
|
||||||
if !found {
|
if len(kv) != 2 {
|
||||||
return fmt.Errorf("invalid parameter format, must be Parameter=Value")
|
return fmt.Errorf("invalid parameter format, must be Parameter=Value")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch k {
|
switch kv[0] {
|
||||||
case execFeeParam, storagePriceParam, setFeeParam:
|
case execFeeParam, storagePriceParam, setFeeParam:
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("parameter must be one of %s, %s and %s", execFeeParam, storagePriceParam, setFeeParam)
|
return fmt.Errorf("parameter must be one of %s, %s and %s", execFeeParam, storagePriceParam, setFeeParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
value, err := strconv.ParseUint(v, 10, 32)
|
value, err := strconv.ParseUint(kv[1], 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't parse parameter value '%s': %w", args[1], err)
|
return fmt.Errorf("can't parse parameter value '%s': %w", args[1], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
emit.AppCall(bw.BinWriter, policy.Hash, "set"+k, callflag.All, int64(value))
|
emit.AppCall(bw.BinWriter, policy.Hash, "set"+kv[0], callflag.All, int64(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil {
|
if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil {
|
||||||
|
|
|
@ -108,7 +108,7 @@ var (
|
||||||
|
|
||||||
forceNewEpoch = &cobra.Command{
|
forceNewEpoch = &cobra.Command{
|
||||||
Use: "force-new-epoch",
|
Use: "force-new-epoch",
|
||||||
Short: "Create new FrostFS epoch event in the side chain",
|
Short: "Create new NeoFS epoch event in the side chain",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
|
@ -130,7 +130,7 @@ var (
|
||||||
setConfig = &cobra.Command{
|
setConfig = &cobra.Command{
|
||||||
Use: "set-config key1=val1 [key2=val2 ...]",
|
Use: "set-config key1=val1 [key2=val2 ...]",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Short: "Add/update global config value in the FrostFS network",
|
Short: "Add/update global config value in the NeoFS network",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
|
@ -164,7 +164,7 @@ var (
|
||||||
|
|
||||||
dumpNetworkConfigCmd = &cobra.Command{
|
dumpNetworkConfigCmd = &cobra.Command{
|
||||||
Use: "dump-config",
|
Use: "dump-config",
|
||||||
Short: "Dump FrostFS network config",
|
Short: "Dump NeoFS network config",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
},
|
},
|
||||||
|
@ -182,7 +182,7 @@ var (
|
||||||
|
|
||||||
updateContractsCmd = &cobra.Command{
|
updateContractsCmd = &cobra.Command{
|
||||||
Use: "update-contracts",
|
Use: "update-contracts",
|
||||||
Short: "Update FrostFS contracts",
|
Short: "Update NeoFS contracts",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
|
@ -192,7 +192,7 @@ var (
|
||||||
|
|
||||||
dumpContainersCmd = &cobra.Command{
|
dumpContainersCmd = &cobra.Command{
|
||||||
Use: "dump-containers",
|
Use: "dump-containers",
|
||||||
Short: "Dump FrostFS containers to file",
|
Short: "Dump NeoFS containers to file",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
},
|
},
|
||||||
|
@ -201,7 +201,7 @@ var (
|
||||||
|
|
||||||
restoreContainersCmd = &cobra.Command{
|
restoreContainersCmd = &cobra.Command{
|
||||||
Use: "restore-containers",
|
Use: "restore-containers",
|
||||||
Short: "Restore FrostFS containers from file",
|
Short: "Restore NeoFS containers from file",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
|
@ -211,7 +211,7 @@ var (
|
||||||
|
|
||||||
listContainersCmd = &cobra.Command{
|
listContainersCmd = &cobra.Command{
|
||||||
Use: "list-containers",
|
Use: "list-containers",
|
||||||
Short: "List FrostFS containers",
|
Short: "List NeoFS containers",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
},
|
},
|
||||||
|
@ -226,16 +226,6 @@ var (
|
||||||
},
|
},
|
||||||
RunE: depositNotary,
|
RunE: depositNotary,
|
||||||
}
|
}
|
||||||
|
|
||||||
netmapCandidatesCmd = &cobra.Command{
|
|
||||||
Use: "netmap-candidates",
|
|
||||||
Short: "List netmap candidates nodes",
|
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
|
||||||
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
|
||||||
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
|
||||||
},
|
|
||||||
Run: listNetmapCandidatesNodes,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -246,8 +236,8 @@ func init() {
|
||||||
RootCmd.AddCommand(initCmd)
|
RootCmd.AddCommand(initCmd)
|
||||||
initCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
initCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||||
initCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
initCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
initCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts (default fetched from latest github release)")
|
initCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled NeoFS contracts (default fetched from latest github release)")
|
||||||
initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one FrostFS epoch")
|
initCmd.Flags().Uint(epochDurationCLIFlag, 240, "Amount of side chain blocks in one NeoFS epoch")
|
||||||
initCmd.Flags().Uint(maxObjectSizeCLIFlag, 67108864, "Max single object size in bytes")
|
initCmd.Flags().Uint(maxObjectSizeCLIFlag, 67108864, "Max single object size in bytes")
|
||||||
initCmd.Flags().Bool(homomorphicHashDisabledCLIFlag, false, "Disable object homomorphic hashing")
|
initCmd.Flags().Bool(homomorphicHashDisabledCLIFlag, false, "Disable object homomorphic hashing")
|
||||||
// Defaults are taken from neo-preodolenie.
|
// Defaults are taken from neo-preodolenie.
|
||||||
|
@ -299,7 +289,7 @@ func init() {
|
||||||
RootCmd.AddCommand(updateContractsCmd)
|
RootCmd.AddCommand(updateContractsCmd)
|
||||||
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
updateContractsCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
|
||||||
updateContractsCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
updateContractsCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled FrostFS contracts (default fetched from latest github release)")
|
updateContractsCmd.Flags().String(contractsInitFlag, "", "Path to archive with compiled NeoFS contracts (default fetched from latest github release)")
|
||||||
|
|
||||||
RootCmd.AddCommand(dumpContainersCmd)
|
RootCmd.AddCommand(dumpContainersCmd)
|
||||||
dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
|
@ -333,7 +323,4 @@ func init() {
|
||||||
depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
|
depositNotaryCmd.Flags().String(walletAccountFlag, "", "Wallet account address")
|
||||||
depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit")
|
depositNotaryCmd.Flags().String(refillGasAmountFlag, "", "Amount of GAS to deposit")
|
||||||
depositNotaryCmd.Flags().String(notaryDepositTillFlag, "", "Notary deposit duration in blocks")
|
depositNotaryCmd.Flags().String(notaryDepositTillFlag, "", "Notary deposit duration in blocks")
|
||||||
|
|
||||||
RootCmd.AddCommand(netmapCandidatesCmd)
|
|
||||||
netmapCandidatesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ func viperBindFlags(cmd *cobra.Command, flags ...string) {
|
||||||
// subnet command section.
|
// subnet command section.
|
||||||
var cmdSubnet = &cobra.Command{
|
var cmdSubnet = &cobra.Command{
|
||||||
Use: "subnet",
|
Use: "subnet",
|
||||||
Short: "FrostFS subnet management",
|
Short: "NeoFS subnet management",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
endpointFlag,
|
endpointFlag,
|
||||||
|
@ -112,7 +112,7 @@ func readSubnetKey(key *keys.PrivateKey) error {
|
||||||
// create subnet command.
|
// create subnet command.
|
||||||
var cmdSubnetCreate = &cobra.Command{
|
var cmdSubnetCreate = &cobra.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create FrostFS subnet",
|
Short: "Create NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetWallet,
|
flagSubnetWallet,
|
||||||
|
@ -177,7 +177,7 @@ var errZeroSubnet = errors.New("zero subnet")
|
||||||
// remove subnet command.
|
// remove subnet command.
|
||||||
var cmdSubnetRemove = &cobra.Command{
|
var cmdSubnetRemove = &cobra.Command{
|
||||||
Use: "remove",
|
Use: "remove",
|
||||||
Short: "Remove FrostFS subnet",
|
Short: "Remove NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetWallet,
|
flagSubnetWallet,
|
||||||
|
@ -226,7 +226,7 @@ const (
|
||||||
// get subnet command.
|
// get subnet command.
|
||||||
var cmdSubnetGet = &cobra.Command{
|
var cmdSubnetGet = &cobra.Command{
|
||||||
Use: "get",
|
Use: "get",
|
||||||
Short: "Read information about the FrostFS subnet",
|
Short: "Read information about the NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetGetID,
|
flagSubnetGetID,
|
||||||
|
@ -290,7 +290,7 @@ const (
|
||||||
// command to manage subnet admins.
|
// command to manage subnet admins.
|
||||||
var cmdSubnetAdmin = &cobra.Command{
|
var cmdSubnetAdmin = &cobra.Command{
|
||||||
Use: "admin",
|
Use: "admin",
|
||||||
Short: "Manage administrators of the FrostFS subnet",
|
Short: "Manage administrators of the NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(cmd *cobra.Command, args []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetWallet,
|
flagSubnetWallet,
|
||||||
|
@ -340,7 +340,7 @@ func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare call parameters
|
// prepare call parameters
|
||||||
prm := make([]any, 0, 3)
|
prm := make([]interface{}, 0, 3)
|
||||||
prm = append(prm, id.Marshal())
|
prm = append(prm, id.Marshal())
|
||||||
|
|
||||||
var method string
|
var method string
|
||||||
|
@ -397,7 +397,7 @@ func manageSubnetAdmins(cmd *cobra.Command, rm bool) error {
|
||||||
// command to add subnet admin.
|
// command to add subnet admin.
|
||||||
var cmdSubnetAdminAdd = &cobra.Command{
|
var cmdSubnetAdminAdd = &cobra.Command{
|
||||||
Use: "add",
|
Use: "add",
|
||||||
Short: "Add admin to the FrostFS subnet",
|
Short: "Add admin to the NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetAdminAddGroup,
|
flagSubnetAdminAddGroup,
|
||||||
|
@ -412,7 +412,7 @@ var cmdSubnetAdminAdd = &cobra.Command{
|
||||||
// command to remove subnet admin.
|
// command to remove subnet admin.
|
||||||
var cmdSubnetAdminRemove = &cobra.Command{
|
var cmdSubnetAdminRemove = &cobra.Command{
|
||||||
Use: "remove",
|
Use: "remove",
|
||||||
Short: "Remove admin of the FrostFS subnet",
|
Short: "Remove admin of the NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetAdminClient,
|
flagSubnetAdminClient,
|
||||||
|
@ -433,7 +433,7 @@ const (
|
||||||
// command to manage subnet clients.
|
// command to manage subnet clients.
|
||||||
var cmdSubnetClient = &cobra.Command{
|
var cmdSubnetClient = &cobra.Command{
|
||||||
Use: "client",
|
Use: "client",
|
||||||
Short: "Manage clients of the FrostFS subnet",
|
Short: "Manage clients of the NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetWallet,
|
flagSubnetWallet,
|
||||||
|
@ -516,7 +516,7 @@ func manageSubnetClients(cmd *cobra.Command, rm bool) error {
|
||||||
// command to add subnet client.
|
// command to add subnet client.
|
||||||
var cmdSubnetClientAdd = &cobra.Command{
|
var cmdSubnetClientAdd = &cobra.Command{
|
||||||
Use: "add",
|
Use: "add",
|
||||||
Short: "Add client to the FrostFS subnet",
|
Short: "Add client to the NeoFS subnet",
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return manageSubnetClients(cmd, false)
|
return manageSubnetClients(cmd, false)
|
||||||
},
|
},
|
||||||
|
@ -525,7 +525,7 @@ var cmdSubnetClientAdd = &cobra.Command{
|
||||||
// command to remove subnet client.
|
// command to remove subnet client.
|
||||||
var cmdSubnetClientRemove = &cobra.Command{
|
var cmdSubnetClientRemove = &cobra.Command{
|
||||||
Use: "remove",
|
Use: "remove",
|
||||||
Short: "Remove client of the FrostFS subnet",
|
Short: "Remove client of the NeoFS subnet",
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return manageSubnetClients(cmd, true)
|
return manageSubnetClients(cmd, true)
|
||||||
},
|
},
|
||||||
|
@ -598,7 +598,7 @@ func manageSubnetNodes(cmd *cobra.Command, rm bool) error {
|
||||||
// command to manage subnet nodes.
|
// command to manage subnet nodes.
|
||||||
var cmdSubnetNode = &cobra.Command{
|
var cmdSubnetNode = &cobra.Command{
|
||||||
Use: "node",
|
Use: "node",
|
||||||
Short: "Manage nodes of the FrostFS subnet",
|
Short: "Manage nodes of the NeoFS subnet",
|
||||||
PreRun: func(cmd *cobra.Command, _ []string) {
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
viperBindFlags(cmd,
|
viperBindFlags(cmd,
|
||||||
flagSubnetWallet,
|
flagSubnetWallet,
|
||||||
|
@ -611,7 +611,7 @@ var cmdSubnetNode = &cobra.Command{
|
||||||
// command to add subnet node.
|
// command to add subnet node.
|
||||||
var cmdSubnetNodeAdd = &cobra.Command{
|
var cmdSubnetNodeAdd = &cobra.Command{
|
||||||
Use: "add",
|
Use: "add",
|
||||||
Short: "Add node to the FrostFS subnet",
|
Short: "Add node to the NeoFS subnet",
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return manageSubnetNodes(cmd, false)
|
return manageSubnetNodes(cmd, false)
|
||||||
},
|
},
|
||||||
|
@ -620,7 +620,7 @@ var cmdSubnetNodeAdd = &cobra.Command{
|
||||||
// command to remove subnet node.
|
// command to remove subnet node.
|
||||||
var cmdSubnetNodeRemove = &cobra.Command{
|
var cmdSubnetNodeRemove = &cobra.Command{
|
||||||
Use: "remove",
|
Use: "remove",
|
||||||
Short: "Remove node from the FrostFS subnet",
|
Short: "Remove node from the NeoFS subnet",
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return manageSubnetNodes(cmd, true)
|
return manageSubnetNodes(cmd, true)
|
||||||
},
|
},
|
||||||
|
@ -693,7 +693,7 @@ func init() {
|
||||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientSubnet)
|
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientSubnet)
|
||||||
clientFlags.String(flagSubnetClientGroup, "", "ID of the client group to work with")
|
clientFlags.String(flagSubnetClientGroup, "", "ID of the client group to work with")
|
||||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientGroup)
|
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientGroup)
|
||||||
clientFlags.String(flagSubnetClientID, "", "Client's user ID in FrostFS system in text format")
|
clientFlags.String(flagSubnetClientID, "", "Client's user ID in NeoFS system in text format")
|
||||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientID)
|
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetClientID)
|
||||||
clientFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
clientFlags.StringP(flagSubnetWallet, "w", "", "Path to file with wallet")
|
||||||
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetWallet)
|
_ = cmdSubnetClient.MarkFlagRequired(flagSubnetWallet)
|
||||||
|
@ -742,7 +742,7 @@ func init() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInvokeMethod(key keys.PrivateKey, method string, args ...any) ([]stackitem.Item, error) {
|
func testInvokeMethod(key keys.PrivateKey, method string, args ...interface{}) ([]stackitem.Item, error) {
|
||||||
c, err := getN3Client(viper.GetViper())
|
c, err := getN3Client(viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("morph client creation: %w", err)
|
return nil, fmt.Errorf("morph client creation: %w", err)
|
||||||
|
@ -780,7 +780,7 @@ func testInvokeMethod(key keys.PrivateKey, method string, args ...any) ([]stacki
|
||||||
return res.Stack, nil
|
return res.Stack, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func invokeMethod(key keys.PrivateKey, tryNotary bool, method string, args ...any) error {
|
func invokeMethod(key keys.PrivateKey, tryNotary bool, method string, args ...interface{}) error {
|
||||||
c, err := getN3Client(viper.GetViper())
|
c, err := getN3Client(viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("morph client creation: %w", err)
|
return fmt.Errorf("morph client creation: %w", err)
|
||||||
|
@ -821,7 +821,7 @@ func invokeMethod(key keys.PrivateKey, tryNotary bool, method string, args ...an
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...any) error {
|
func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...interface{}) error {
|
||||||
nnsCs, err := c.GetContractStateByID(1)
|
nnsCs, err := c.GetContractStateByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("NNS contract resolving: %w", err)
|
return fmt.Errorf("NNS contract resolving: %w", err)
|
||||||
|
@ -868,7 +868,7 @@ func invokeNonNotary(c Client, key keys.PrivateKey, method string, args ...any)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.Uint160, args ...any) error {
|
func invokeNotary(c Client, key keys.PrivateKey, method string, notaryHash util.Uint160, args ...interface{}) error {
|
||||||
nnsCs, err := c.GetContractStateByID(1)
|
nnsCs, err := c.GetContractStateByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("NNS contract resolving: %w", err)
|
return fmt.Errorf("NNS contract resolving: %w", err)
|
||||||
|
|
|
@ -3,13 +3,11 @@ package modules
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/storagecfg"
|
||||||
"github.com/TrueCloudLab/frostfs-node/misc"
|
"github.com/TrueCloudLab/frostfs-node/misc"
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/autocomplete"
|
||||||
utilConfig "github.com/TrueCloudLab/frostfs-node/pkg/util/config"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -18,12 +16,14 @@ import (
|
||||||
var (
|
var (
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "frostfs-adm",
|
Use: "frostfs-adm",
|
||||||
Short: "FrostFS Administrative Tool",
|
Short: "NeoFS Administrative Tool",
|
||||||
Long: `FrostFS Administrative Tool provides functions to setup and
|
Long: `NeoFS Administrative Tool provides functions to setup and
|
||||||
manage FrostFS network deployment.`,
|
manage NeoFS network deployment.`,
|
||||||
RunE: entryPoint,
|
RunE: entryPoint,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configFlag = "config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -34,10 +34,7 @@ func init() {
|
||||||
// use stdout as default output for cmd.Print()
|
// use stdout as default output for cmd.Print()
|
||||||
rootCmd.SetOut(os.Stdout)
|
rootCmd.SetOut(os.Stdout)
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringP(commonflags.ConfigFlag, commonflags.ConfigFlagShorthand, "", commonflags.ConfigFlagUsage)
|
rootCmd.PersistentFlags().StringP(configFlag, "c", "", "Config file")
|
||||||
rootCmd.PersistentFlags().String(commonflags.ConfigDirFlag, "", commonflags.ConfigDirFlagUsage)
|
|
||||||
rootCmd.PersistentFlags().BoolP(commonflags.Verbose, commonflags.VerboseShorthand, false, commonflags.VerboseUsage)
|
|
||||||
_ = viper.BindPFlag(commonflags.Verbose, rootCmd.PersistentFlags().Lookup(commonflags.Verbose))
|
|
||||||
rootCmd.Flags().Bool("version", false, "Application version")
|
rootCmd.Flags().Bool("version", false, "Application version")
|
||||||
|
|
||||||
rootCmd.AddCommand(config.RootCmd)
|
rootCmd.AddCommand(config.RootCmd)
|
||||||
|
@ -55,7 +52,7 @@ func Execute() error {
|
||||||
func entryPoint(cmd *cobra.Command, args []string) error {
|
func entryPoint(cmd *cobra.Command, args []string) error {
|
||||||
printVersion, _ := cmd.Flags().GetBool("version")
|
printVersion, _ := cmd.Flags().GetBool("version")
|
||||||
if printVersion {
|
if printVersion {
|
||||||
cmd.Print(misc.BuildInfo("FrostFS Adm"))
|
cmd.Print(misc.BuildInfo("NeoFS Adm"))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,23 +60,12 @@ func entryPoint(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig(cmd *cobra.Command) {
|
func initConfig(cmd *cobra.Command) {
|
||||||
configFile, err := cmd.Flags().GetString(commonflags.ConfigFlag)
|
configFile, err := cmd.Flags().GetString(configFlag)
|
||||||
if err != nil {
|
if err != nil || configFile == "" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if configFile != "" {
|
viper.SetConfigType("yml")
|
||||||
viper.SetConfigType("yml")
|
viper.SetConfigFile(configFile)
|
||||||
viper.SetConfigFile(configFile)
|
_ = viper.ReadInConfig() // if config file is set but unavailable, ignore it
|
||||||
_ = viper.ReadInConfig() // if config file is set but unavailable, ignore it
|
|
||||||
}
|
|
||||||
|
|
||||||
configDir, err := cmd.Flags().GetString(commonflags.ConfigDirFlag)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if configDir != "" {
|
|
||||||
_ = utilConfig.ReadConfigDir(viper.GetViper(), configDir) // if config files cannot be read, ignore it
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ node:
|
||||||
relay: {{ .Relay }} # start Storage node in relay mode without bootstrapping into the Network map
|
relay: {{ .Relay }} # start Storage node in relay mode without bootstrapping into the Network map
|
||||||
subnet:
|
subnet:
|
||||||
exit_zero: false # toggle entrance to zero subnet (overrides corresponding attribute and occurrence in entries)
|
exit_zero: false # toggle entrance to zero subnet (overrides corresponding attribute and occurrence in entries)
|
||||||
entries: [] # list of IDs of subnets to enter in a text format of FrostFS API protocol (overrides corresponding attributes)
|
entries: [] # list of IDs of subnets to enter in a text format of NeoFS API protocol (overrides corresponding attributes)
|
||||||
|
|
||||||
grpc:
|
grpc:
|
||||||
num: 1 # total number of listener endpoints
|
num: 1 # total number of listener endpoints
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# How FrostFS CLI uses session mechanism of the FrostFS
|
# How NeoFS CLI uses session mechanism of the NeoFS
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
FrostFS sessions implement a mechanism for issuing a power of attorney by one
|
NeoFS sessions implement a mechanism for issuing a power of attorney by one
|
||||||
party to another. A trusted party can provide a so-called session token as
|
party to another. A trusted party can provide a so-called session token as
|
||||||
proof of the right to act on behalf of another member of the network. The
|
proof of the right to act on behalf of another member of the network. The
|
||||||
client of operations carried out with such a token will be the user who opened
|
client of operations carried out with such a token will be the user who opened
|
||||||
|
@ -15,7 +15,7 @@ attached session token is treated as performed by the original client.
|
||||||
|
|
||||||
## Types
|
## Types
|
||||||
|
|
||||||
FrostFS CLI supports two ways to execute operation within a session depending on
|
NeoFS CLI supports two ways to execute operation within a session depending on
|
||||||
whether the user of the command application is an original user (1) or a trusted
|
whether the user of the command application is an original user (1) or a trusted
|
||||||
one (2).
|
one (2).
|
||||||
|
|
||||||
|
|
|
@ -2,26 +2,26 @@
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Extended headers are used for request/response. They may contain any
|
Extended headers are used for request/response. They may contain any user-defined headers
|
||||||
user-defined headers to be interpreted on application level. Key name must be a
|
to be interpreted on application level.
|
||||||
unique valid UTF-8 string. Value can't be empty. Requests or Responses with
|
Key name must be a unique valid UTF-8 string. Value can't be empty. Requests or
|
||||||
duplicated header names or headers with empty values are considered invalid.
|
Responses with duplicated header names or headers with empty values are
|
||||||
|
considered invalid.
|
||||||
|
|
||||||
## Existing headers
|
## Existing headers
|
||||||
|
|
||||||
There are some "well-known" headers starting with `__FROSTFS__` prefix that
|
There are some "well-known" headers starting with `__NEOFS__` prefix that
|
||||||
affect system behaviour. For backward compatibility, the same set of
|
affect system behaviour:
|
||||||
"well-known" headers may also use `__NEOFS__` prefix:
|
|
||||||
|
|
||||||
* `__FROSTFS__NETMAP_EPOCH` - netmap epoch to use for object placement calculation. The `value` is string
|
* `__NEOFS__NETMAP_EPOCH` - netmap epoch to use for object placement calculation. The `value` is string
|
||||||
encoded `uint64` in decimal presentation. If set to '0' or omitted, the
|
encoded `uint64` in decimal presentation. If set to '0' or omitted, the
|
||||||
current epoch only will be used.
|
current epoch only will be used.
|
||||||
* `__FROSTFS__NETMAP_LOOKUP_DEPTH` - if object can't be found using current epoch's netmap, this header limits
|
* `__NEOFS__NETMAP_LOOKUP_DEPTH` - if object can't be found using current epoch's netmap, this header limits
|
||||||
how many past epochs the node can look up through. Depth is applied to a current epoch or the value
|
how many past epochs the node can look up through. Depth is applied to a current epoch or the value
|
||||||
of `__FROSTFS__NETMAP_EPOCH` attribute. The `value` is string encoded `uint64` in decimal presentation.
|
of `__NEOFS__NETMAP_EPOCH` attribute. The `value` is string encoded `uint64` in decimal presentation.
|
||||||
If set to '0' or not set, only the current epoch is used.
|
If set to '0' or not set, only the current epoch is used.
|
||||||
|
|
||||||
## `frostfs-cli` commands with `--xhdr`
|
## `neofs-cli` commands with `--xhdr`
|
||||||
|
|
||||||
List of commands with support of extended headers:
|
List of commands with support of extended headers:
|
||||||
* `container list-objects`
|
* `container list-objects`
|
||||||
|
@ -30,5 +30,5 @@ List of commands with support of extended headers:
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```shell
|
```shell
|
||||||
$ frostfs-cli object put -r s01.frostfs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__FROSTFS__NETMAP_EPOCH=777"
|
$ neofs-cli object put -r s01.neofs.devenv:8080 -w wallet.json --cid CID --file FILE --xhdr "__NEOFS__NETMAP_EPOCH=777"
|
||||||
```
|
```
|
||||||
|
|
|
@ -34,7 +34,7 @@ func (x BalanceOfRes) Balance() accounting.Decimal {
|
||||||
return x.cliRes.Amount()
|
return x.cliRes.Amount()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BalanceOf requests the current balance of a FrostFS user.
|
// BalanceOf requests the current balance of a NeoFS user.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func BalanceOf(prm BalanceOfPrm) (res BalanceOfRes, err error) {
|
func BalanceOf(prm BalanceOfPrm) (res BalanceOfRes, err error) {
|
||||||
|
@ -59,7 +59,7 @@ func (x ListContainersRes) IDList() []cid.ID {
|
||||||
return x.cliRes.Containers()
|
return x.cliRes.Containers()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListContainers requests a list of FrostFS user's containers.
|
// ListContainers requests a list of NeoFS user's containers.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func ListContainers(prm ListContainersPrm) (res ListContainersRes, err error) {
|
func ListContainers(prm ListContainersPrm) (res ListContainersRes, err error) {
|
||||||
|
@ -84,7 +84,7 @@ func (x PutContainerRes) ID() cid.ID {
|
||||||
return x.cnr
|
return x.cnr
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutContainer sends a request to save the container in FrostFS.
|
// PutContainer sends a request to save the container in NeoFS.
|
||||||
//
|
//
|
||||||
// Operation is asynchronous and not guaranteed even in the absence of errors.
|
// Operation is asynchronous and not guaranteed even in the absence of errors.
|
||||||
// The required time is also not predictable.
|
// The required time is also not predictable.
|
||||||
|
@ -122,7 +122,7 @@ func (x GetContainerRes) Container() containerSDK.Container {
|
||||||
return x.cliRes.Container()
|
return x.cliRes.Container()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContainer reads a container from FrostFS by ID.
|
// GetContainer reads a container from NeoFS by ID.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func GetContainer(prm GetContainerPrm) (res GetContainerRes, err error) {
|
func GetContainer(prm GetContainerPrm) (res GetContainerRes, err error) {
|
||||||
|
@ -140,7 +140,7 @@ func IsACLExtendable(c *client.Client, cnr cid.ID) (bool, error) {
|
||||||
|
|
||||||
res, err := GetContainer(prm)
|
res, err := GetContainer(prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, fmt.Errorf("get container from the FrostFS: %w", err)
|
return false, fmt.Errorf("get container from the NeoFS: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.Container().BasicACL().Extendable(), nil
|
return res.Container().BasicACL().Extendable(), nil
|
||||||
|
@ -155,7 +155,7 @@ type DeleteContainerPrm struct {
|
||||||
// DeleteContainerRes groups the resulting values of DeleteContainer operation.
|
// DeleteContainerRes groups the resulting values of DeleteContainer operation.
|
||||||
type DeleteContainerRes struct{}
|
type DeleteContainerRes struct{}
|
||||||
|
|
||||||
// DeleteContainer sends a request to remove a container from FrostFS by ID.
|
// DeleteContainer sends a request to remove a container from NeoFS by ID.
|
||||||
//
|
//
|
||||||
// Operation is asynchronous and not guaranteed even in the absence of errors.
|
// Operation is asynchronous and not guaranteed even in the absence of errors.
|
||||||
// The required time is also not predictable.
|
// The required time is also not predictable.
|
||||||
|
@ -185,7 +185,7 @@ func (x EACLRes) EACL() eacl.Table {
|
||||||
return x.cliRes.Table()
|
return x.cliRes.Table()
|
||||||
}
|
}
|
||||||
|
|
||||||
// EACL reads eACL table from FrostFS by container ID.
|
// EACL reads eACL table from NeoFS by container ID.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func EACL(prm EACLPrm) (res EACLRes, err error) {
|
func EACL(prm EACLPrm) (res EACLRes, err error) {
|
||||||
|
@ -203,7 +203,7 @@ type SetEACLPrm struct {
|
||||||
// SetEACLRes groups the resulting values of SetEACL operation.
|
// SetEACLRes groups the resulting values of SetEACL operation.
|
||||||
type SetEACLRes struct{}
|
type SetEACLRes struct{}
|
||||||
|
|
||||||
// SetEACL requests to save an eACL table in FrostFS.
|
// SetEACL requests to save an eACL table in NeoFS.
|
||||||
//
|
//
|
||||||
// Operation is asynchronous and no guaranteed even in the absence of errors.
|
// Operation is asynchronous and no guaranteed even in the absence of errors.
|
||||||
// The required time is also not predictable.
|
// The required time is also not predictable.
|
||||||
|
@ -228,12 +228,12 @@ type NetworkInfoRes struct {
|
||||||
cliRes *client.ResNetworkInfo
|
cliRes *client.ResNetworkInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkInfo returns structured information about the FrostFS network.
|
// NetworkInfo returns structured information about the NeoFS network.
|
||||||
func (x NetworkInfoRes) NetworkInfo() netmap.NetworkInfo {
|
func (x NetworkInfoRes) NetworkInfo() netmap.NetworkInfo {
|
||||||
return x.cliRes.Info()
|
return x.cliRes.Info()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetworkInfo reads information about the FrostFS network.
|
// NetworkInfo reads information about the NeoFS network.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func NetworkInfo(prm NetworkInfoPrm) (res NetworkInfoRes, err error) {
|
func NetworkInfo(prm NetworkInfoPrm) (res NetworkInfoRes, err error) {
|
||||||
|
@ -258,12 +258,12 @@ func (x NodeInfoRes) NodeInfo() netmap.NodeInfo {
|
||||||
return x.cliRes.NodeInfo()
|
return x.cliRes.NodeInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// LatestVersion returns the latest FrostFS API version in use.
|
// LatestVersion returns the latest NeoFS API version in use.
|
||||||
func (x NodeInfoRes) LatestVersion() version.Version {
|
func (x NodeInfoRes) LatestVersion() version.Version {
|
||||||
return x.cliRes.LatestVersion()
|
return x.cliRes.LatestVersion()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeInfo requests information about the remote server from FrostFS netmap.
|
// NodeInfo requests information about the remote server from NeoFS netmap.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func NodeInfo(prm NodeInfoPrm) (res NodeInfoRes, err error) {
|
func NodeInfo(prm NodeInfoPrm) (res NodeInfoRes, err error) {
|
||||||
|
@ -282,7 +282,7 @@ type NetMapSnapshotRes struct {
|
||||||
cliRes *client.ResNetMapSnapshot
|
cliRes *client.ResNetMapSnapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
// NetMap returns current local snapshot of the FrostFS network map.
|
// NetMap returns current local snapshot of the NeoFS network map.
|
||||||
func (x NetMapSnapshotRes) NetMap() netmap.NetMap {
|
func (x NetMapSnapshotRes) NetMap() netmap.NetMap {
|
||||||
return x.cliRes.NetMap()
|
return x.cliRes.NetMap()
|
||||||
}
|
}
|
||||||
|
@ -362,7 +362,7 @@ func (x PutObjectRes) ID() oid.ID {
|
||||||
return x.id
|
return x.id
|
||||||
}
|
}
|
||||||
|
|
||||||
// PutObject saves the object in FrostFS network.
|
// PutObject saves the object in NeoFS network.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func PutObject(prm PutObjectPrm) (*PutObjectRes, error) {
|
func PutObject(prm PutObjectPrm) (*PutObjectRes, error) {
|
||||||
|
@ -404,7 +404,8 @@ func PutObject(prm PutObjectPrm) (*PutObjectRes, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if prm.rdr != nil {
|
if prm.rdr != nil {
|
||||||
const defaultBufferSizePut = 3 << 20 // Maximum chunk size is 3 MiB in the SDK.
|
// TODO: (neofs-node#1198) explore better values or configure it
|
||||||
|
const defaultBufferSizePut = 4096
|
||||||
|
|
||||||
if sz == 0 || sz > defaultBufferSizePut {
|
if sz == 0 || sz > defaultBufferSizePut {
|
||||||
sz = defaultBufferSizePut
|
sz = defaultBufferSizePut
|
||||||
|
@ -459,7 +460,7 @@ func (x DeleteObjectRes) Tombstone() oid.ID {
|
||||||
return x.tomb
|
return x.tomb
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteObject marks an object to be removed from FrostFS through tombstone placement.
|
// DeleteObject marks an object to be removed from NeoFS through tombstone placement.
|
||||||
//
|
//
|
||||||
// Returns any error which prevented the operation from completing correctly in error return.
|
// Returns any error which prevented the operation from completing correctly in error return.
|
||||||
func DeleteObject(prm DeleteObjectPrm) (*DeleteObjectRes, error) {
|
func DeleteObject(prm DeleteObjectPrm) (*DeleteObjectRes, error) {
|
||||||
|
@ -575,7 +576,7 @@ type HeadObjectPrm struct {
|
||||||
mainOnly bool
|
mainOnly bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMainOnlyFlag sets flag to get only main fields of an object header in terms of FrostFS API.
|
// SetMainOnlyFlag sets flag to get only main fields of an object header in terms of NeoFS API.
|
||||||
func (x *HeadObjectPrm) SetMainOnlyFlag(v bool) {
|
func (x *HeadObjectPrm) SetMainOnlyFlag(v bool) {
|
||||||
x.mainOnly = v
|
x.mainOnly = v
|
||||||
}
|
}
|
||||||
|
@ -811,7 +812,7 @@ func (x *PayloadRangePrm) SetRange(rng *object.Range) {
|
||||||
// PayloadRangeRes groups the resulting values of PayloadRange operation.
|
// PayloadRangeRes groups the resulting values of PayloadRange operation.
|
||||||
type PayloadRangeRes struct{}
|
type PayloadRangeRes struct{}
|
||||||
|
|
||||||
// PayloadRange reads object payload range from FrostFS and writes it to the specified writer.
|
// PayloadRange reads object payload range from NeoFS and writes it to the specified writer.
|
||||||
//
|
//
|
||||||
// Interrupts on any writer error.
|
// Interrupts on any writer error.
|
||||||
//
|
//
|
||||||
|
@ -871,7 +872,7 @@ func (s *SyncContainerPrm) SetContainer(c *containerSDK.Container) {
|
||||||
// operation.
|
// operation.
|
||||||
type SyncContainerRes struct{}
|
type SyncContainerRes struct{}
|
||||||
|
|
||||||
// SyncContainerSettings reads global network config from FrostFS and
|
// SyncContainerSettings reads global network config from NeoFS and
|
||||||
// syncs container settings with it.
|
// syncs container settings with it.
|
||||||
//
|
//
|
||||||
// Interrupts on any writer error.
|
// Interrupts on any writer error.
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
// Package internal provides functionality for FrostFS CLI application
|
// Package internal provides functionality for NeoFS CLI application communication with NeoFS network.
|
||||||
// communication with FrostFS network.
|
|
||||||
//
|
//
|
||||||
// The base client for accessing remote nodes via FrostFS API is a FrostFS SDK
|
// The base client for accessing remote nodes via NeoFS API is a NeoFS SDK Go API client.
|
||||||
// Go API client. However, although it encapsulates a useful piece of business
|
// However, although it encapsulates a useful piece of business logic (e.g. the signature mechanism),
|
||||||
// logic (e.g. the signature mechanism), the FrostFS CLI application does not
|
// the NeoFS CLI application does not fully use the client's flexible interface.
|
||||||
// fully use the client's flexible interface.
|
|
||||||
//
|
//
|
||||||
// In this regard, this package provides functions over base API client
|
// In this regard, this package provides functions over base API client necessary for the application.
|
||||||
// necessary for the application. This allows you to concentrate the entire
|
// This allows you to concentrate the entire spectrum of the client's use in one place (this will be convenient
|
||||||
// spectrum of the client's use in one place (this will be convenient both when
|
// both when updating the base client and for evaluating the UX of SDK library). So it is expected that all
|
||||||
// updating the base client and for evaluating the UX of SDK library). So it is
|
// application packages will be limited to this package for the development of functionality requiring
|
||||||
// expected that all application packages will be limited to this package for
|
// NeoFS API communication.
|
||||||
// the development of functionality requiring FrostFS API communication.
|
|
||||||
package internal
|
package internal
|
||||||
|
|
|
@ -16,7 +16,7 @@ type commonPrm struct {
|
||||||
cli *client.Client
|
cli *client.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetClient sets the base client for FrostFS API communication.
|
// SetClient sets the base client for NeoFS API communication.
|
||||||
func (x *commonPrm) SetClient(cli *client.Client) {
|
func (x *commonPrm) SetClient(cli *client.Client) {
|
||||||
x.cli = cli
|
x.cli = cli
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -24,7 +23,7 @@ var errInvalidEndpoint = errors.New("provided RPC endpoint is incorrect")
|
||||||
func GetSDKClientByFlag(cmd *cobra.Command, key *ecdsa.PrivateKey, endpointFlag string) *client.Client {
|
func GetSDKClientByFlag(cmd *cobra.Command, key *ecdsa.PrivateKey, endpointFlag string) *client.Client {
|
||||||
cli, err := getSDKClientByFlag(cmd, key, endpointFlag)
|
cli, err := getSDKClientByFlag(cmd, key, endpointFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
commonCmd.ExitOnErr(cmd, "can't create API client: %w", err)
|
common.ExitOnErr(cmd, "can't create API client: %w", err)
|
||||||
}
|
}
|
||||||
return cli
|
return cli
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/core/version"
|
"github.com/TrueCloudLab/frostfs-node/pkg/core/version"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
versionSDK "github.com/TrueCloudLab/frostfs-sdk-go/version"
|
versionSDK "github.com/TrueCloudLab/frostfs-sdk-go/version"
|
||||||
|
@ -17,13 +16,13 @@ var errUnsupportedEACLFormat = errors.New("unsupported eACL format")
|
||||||
func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table {
|
func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table {
|
||||||
_, err := os.Stat(eaclPath) // check if `eaclPath` is an existing file
|
_, err := os.Stat(eaclPath) // check if `eaclPath` is an existing file
|
||||||
if err != nil {
|
if err != nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("incorrect path to file with EACL"))
|
ExitOnErr(cmd, "", errors.New("incorrect path to file with EACL"))
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintVerbose(cmd, "Reading EACL from file: %s", eaclPath)
|
PrintVerbose(cmd, "Reading EACL from file: %s", eaclPath)
|
||||||
|
|
||||||
data, err := os.ReadFile(eaclPath)
|
data, err := os.ReadFile(eaclPath)
|
||||||
commonCmd.ExitOnErr(cmd, "can't read file with EACL: %w", err)
|
ExitOnErr(cmd, "can't read file with EACL: %w", err)
|
||||||
|
|
||||||
table := eacl.NewTable()
|
table := eacl.NewTable()
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table {
|
||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "", errUnsupportedEACLFormat)
|
ExitOnErr(cmd, "", errUnsupportedEACLFormat)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,11 +39,11 @@ func PrettyPrintNodeInfo(cmd *cobra.Command, node netmap.NodeInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrettyPrintNetMap print information about network map.
|
// PrettyPrintNetMap print information about network map.
|
||||||
func PrettyPrintNetMap(cmd *cobra.Command, nm netmap.NetMap, short bool) {
|
func PrettyPrintNetMap(cmd *cobra.Command, nm netmap.NetMap) {
|
||||||
cmd.Println("Epoch:", nm.Epoch())
|
cmd.Println("Epoch:", nm.Epoch())
|
||||||
|
|
||||||
nodes := nm.Nodes()
|
nodes := nm.Nodes()
|
||||||
for i := range nodes {
|
for i := range nodes {
|
||||||
PrettyPrintNodeInfo(cmd, nodes[i], i, "", short)
|
PrettyPrintNodeInfo(cmd, nodes[i], i, "", false)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -14,7 +13,7 @@ import (
|
||||||
// ReadBearerToken reads bearer token from the path provided in a specified flag.
|
// ReadBearerToken reads bearer token from the path provided in a specified flag.
|
||||||
func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token {
|
func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token {
|
||||||
path, err := cmd.Flags().GetString(flagname)
|
path, err := cmd.Flags().GetString(flagname)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -25,13 +24,13 @@ func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token {
|
||||||
var tok bearer.Token
|
var tok bearer.Token
|
||||||
|
|
||||||
err = ReadBinaryOrJSON(cmd, &tok, path)
|
err = ReadBinaryOrJSON(cmd, &tok, path)
|
||||||
commonCmd.ExitOnErr(cmd, "invalid bearer token: %v", err)
|
ExitOnErr(cmd, "invalid bearer token: %v", err)
|
||||||
|
|
||||||
return &tok
|
return &tok
|
||||||
}
|
}
|
||||||
|
|
||||||
// BinaryOrJSON is an interface of entities which provide json.Unmarshaler
|
// BinaryOrJSON is an interface of entities which provide json.Unmarshaler
|
||||||
// and FrostFS binary decoder.
|
// and NeoFS binary decoder.
|
||||||
type BinaryOrJSON interface {
|
type BinaryOrJSON interface {
|
||||||
Unmarshal([]byte) error
|
Unmarshal([]byte) error
|
||||||
json.Unmarshaler
|
json.Unmarshaler
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrintVerbose prints to the stdout if the commonflags.Verbose flag is on.
|
// PrintVerbose prints to the stdout if the commonflags.Verbose flag is on.
|
||||||
func PrintVerbose(cmd *cobra.Command, format string, a ...any) {
|
func PrintVerbose(cmd *cobra.Command, format string, a ...interface{}) {
|
||||||
if viper.GetBool(commonflags.Verbose) {
|
if viper.GetBool(commonflags.Verbose) {
|
||||||
cmd.Printf(format+"\n", a...)
|
cmd.Printf(format+"\n", a...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
|
|
||||||
const SessionToken = "session"
|
const SessionToken = "session"
|
||||||
|
|
||||||
// InitSession registers SessionToken flag representing file path to the token of
|
// InitSession registers SessionToken flag representing filepath to the token
|
||||||
// the session with the given name. Supports FrostFS-binary and JSON files.
|
// of the session with the given name. Supports NeoFS-binary and JSON files.
|
||||||
func InitSession(cmd *cobra.Command, name string) {
|
func InitSession(cmd *cobra.Command, name string) {
|
||||||
cmd.Flags().String(
|
cmd.Flags().String(
|
||||||
SessionToken,
|
SessionToken,
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -21,7 +21,7 @@ var errCantGenerateKey = errors.New("can't generate new private key")
|
||||||
// This function assumes that all flags were bind to viper in a `PersistentPreRun`.
|
// This function assumes that all flags were bind to viper in a `PersistentPreRun`.
|
||||||
func Get(cmd *cobra.Command) *ecdsa.PrivateKey {
|
func Get(cmd *cobra.Command) *ecdsa.PrivateKey {
|
||||||
pk, err := get(cmd)
|
pk, err := get(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "can't fetch private key: %w", err)
|
common.ExitOnErr(cmd, "can't fetch private key: %w", err)
|
||||||
return pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ func get(cmd *cobra.Command) (*ecdsa.PrivateKey, error) {
|
||||||
// GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set.
|
// GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set.
|
||||||
func GetOrGenerate(cmd *cobra.Command) *ecdsa.PrivateKey {
|
func GetOrGenerate(cmd *cobra.Command) *ecdsa.PrivateKey {
|
||||||
pk, err := getOrGenerate(cmd)
|
pk, err := getOrGenerate(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "can't fetch private key: %w", err)
|
common.ExitOnErr(cmd, "can't fetch private key: %w", err)
|
||||||
return pk
|
return pk
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/precision"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/precision"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/accounting"
|
"github.com/TrueCloudLab/frostfs-sdk-go/accounting"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
|
@ -21,8 +21,8 @@ const (
|
||||||
|
|
||||||
var accountingBalanceCmd = &cobra.Command{
|
var accountingBalanceCmd = &cobra.Command{
|
||||||
Use: "balance",
|
Use: "balance",
|
||||||
Short: "Get internal balance of FrostFS account",
|
Short: "Get internal balance of NeoFS account",
|
||||||
Long: `Get internal balance of FrostFS account`,
|
Long: `Get internal balance of NeoFS account`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
var idUser user.ID
|
var idUser user.ID
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ var accountingBalanceCmd = &cobra.Command{
|
||||||
if balanceOwner == "" {
|
if balanceOwner == "" {
|
||||||
user.IDFromKey(&idUser, pk.PublicKey)
|
user.IDFromKey(&idUser, pk.PublicKey)
|
||||||
} else {
|
} else {
|
||||||
commonCmd.ExitOnErr(cmd, "can't decode owner ID wallet address: %w", idUser.DecodeString(balanceOwner))
|
common.ExitOnErr(cmd, "can't decode owner ID wallet address: %w", idUser.DecodeString(balanceOwner))
|
||||||
}
|
}
|
||||||
|
|
||||||
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
|
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
|
||||||
|
@ -42,7 +42,7 @@ var accountingBalanceCmd = &cobra.Command{
|
||||||
prm.SetAccount(idUser)
|
prm.SetAccount(idUser)
|
||||||
|
|
||||||
res, err := internalclient.BalanceOf(prm)
|
res, err := internalclient.BalanceOf(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
// print to stdout
|
// print to stdout
|
||||||
prettyPrintDecimal(cmd, res.Balance())
|
prettyPrintDecimal(cmd, res.Balance())
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package basic
|
package basic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -23,6 +23,6 @@ InnerRing members are allowed to data audit ops only:
|
||||||
|
|
||||||
func printACL(cmd *cobra.Command, args []string) {
|
func printACL(cmd *cobra.Command, args []string) {
|
||||||
var bacl acl.Basic
|
var bacl acl.Basic
|
||||||
commonCmd.ExitOnErr(cmd, "unable to parse basic acl: %w", bacl.DecodeString(args[0]))
|
common.ExitOnErr(cmd, "unable to parse basic acl: %w", bacl.DecodeString(args[0]))
|
||||||
util.PrettyPrintTableBACL(cmd, &bacl)
|
util.PrettyPrintTableBACL(cmd, &bacl)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -84,7 +84,7 @@ func createEACL(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tb := eacl.NewTable()
|
tb := eacl.NewTable()
|
||||||
commonCmd.ExitOnErr(cmd, "unable to parse provided rules: %w", util.ParseEACLRules(tb, rules))
|
common.ExitOnErr(cmd, "unable to parse provided rules: %w", util.ParseEACLRules(tb, rules))
|
||||||
|
|
||||||
tb.SetCID(containerID)
|
tb.SetCID(containerID)
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -27,12 +27,12 @@ func printEACL(cmd *cobra.Command, _ []string) {
|
||||||
file, _ := cmd.Flags().GetString("file")
|
file, _ := cmd.Flags().GetString("file")
|
||||||
eaclTable := new(eacl.Table)
|
eaclTable := new(eacl.Table)
|
||||||
data, err := os.ReadFile(file)
|
data, err := os.ReadFile(file)
|
||||||
commonCmd.ExitOnErr(cmd, "can't read file with EACL: %w", err)
|
common.ExitOnErr(cmd, "can't read file with EACL: %w", err)
|
||||||
if strings.HasSuffix(file, ".json") {
|
if strings.HasSuffix(file, ".json") {
|
||||||
commonCmd.ExitOnErr(cmd, "unable to parse json: %w", eaclTable.UnmarshalJSON(data))
|
common.ExitOnErr(cmd, "unable to parse json: %w", eaclTable.UnmarshalJSON(data))
|
||||||
} else {
|
} else {
|
||||||
rules := strings.Split(strings.TrimSpace(string(data)), "\n")
|
rules := strings.Split(strings.TrimSpace(string(data)), "\n")
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse file with EACL: %w", util.ParseEACLRules(eaclTable, rules))
|
common.ExitOnErr(cmd, "can't parse file with EACL: %w", util.ParseEACLRules(eaclTable, rules))
|
||||||
}
|
}
|
||||||
util.PrettyPrintTableEACL(cmd, eaclTable)
|
util.PrettyPrintTableEACL(cmd, eaclTable)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
eaclSDK "github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
eaclSDK "github.com/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
|
@ -59,13 +58,13 @@ func init() {
|
||||||
|
|
||||||
func createToken(cmd *cobra.Command, _ []string) {
|
func createToken(cmd *cobra.Command, _ []string) {
|
||||||
iat, iatRelative, err := common.ParseEpoch(cmd, issuedAtFlag)
|
iat, iatRelative, err := common.ParseEpoch(cmd, issuedAtFlag)
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse --"+issuedAtFlag+" flag: %w", err)
|
common.ExitOnErr(cmd, "can't parse --"+issuedAtFlag+" flag: %w", err)
|
||||||
|
|
||||||
exp, expRelative, err := common.ParseEpoch(cmd, commonflags.ExpireAt)
|
exp, expRelative, err := common.ParseEpoch(cmd, commonflags.ExpireAt)
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse --"+commonflags.ExpireAt+" flag: %w", err)
|
common.ExitOnErr(cmd, "can't parse --"+commonflags.ExpireAt+" flag: %w", err)
|
||||||
|
|
||||||
nvb, nvbRelative, err := common.ParseEpoch(cmd, notValidBeforeFlag)
|
nvb, nvbRelative, err := common.ParseEpoch(cmd, notValidBeforeFlag)
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse --"+notValidBeforeFlag+" flag: %w", err)
|
common.ExitOnErr(cmd, "can't parse --"+notValidBeforeFlag+" flag: %w", err)
|
||||||
|
|
||||||
if iatRelative || expRelative || nvbRelative {
|
if iatRelative || expRelative || nvbRelative {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||||
|
@ -73,7 +72,7 @@ func createToken(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
|
endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
|
||||||
currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint)
|
currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint)
|
||||||
commonCmd.ExitOnErr(cmd, "can't fetch current epoch: %w", err)
|
common.ExitOnErr(cmd, "can't fetch current epoch: %w", err)
|
||||||
|
|
||||||
if iatRelative {
|
if iatRelative {
|
||||||
iat += currEpoch
|
iat += currEpoch
|
||||||
|
@ -86,14 +85,14 @@ func createToken(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if exp < nvb {
|
if exp < nvb {
|
||||||
commonCmd.ExitOnErr(cmd, "",
|
common.ExitOnErr(cmd, "",
|
||||||
fmt.Errorf("expiration epoch is less than not-valid-before epoch: %d < %d", exp, nvb))
|
fmt.Errorf("expiration epoch is less than not-valid-before epoch: %d < %d", exp, nvb))
|
||||||
}
|
}
|
||||||
|
|
||||||
ownerStr, _ := cmd.Flags().GetString(ownerFlag)
|
ownerStr, _ := cmd.Flags().GetString(ownerFlag)
|
||||||
|
|
||||||
var ownerID user.ID
|
var ownerID user.ID
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse recipient: %w", ownerID.DecodeString(ownerStr))
|
common.ExitOnErr(cmd, "can't parse recipient: %w", ownerID.DecodeString(ownerStr))
|
||||||
|
|
||||||
var b bearer.Token
|
var b bearer.Token
|
||||||
b.SetExp(exp)
|
b.SetExp(exp)
|
||||||
|
@ -105,8 +104,8 @@ func createToken(cmd *cobra.Command, _ []string) {
|
||||||
if eaclPath != "" {
|
if eaclPath != "" {
|
||||||
table := eaclSDK.NewTable()
|
table := eaclSDK.NewTable()
|
||||||
raw, err := os.ReadFile(eaclPath)
|
raw, err := os.ReadFile(eaclPath)
|
||||||
commonCmd.ExitOnErr(cmd, "can't read extended ACL file: %w", err)
|
common.ExitOnErr(cmd, "can't read extended ACL file: %w", err)
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse extended ACL: %w", json.Unmarshal(raw, table))
|
common.ExitOnErr(cmd, "can't parse extended ACL: %w", json.Unmarshal(raw, table))
|
||||||
b.SetEACLTable(*table)
|
b.SetEACLTable(*table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,12 +114,12 @@ func createToken(cmd *cobra.Command, _ []string) {
|
||||||
toJSON, _ := cmd.Flags().GetBool(jsonFlag)
|
toJSON, _ := cmd.Flags().GetBool(jsonFlag)
|
||||||
if toJSON {
|
if toJSON {
|
||||||
data, err = json.Marshal(b)
|
data, err = json.Marshal(b)
|
||||||
commonCmd.ExitOnErr(cmd, "can't mashal token to JSON: %w", err)
|
common.ExitOnErr(cmd, "can't mashal token to JSON: %w", err)
|
||||||
} else {
|
} else {
|
||||||
data = b.Marshal()
|
data = b.Marshal()
|
||||||
}
|
}
|
||||||
|
|
||||||
out, _ := cmd.Flags().GetString(outFlag)
|
out, _ := cmd.Flags().GetString(outFlag)
|
||||||
err = os.WriteFile(out, data, 0644)
|
err = os.WriteFile(out, data, 0644)
|
||||||
commonCmd.ExitOnErr(cmd, "can't write token to file: %w", err)
|
common.ExitOnErr(cmd, "can't write token to file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
containerApi "github.com/TrueCloudLab/frostfs-api-go/v2/container"
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
|
@ -27,8 +25,6 @@ var (
|
||||||
containerAttributes []string
|
containerAttributes []string
|
||||||
containerAwait bool
|
containerAwait bool
|
||||||
containerName string
|
containerName string
|
||||||
containerNnsName string
|
|
||||||
containerNnsZone string
|
|
||||||
containerNoTimestamp bool
|
containerNoTimestamp bool
|
||||||
containerSubnet string
|
containerSubnet string
|
||||||
force bool
|
force bool
|
||||||
|
@ -37,11 +33,11 @@ var (
|
||||||
var createContainerCmd = &cobra.Command{
|
var createContainerCmd = &cobra.Command{
|
||||||
Use: "create",
|
Use: "create",
|
||||||
Short: "Create new container",
|
Short: "Create new container",
|
||||||
Long: `Create new container and register it in the FrostFS.
|
Long: `Create new container and register it in the NeoFS.
|
||||||
It will be stored in sidechain when inner ring will accepts it.`,
|
It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
placementPolicy, err := parseContainerPolicy(cmd, containerPolicy)
|
placementPolicy, err := parseContainerPolicy(cmd, containerPolicy)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
key := key.Get(cmd)
|
key := key.Get(cmd)
|
||||||
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
||||||
|
@ -51,16 +47,16 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
prm.SetClient(cli)
|
prm.SetClient(cli)
|
||||||
|
|
||||||
resmap, err := internalclient.NetMapSnapshot(prm)
|
resmap, err := internalclient.NetMapSnapshot(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "unable to get netmap snapshot to validate container placement, "+
|
common.ExitOnErr(cmd, "unable to get netmap snapshot to validate container placement, "+
|
||||||
"use --force option to skip this check: %w", err)
|
"use --force option to skip this check: %w", err)
|
||||||
|
|
||||||
nodesByRep, err := resmap.NetMap().ContainerNodes(*placementPolicy, nil)
|
nodesByRep, err := resmap.NetMap().ContainerNodes(*placementPolicy, nil)
|
||||||
commonCmd.ExitOnErr(cmd, "could not build container nodes based on given placement policy, "+
|
common.ExitOnErr(cmd, "could not build container nodes based on given placement policy, "+
|
||||||
"use --force option to skip this check: %w", err)
|
"use --force option to skip this check: %w", err)
|
||||||
|
|
||||||
for i, nodes := range nodesByRep {
|
for i, nodes := range nodesByRep {
|
||||||
if placementPolicy.ReplicaNumberByIndex(i) > uint32(len(nodes)) {
|
if placementPolicy.ReplicaNumberByIndex(i) > uint32(len(nodes)) {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf(
|
common.ExitOnErr(cmd, "", fmt.Errorf(
|
||||||
"the number of nodes '%d' in selector is not enough for the number of replicas '%d', "+
|
"the number of nodes '%d' in selector is not enough for the number of replicas '%d', "+
|
||||||
"use --force option to skip this check",
|
"use --force option to skip this check",
|
||||||
len(nodes),
|
len(nodes),
|
||||||
|
@ -74,7 +70,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
var subnetID subnetid.ID
|
var subnetID subnetid.ID
|
||||||
|
|
||||||
err = subnetID.DecodeString(containerSubnet)
|
err = subnetID.DecodeString(containerSubnet)
|
||||||
commonCmd.ExitOnErr(cmd, "could not parse subnetID: %w", err)
|
common.ExitOnErr(cmd, "could not parse subnetID: %w", err)
|
||||||
|
|
||||||
placementPolicy.RestrictSubnet(subnetID)
|
placementPolicy.RestrictSubnet(subnetID)
|
||||||
}
|
}
|
||||||
|
@ -83,10 +79,10 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
cnr.Init()
|
cnr.Init()
|
||||||
|
|
||||||
err = parseAttributes(&cnr, containerAttributes)
|
err = parseAttributes(&cnr, containerAttributes)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
var basicACL acl.Basic
|
var basicACL acl.Basic
|
||||||
commonCmd.ExitOnErr(cmd, "decode basic ACL string: %w", basicACL.DecodeString(containerACL))
|
common.ExitOnErr(cmd, "decode basic ACL string: %w", basicACL.DecodeString(containerACL))
|
||||||
|
|
||||||
tok := getSession(cmd)
|
tok := getSession(cmd)
|
||||||
|
|
||||||
|
@ -108,7 +104,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
syncContainerPrm.SetContainer(&cnr)
|
syncContainerPrm.SetContainer(&cnr)
|
||||||
|
|
||||||
_, err = internalclient.SyncContainerSettings(syncContainerPrm)
|
_, err = internalclient.SyncContainerSettings(syncContainerPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "syncing container's settings rpc error: %w", err)
|
common.ExitOnErr(cmd, "syncing container's settings rpc error: %w", err)
|
||||||
|
|
||||||
var putPrm internalclient.PutContainerPrm
|
var putPrm internalclient.PutContainerPrm
|
||||||
putPrm.SetClient(cli)
|
putPrm.SetClient(cli)
|
||||||
|
@ -119,7 +115,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := internalclient.PutContainer(putPrm)
|
res, err := internalclient.PutContainer(putPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "put container rpc error: %w", err)
|
common.ExitOnErr(cmd, "put container rpc error: %w", err)
|
||||||
|
|
||||||
id := res.ID()
|
id := res.ID()
|
||||||
|
|
||||||
|
@ -142,7 +138,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "", errCreateTimeout)
|
common.ExitOnErr(cmd, "", errCreateTimeout)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -163,8 +159,6 @@ func initContainerCreateCmd() {
|
||||||
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")
|
||||||
flags.StringVar(&containerName, "name", "", "Container name attribute")
|
flags.StringVar(&containerName, "name", "", "Container name attribute")
|
||||||
flags.StringVar(&containerNnsName, "nns-name", "", "Container nns name attribute")
|
|
||||||
flags.StringVar(&containerNnsZone, "nns-zone", "", "Container nns zone attribute")
|
|
||||||
flags.BoolVar(&containerNoTimestamp, "disable-timestamp", false, "Disable timestamp container attribute")
|
flags.BoolVar(&containerNoTimestamp, "disable-timestamp", false, "Disable timestamp container attribute")
|
||||||
flags.StringVar(&containerSubnet, "subnet", "", "String representation of container subnetwork")
|
flags.StringVar(&containerSubnet, "subnet", "", "String representation of container subnetwork")
|
||||||
flags.BoolVarP(&force, commonflags.ForceFlag, commonflags.ForceFlagShorthand, false,
|
flags.BoolVarP(&force, commonflags.ForceFlag, commonflags.ForceFlagShorthand, false,
|
||||||
|
@ -202,12 +196,12 @@ func parseContainerPolicy(cmd *cobra.Command, policyString string) (*netmap.Plac
|
||||||
|
|
||||||
func parseAttributes(dst *container.Container, attributes []string) error {
|
func parseAttributes(dst *container.Container, attributes []string) error {
|
||||||
for i := range attributes {
|
for i := range attributes {
|
||||||
k, v, found := strings.Cut(attributes[i], attributeDelimiter)
|
kvPair := strings.Split(attributes[i], attributeDelimiter)
|
||||||
if !found {
|
if len(kvPair) != 2 {
|
||||||
return errors.New("invalid container attribute")
|
return errors.New("invalid container attribute")
|
||||||
}
|
}
|
||||||
|
|
||||||
dst.SetAttribute(k, v)
|
dst.SetAttribute(kvPair[0], kvPair[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
if !containerNoTimestamp {
|
if !containerNoTimestamp {
|
||||||
|
@ -218,12 +212,5 @@ func parseAttributes(dst *container.Container, attributes []string) error {
|
||||||
container.SetName(dst, containerName)
|
container.SetName(dst, containerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if containerNnsName != "" {
|
|
||||||
dst.SetAttribute(containerApi.SysAttributeName, containerNnsName)
|
|
||||||
}
|
|
||||||
if containerNnsZone != "" {
|
|
||||||
dst.SetAttribute(containerApi.SysAttributeZone, containerNnsZone)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -35,7 +34,7 @@ Only owner of the container has a permission to remove container.`,
|
||||||
getPrm.SetContainer(id)
|
getPrm.SetContainer(id)
|
||||||
|
|
||||||
resGet, err := internalclient.GetContainer(getPrm)
|
resGet, err := internalclient.GetContainer(getPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "can't get the container: %w", err)
|
common.ExitOnErr(cmd, "can't get the container: %w", err)
|
||||||
|
|
||||||
owner := resGet.Container().Owner()
|
owner := resGet.Container().Owner()
|
||||||
|
|
||||||
|
@ -43,7 +42,7 @@ Only owner of the container has a permission to remove container.`,
|
||||||
common.PrintVerbose(cmd, "Checking session issuer...")
|
common.PrintVerbose(cmd, "Checking session issuer...")
|
||||||
|
|
||||||
if !tok.Issuer().Equals(owner) {
|
if !tok.Issuer().Equals(owner) {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer()))
|
common.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
common.PrintVerbose(cmd, "Checking provided account...")
|
common.PrintVerbose(cmd, "Checking provided account...")
|
||||||
|
@ -52,7 +51,7 @@ Only owner of the container has a permission to remove container.`,
|
||||||
user.IDFromKey(&acc, pk.PublicKey)
|
user.IDFromKey(&acc, pk.PublicKey)
|
||||||
|
|
||||||
if !acc.Equals(owner) {
|
if !acc.Equals(owner) {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("provided account differs with the container owner: expected %s, has %s", owner, acc))
|
common.ExitOnErr(cmd, "", fmt.Errorf("provided account differs with the container owner: expected %s, has %s", owner, acc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,10 +72,10 @@ Only owner of the container has a permission to remove container.`,
|
||||||
common.PrintVerbose(cmd, "Searching for LOCK objects...")
|
common.PrintVerbose(cmd, "Searching for LOCK objects...")
|
||||||
|
|
||||||
res, err := internalclient.SearchObjects(searchPrm)
|
res, err := internalclient.SearchObjects(searchPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "can't search for LOCK objects: %w", err)
|
common.ExitOnErr(cmd, "can't search for LOCK objects: %w", err)
|
||||||
|
|
||||||
if len(res.IDList()) != 0 {
|
if len(res.IDList()) != 0 {
|
||||||
commonCmd.ExitOnErr(cmd, "",
|
common.ExitOnErr(cmd, "",
|
||||||
fmt.Errorf("Container wasn't removed because LOCK objects were found.\n"+
|
fmt.Errorf("Container wasn't removed because LOCK objects were found.\n"+
|
||||||
"Use --%s flag to remove anyway.", commonflags.ForceFlag))
|
"Use --%s flag to remove anyway.", commonflags.ForceFlag))
|
||||||
}
|
}
|
||||||
|
@ -92,7 +91,7 @@ Only owner of the container has a permission to remove container.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := internalclient.DeleteContainer(delPrm)
|
_, err := internalclient.DeleteContainer(delPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
cmd.Println("container delete method invoked")
|
cmd.Println("container delete method invoked")
|
||||||
|
|
||||||
|
@ -113,7 +112,7 @@ Only owner of the container has a permission to remove container.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "", errDeleteTimeout)
|
common.ExitOnErr(cmd, "", errDeleteTimeout)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
@ -45,13 +44,13 @@ var getContainerInfoCmd = &cobra.Command{
|
||||||
|
|
||||||
if containerJSON {
|
if containerJSON {
|
||||||
data, err = cnr.MarshalJSON()
|
data, err = cnr.MarshalJSON()
|
||||||
commonCmd.ExitOnErr(cmd, "can't JSON encode container: %w", err)
|
common.ExitOnErr(cmd, "can't JSON encode container: %w", err)
|
||||||
} else {
|
} else {
|
||||||
data = cnr.Marshal()
|
data = cnr.Marshal()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile(containerPathTo, data, 0644)
|
err = os.WriteFile(containerPathTo, data, 0644)
|
||||||
commonCmd.ExitOnErr(cmd, "can't write container to file: %w", err)
|
common.ExitOnErr(cmd, "can't write container to file: %w", err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -97,7 +96,7 @@ func prettyPrintContainer(cmd *cobra.Command, cnr container.Container, jsonEncod
|
||||||
})
|
})
|
||||||
|
|
||||||
cmd.Println("placement policy:")
|
cmd.Println("placement policy:")
|
||||||
commonCmd.ExitOnErr(cmd, "write policy: %w", cnr.PlacementPolicy().WriteStringTo((*stringWriter)(cmd)))
|
common.ExitOnErr(cmd, "write policy: %w", cnr.PlacementPolicy().WriteStringTo((*stringWriter)(cmd)))
|
||||||
cmd.Println()
|
cmd.Println()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,10 +137,10 @@ func getContainer(cmd *cobra.Command) (container.Container, *ecdsa.PrivateKey) {
|
||||||
var pk *ecdsa.PrivateKey
|
var pk *ecdsa.PrivateKey
|
||||||
if containerPathFrom != "" {
|
if containerPathFrom != "" {
|
||||||
data, err := os.ReadFile(containerPathFrom)
|
data, err := os.ReadFile(containerPathFrom)
|
||||||
commonCmd.ExitOnErr(cmd, "can't read file: %w", err)
|
common.ExitOnErr(cmd, "can't read file: %w", err)
|
||||||
|
|
||||||
err = cnr.Unmarshal(data)
|
err = cnr.Unmarshal(data)
|
||||||
commonCmd.ExitOnErr(cmd, "can't unmarshal container: %w", err)
|
common.ExitOnErr(cmd, "can't unmarshal container: %w", err)
|
||||||
} else {
|
} else {
|
||||||
id := parseContainerID(cmd)
|
id := parseContainerID(cmd)
|
||||||
pk = key.GetOrGenerate(cmd)
|
pk = key.GetOrGenerate(cmd)
|
||||||
|
@ -152,7 +151,7 @@ func getContainer(cmd *cobra.Command) (container.Container, *ecdsa.PrivateKey) {
|
||||||
prm.SetContainer(id)
|
prm.SetContainer(id)
|
||||||
|
|
||||||
res, err := internalclient.GetContainer(prm)
|
res, err := internalclient.GetContainer(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
cnr = res.Container()
|
cnr = res.Container()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ var getExtendedACLCmd = &cobra.Command{
|
||||||
eaclPrm.SetContainer(id)
|
eaclPrm.SetContainer(id)
|
||||||
|
|
||||||
res, err := internalclient.EACL(eaclPrm)
|
res, err := internalclient.EACL(eaclPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
eaclTable := res.EACL()
|
eaclTable := res.EACL()
|
||||||
|
|
||||||
|
@ -40,16 +39,16 @@ var getExtendedACLCmd = &cobra.Command{
|
||||||
|
|
||||||
if containerJSON {
|
if containerJSON {
|
||||||
data, err = eaclTable.MarshalJSON()
|
data, err = eaclTable.MarshalJSON()
|
||||||
commonCmd.ExitOnErr(cmd, "can't encode to JSON: %w", err)
|
common.ExitOnErr(cmd, "can't encode to JSON: %w", err)
|
||||||
} else {
|
} else {
|
||||||
data, err = eaclTable.Marshal()
|
data, err = eaclTable.Marshal()
|
||||||
commonCmd.ExitOnErr(cmd, "can't encode to binary: %w", err)
|
common.ExitOnErr(cmd, "can't encode to binary: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("dumping data to file:", containerPathTo)
|
cmd.Println("dumping data to file:", containerPathTo)
|
||||||
|
|
||||||
err = os.WriteFile(containerPathTo, data, 0644)
|
err = os.WriteFile(containerPathTo, data, 0644)
|
||||||
commonCmd.ExitOnErr(cmd, "could not write eACL to file: %w", err)
|
common.ExitOnErr(cmd, "could not write eACL to file: %w", err)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@ import (
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-api-go/v2/container"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/container"
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -37,7 +37,7 @@ var listContainersCmd = &cobra.Command{
|
||||||
user.IDFromKey(&idUser, key.PublicKey)
|
user.IDFromKey(&idUser, key.PublicKey)
|
||||||
} else {
|
} else {
|
||||||
err := idUser.DecodeString(flagVarListContainerOwner)
|
err := idUser.DecodeString(flagVarListContainerOwner)
|
||||||
commonCmd.ExitOnErr(cmd, "invalid user ID: %w", err)
|
common.ExitOnErr(cmd, "invalid user ID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
||||||
|
@ -47,7 +47,7 @@ var listContainersCmd = &cobra.Command{
|
||||||
prm.SetAccount(idUser)
|
prm.SetAccount(idUser)
|
||||||
|
|
||||||
res, err := internalclient.ListContainers(prm)
|
res, err := internalclient.ListContainers(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
var prmGet internalclient.GetContainerPrm
|
var prmGet internalclient.GetContainerPrm
|
||||||
prmGet.SetClient(cli)
|
prmGet.SetClient(cli)
|
||||||
|
|
|
@ -5,10 +5,10 @@ import (
|
||||||
|
|
||||||
v2object "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
v2object "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -52,7 +52,7 @@ var listContainerObjectsCmd = &cobra.Command{
|
||||||
prmSearch.SetFilters(*filters)
|
prmSearch.SetFilters(*filters)
|
||||||
|
|
||||||
res, err := internalclient.SearchObjects(prmSearch)
|
res, err := internalclient.SearchObjects(prmSearch)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
objectIDs := res.IDList()
|
objectIDs := res.IDList()
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
containerAPI "github.com/TrueCloudLab/frostfs-sdk-go/container"
|
containerAPI "github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
|
@ -32,7 +32,7 @@ var containerNodesCmd = &cobra.Command{
|
||||||
prm.SetClient(cli)
|
prm.SetClient(cli)
|
||||||
|
|
||||||
resmap, err := internalclient.NetMapSnapshot(prm)
|
resmap, err := internalclient.NetMapSnapshot(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "unable to get netmap snapshot", err)
|
common.ExitOnErr(cmd, "unable to get netmap snapshot", err)
|
||||||
|
|
||||||
var id cid.ID
|
var id cid.ID
|
||||||
containerAPI.CalculateID(&id, cnr)
|
containerAPI.CalculateID(&id, cnr)
|
||||||
|
@ -43,12 +43,12 @@ var containerNodesCmd = &cobra.Command{
|
||||||
|
|
||||||
var cnrNodes [][]netmap.NodeInfo
|
var cnrNodes [][]netmap.NodeInfo
|
||||||
cnrNodes, err = resmap.NetMap().ContainerNodes(policy, binCnr)
|
cnrNodes, err = resmap.NetMap().ContainerNodes(policy, binCnr)
|
||||||
commonCmd.ExitOnErr(cmd, "could not build container nodes for given container: %w", err)
|
common.ExitOnErr(cmd, "could not build container nodes for given container: %w", err)
|
||||||
|
|
||||||
for i := range cnrNodes {
|
for i := range cnrNodes {
|
||||||
cmd.Printf("Descriptor #%d, REP %d:\n", i+1, policy.ReplicaNumberByIndex(i))
|
cmd.Printf("Descriptor #%d, REP %d:\n", i+1, policy.ReplicaNumberByIndex(i))
|
||||||
for j := range cnrNodes[i] {
|
for j := range cnrNodes[i] {
|
||||||
commonCmd.PrettyPrintNodeInfo(cmd, cnrNodes[i][j], j, "\t", short)
|
common.PrettyPrintNodeInfo(cmd, cnrNodes[i][j], j, "\t", short)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,10 +38,10 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
|
||||||
cmd.Println("Checking the ability to modify access rights in the container...")
|
cmd.Println("Checking the ability to modify access rights in the container...")
|
||||||
|
|
||||||
extendable, err := internalclient.IsACLExtendable(cli, id)
|
extendable, err := internalclient.IsACLExtendable(cli, id)
|
||||||
commonCmd.ExitOnErr(cmd, "Extensibility check failure: %w", err)
|
common.ExitOnErr(cmd, "Extensibility check failure: %w", err)
|
||||||
|
|
||||||
if !extendable {
|
if !extendable {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("container ACL is immutable"))
|
common.ExitOnErr(cmd, "", errors.New("container ACL is immutable"))
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("ACL extension is enabled in the container, continue processing.")
|
cmd.Println("ACL extension is enabled in the container, continue processing.")
|
||||||
|
@ -57,11 +56,11 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := internalclient.SetEACL(setEACLPrm)
|
_, err := internalclient.SetEACL(setEACLPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
if containerAwait {
|
if containerAwait {
|
||||||
exp, err := eaclTable.Marshal()
|
exp, err := eaclTable.Marshal()
|
||||||
commonCmd.ExitOnErr(cmd, "broken EACL table: %w", err)
|
common.ExitOnErr(cmd, "broken EACL table: %w", err)
|
||||||
|
|
||||||
cmd.Println("awaiting...")
|
cmd.Println("awaiting...")
|
||||||
|
|
||||||
|
@ -88,7 +87,7 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "", errSetEACLTimeout)
|
common.ExitOnErr(cmd, "", errSetEACLTimeout)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -25,12 +24,12 @@ var (
|
||||||
|
|
||||||
func parseContainerID(cmd *cobra.Command) cid.ID {
|
func parseContainerID(cmd *cobra.Command) cid.ID {
|
||||||
if containerID == "" {
|
if containerID == "" {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("container ID is not set"))
|
common.ExitOnErr(cmd, "", errors.New("container ID is not set"))
|
||||||
}
|
}
|
||||||
|
|
||||||
var id cid.ID
|
var id cid.ID
|
||||||
err := id.DecodeString(containerID)
|
err := id.DecodeString(containerID)
|
||||||
commonCmd.ExitOnErr(cmd, "can't decode container ID value: %w", err)
|
common.ExitOnErr(cmd, "can't decode container ID value: %w", err)
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +49,7 @@ func getSession(cmd *cobra.Command) *session.Container {
|
||||||
var res session.Container
|
var res session.Container
|
||||||
|
|
||||||
err := common.ReadBinaryOrJSON(cmd, &res, path)
|
err := common.ReadBinaryOrJSON(cmd, &res, path)
|
||||||
commonCmd.ExitOnErr(cmd, "read container session: %v", err)
|
common.ExitOnErr(cmd, "read container session: %v", err)
|
||||||
|
|
||||||
common.PrintVerbose(cmd, "Session successfully read.")
|
common.PrintVerbose(cmd, "Session successfully read.")
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -40,7 +40,7 @@ var dropObjectsCmd = &cobra.Command{
|
||||||
resp, err = control.DropObjects(client, req)
|
resp, err = control.DropObjects(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -32,7 +32,7 @@ func evacuateShard(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.EvacuateShard(client, req)
|
resp, err = control.EvacuateShard(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
cmd.Printf("Objects moved: %d\n", resp.GetBody().GetCount())
|
cmd.Printf("Objects moved: %d\n", resp.GetBody().GetCount())
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -31,7 +31,7 @@ func flushCache(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.FlushCache(client, req)
|
resp, err = control.FlushCache(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
|
|
||||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
ircontrol "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
ircontrol "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir"
|
||||||
ircontrolsrv "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
ircontrolsrv "github.com/TrueCloudLab/frostfs-node/pkg/services/control/ir/server"
|
||||||
|
@ -19,8 +19,8 @@ const (
|
||||||
|
|
||||||
var healthCheckCmd = &cobra.Command{
|
var healthCheckCmd = &cobra.Command{
|
||||||
Use: "healthcheck",
|
Use: "healthcheck",
|
||||||
Short: "Health check of the FrostFS node",
|
Short: "Health check of the NeoFS node",
|
||||||
Long: "Health check of the FrostFS node. Checks storage node by default, use --ir flag to work with Inner Ring.",
|
Long: "Health check of the NeoFS node. Checks storage node by default, use --ir flag to work with Inner Ring.",
|
||||||
Run: healthCheck,
|
Run: healthCheck,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func healthCheck(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.HealthCheck(client, req)
|
resp, err = control.HealthCheck(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
@ -66,14 +66,14 @@ func healthCheckIR(cmd *cobra.Command, key *ecdsa.PrivateKey, c *client.Client)
|
||||||
req.SetBody(new(ircontrol.HealthCheckRequest_Body))
|
req.SetBody(new(ircontrol.HealthCheckRequest_Body))
|
||||||
|
|
||||||
err := ircontrolsrv.SignMessage(key, req)
|
err := ircontrolsrv.SignMessage(key, req)
|
||||||
commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)
|
common.ExitOnErr(cmd, "could not sign request: %w", err)
|
||||||
|
|
||||||
var resp *ircontrol.HealthCheckResponse
|
var resp *ircontrol.HealthCheckResponse
|
||||||
err = c.ExecRaw(func(client *rawclient.Client) error {
|
err = c.ExecRaw(func(client *rawclient.Client) error {
|
||||||
resp, err = ircontrol.HealthCheck(client, req)
|
resp, err = ircontrol.HealthCheck(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -22,8 +21,8 @@ const (
|
||||||
|
|
||||||
var setNetmapStatusCmd = &cobra.Command{
|
var setNetmapStatusCmd = &cobra.Command{
|
||||||
Use: "set-status",
|
Use: "set-status",
|
||||||
Short: "Set status of the storage node in FrostFS network map",
|
Short: "Set status of the storage node in NeoFS network map",
|
||||||
Long: "Set status of the storage node in FrostFS network map",
|
Long: "Set status of the storage node in NeoFS network map",
|
||||||
Run: setNetmapStatus,
|
Run: setNetmapStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +57,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
switch st, _ := cmd.Flags().GetString(netmapStatusFlag); st {
|
switch st, _ := cmd.Flags().GetString(netmapStatusFlag); st {
|
||||||
default:
|
default:
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("unsupported status %s", st))
|
common.ExitOnErr(cmd, "", fmt.Errorf("unsupported status %s", st))
|
||||||
case netmapStatusOnline:
|
case netmapStatusOnline:
|
||||||
body.SetStatus(control.NetmapStatus_ONLINE)
|
body.SetStatus(control.NetmapStatus_ONLINE)
|
||||||
printIgnoreForce(control.NetmapStatus_ONLINE)
|
printIgnoreForce(control.NetmapStatus_ONLINE)
|
||||||
|
@ -87,7 +86,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.SetNetmapStatus(client, req)
|
resp, err = control.SetNetmapStatus(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -45,7 +45,7 @@ func dumpShard(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.DumpShard(client, req)
|
resp, err = control.DumpShard(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/mr-tron/base58"
|
"github.com/mr-tron/base58"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -45,7 +45,7 @@ func listShards(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.ListShards(client, req)
|
resp, err = control.ListShards(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ func listShards(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) {
|
func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) {
|
||||||
out := make([]map[string]any, 0, len(ii))
|
out := make([]map[string]interface{}, 0, len(ii))
|
||||||
for _, i := range ii {
|
for _, i := range ii {
|
||||||
out = append(out, map[string]any{
|
out = append(out, map[string]interface{}{
|
||||||
"shard_id": base58.Encode(i.Shard_ID),
|
"shard_id": base58.Encode(i.Shard_ID),
|
||||||
"mode": shardModeToString(i.GetMode()),
|
"mode": shardModeToString(i.GetMode()),
|
||||||
"metabase": i.GetMetabasePath(),
|
"metabase": i.GetMetabasePath(),
|
||||||
|
@ -73,7 +73,7 @@ func prettyPrintShardsJSON(cmd *cobra.Command, ii []*control.ShardInfo) {
|
||||||
buf := bytes.NewBuffer(nil)
|
buf := bytes.NewBuffer(nil)
|
||||||
enc := json.NewEncoder(buf)
|
enc := json.NewEncoder(buf)
|
||||||
enc.SetIndent("", " ")
|
enc.SetIndent("", " ")
|
||||||
commonCmd.ExitOnErr(cmd, "cannot shard info to JSON: %w", enc.Encode(out))
|
common.ExitOnErr(cmd, "cannot shard info to JSON: %w", enc.Encode(out))
|
||||||
|
|
||||||
cmd.Print(buf.String()) // pretty printer emits newline, to no need for Println
|
cmd.Print(buf.String()) // pretty printer emits newline, to no need for Println
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ package control
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -45,7 +45,7 @@ func restoreShard(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.RestoreShard(client, req)
|
resp, err = control.RestoreShard(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
"github.com/mr-tron/base58"
|
"github.com/mr-tron/base58"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -93,7 +93,6 @@ func initControlSetShardModeCmd() {
|
||||||
flags.String(shardModeFlag, "",
|
flags.String(shardModeFlag, "",
|
||||||
fmt.Sprintf("New shard mode (%s)", strings.Join(modes, ", ")),
|
fmt.Sprintf("New shard mode (%s)", strings.Join(modes, ", ")),
|
||||||
)
|
)
|
||||||
_ = setShardModeCmd.MarkFlagRequired(shardModeFlag)
|
|
||||||
flags.Bool(shardClearErrorsFlag, false, "Set shard error count to 0")
|
flags.Bool(shardClearErrorsFlag, false, "Set shard error count to 0")
|
||||||
|
|
||||||
setShardModeCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag)
|
setShardModeCmd.MarkFlagsMutuallyExclusive(shardIDFlag, shardAllFlag)
|
||||||
|
@ -106,7 +105,7 @@ func setShardMode(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
mode, ok := lookUpShardModeFromString(strMode)
|
mode, ok := lookUpShardModeFromString(strMode)
|
||||||
if !ok {
|
if !ok {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("unsupported mode %s", strMode))
|
common.ExitOnErr(cmd, "", fmt.Errorf("unsupported mode %s", strMode))
|
||||||
}
|
}
|
||||||
|
|
||||||
req := new(control.SetShardModeRequest)
|
req := new(control.SetShardModeRequest)
|
||||||
|
@ -130,7 +129,7 @@ func setShardMode(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.SetShardMode(client, req)
|
resp, err = control.SetShardMode(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
@ -140,7 +139,7 @@ func setShardMode(cmd *cobra.Command, _ []string) {
|
||||||
func getShardID(cmd *cobra.Command) []byte {
|
func getShardID(cmd *cobra.Command) []byte {
|
||||||
sid, _ := cmd.Flags().GetString(shardIDFlag)
|
sid, _ := cmd.Flags().GetString(shardIDFlag)
|
||||||
raw, err := base58.Decode(sid)
|
raw, err := base58.Decode(sid)
|
||||||
commonCmd.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err)
|
common.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err)
|
||||||
return raw
|
return raw
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +151,7 @@ func getShardIDList(cmd *cobra.Command) [][]byte {
|
||||||
|
|
||||||
sidList, _ := cmd.Flags().GetStringSlice(shardIDFlag)
|
sidList, _ := cmd.Flags().GetStringSlice(shardIDFlag)
|
||||||
if len(sidList) == 0 {
|
if len(sidList) == 0 {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("either --%s or --%s flag must be provided", shardIDFlag, shardAllFlag))
|
common.ExitOnErr(cmd, "", fmt.Errorf("either --%s or --%s flag must be provided", shardIDFlag, shardAllFlag))
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can sort the ID list and perform this check without additional allocations,
|
// We can sort the ID list and perform this check without additional allocations,
|
||||||
|
@ -161,7 +160,7 @@ func getShardIDList(cmd *cobra.Command) [][]byte {
|
||||||
seen := make(map[string]struct{})
|
seen := make(map[string]struct{})
|
||||||
for i := range sidList {
|
for i := range sidList {
|
||||||
if _, ok := seen[sidList[i]]; ok {
|
if _, ok := seen[sidList[i]]; ok {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("duplicated shard IDs: %s", sidList[i]))
|
common.ExitOnErr(cmd, "", fmt.Errorf("duplicated shard IDs: %s", sidList[i]))
|
||||||
}
|
}
|
||||||
seen[sidList[i]] = struct{}{}
|
seen[sidList[i]] = struct{}{}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +168,7 @@ func getShardIDList(cmd *cobra.Command) [][]byte {
|
||||||
res := make([][]byte, 0, len(sidList))
|
res := make([][]byte, 0, len(sidList))
|
||||||
for i := range sidList {
|
for i := range sidList {
|
||||||
raw, err := base58.Decode(sidList[i])
|
raw, err := base58.Decode(sidList[i])
|
||||||
commonCmd.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err)
|
common.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err)
|
||||||
|
|
||||||
res = append(res, raw)
|
res = append(res, raw)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
rawclient "github.com/TrueCloudLab/frostfs-api-go/v2/rpc/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
@ -40,11 +40,11 @@ func synchronizeTree(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var cnr cid.ID
|
var cnr cid.ID
|
||||||
cidStr, _ := cmd.Flags().GetString(commonflags.CIDFlag)
|
cidStr, _ := cmd.Flags().GetString(commonflags.CIDFlag)
|
||||||
commonCmd.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(cidStr))
|
common.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(cidStr))
|
||||||
|
|
||||||
treeID, _ := cmd.Flags().GetString("tree-id")
|
treeID, _ := cmd.Flags().GetString("tree-id")
|
||||||
if treeID == "" {
|
if treeID == "" {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("tree ID must not be empty"))
|
common.ExitOnErr(cmd, "", errors.New("tree ID must not be empty"))
|
||||||
}
|
}
|
||||||
|
|
||||||
height, _ := cmd.Flags().GetUint64("height")
|
height, _ := cmd.Flags().GetUint64("height")
|
||||||
|
@ -61,7 +61,7 @@ func synchronizeTree(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
err := controlSvc.SignMessage(pk, req)
|
err := controlSvc.SignMessage(pk, req)
|
||||||
commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)
|
common.ExitOnErr(cmd, "could not sign request: %w", err)
|
||||||
|
|
||||||
cli := getClient(cmd, pk)
|
cli := getClient(cmd, pk)
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ func synchronizeTree(cmd *cobra.Command, _ []string) {
|
||||||
resp, err = control.SynchronizeTree(client, req)
|
resp, err = control.SynchronizeTree(client, req)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ import (
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
|
"github.com/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
controlSvc "github.com/TrueCloudLab/frostfs-node/pkg/services/control/server"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
frostfscrypto "github.com/TrueCloudLab/frostfs-sdk-go/crypto"
|
frostfscrypto "github.com/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||||
|
@ -24,7 +24,7 @@ func initControlFlags(cmd *cobra.Command) {
|
||||||
|
|
||||||
func signRequest(cmd *cobra.Command, pk *ecdsa.PrivateKey, req controlSvc.SignedMessage) {
|
func signRequest(cmd *cobra.Command, pk *ecdsa.PrivateKey, req controlSvc.SignedMessage) {
|
||||||
err := controlSvc.SignMessage(pk, req)
|
err := controlSvc.SignMessage(pk, req)
|
||||||
commonCmd.ExitOnErr(cmd, "could not sign request: %w", err)
|
common.ExitOnErr(cmd, "could not sign request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyResponse(cmd *cobra.Command,
|
func verifyResponse(cmd *cobra.Command,
|
||||||
|
@ -37,7 +37,7 @@ func verifyResponse(cmd *cobra.Command,
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if sigControl == nil {
|
if sigControl == nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("missing response signature"))
|
common.ExitOnErr(cmd, "", errors.New("missing response signature"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
|
// TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion
|
||||||
|
@ -47,10 +47,10 @@ func verifyResponse(cmd *cobra.Command,
|
||||||
sigV2.SetSign(sigControl.GetSign())
|
sigV2.SetSign(sigControl.GetSign())
|
||||||
|
|
||||||
var sig frostfscrypto.Signature
|
var sig frostfscrypto.Signature
|
||||||
commonCmd.ExitOnErr(cmd, "can't read signature: %w", sig.ReadFromV2(sigV2))
|
common.ExitOnErr(cmd, "can't read signature: %w", sig.ReadFromV2(sigV2))
|
||||||
|
|
||||||
if !sig.Verify(body.StableMarshal(nil)) {
|
if !sig.Verify(body.StableMarshal(nil)) {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("invalid response signature"))
|
common.ExitOnErr(cmd, "", errors.New("invalid response signature"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,9 @@ package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ var getEpochCmd = &cobra.Command{
|
||||||
prm.SetClient(cli)
|
prm.SetClient(cli)
|
||||||
|
|
||||||
res, err := internalclient.NetworkInfo(prm)
|
res, err := internalclient.NetworkInfo(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
netInfo := res.NetworkInfo()
|
netInfo := res.NetworkInfo()
|
||||||
|
|
||||||
|
|
|
@ -5,17 +5,17 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var netInfoCmd = &cobra.Command{
|
var netInfoCmd = &cobra.Command{
|
||||||
Use: "netinfo",
|
Use: "netinfo",
|
||||||
Short: "Get information about FrostFS network",
|
Short: "Get information about NeoFS network",
|
||||||
Long: "Get information about FrostFS network",
|
Long: "Get information about NeoFS network",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
p := key.GetOrGenerate(cmd)
|
p := key.GetOrGenerate(cmd)
|
||||||
cli := internalclient.GetSDKClientByFlag(cmd, p, commonflags.RPC)
|
cli := internalclient.GetSDKClientByFlag(cmd, p, commonflags.RPC)
|
||||||
|
@ -24,7 +24,7 @@ var netInfoCmd = &cobra.Command{
|
||||||
prm.SetClient(cli)
|
prm.SetClient(cli)
|
||||||
|
|
||||||
res, err := internalclient.NetworkInfo(prm)
|
res, err := internalclient.NetworkInfo(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
netInfo := res.NetworkInfo()
|
netInfo := res.NetworkInfo()
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ var netInfoCmd = &cobra.Command{
|
||||||
|
|
||||||
const format = " %s: %v\n"
|
const format = " %s: %v\n"
|
||||||
|
|
||||||
cmd.Println("FrostFS network configuration (system)")
|
cmd.Println("NeoFS network configuration (system)")
|
||||||
cmd.Printf(format, "Audit fee", netInfo.AuditFee())
|
cmd.Printf(format, "Audit fee", netInfo.AuditFee())
|
||||||
cmd.Printf(format, "Storage price", netInfo.StoragePrice())
|
cmd.Printf(format, "Storage price", netInfo.StoragePrice())
|
||||||
cmd.Printf(format, "Container fee", netInfo.ContainerFee())
|
cmd.Printf(format, "Container fee", netInfo.ContainerFee())
|
||||||
|
@ -50,7 +50,7 @@ var netInfoCmd = &cobra.Command{
|
||||||
cmd.Printf(format, "Homomorphic hashing disabled", netInfo.HomomorphicHashingDisabled())
|
cmd.Printf(format, "Homomorphic hashing disabled", netInfo.HomomorphicHashingDisabled())
|
||||||
cmd.Printf(format, "Maintenance mode allowed", netInfo.MaintenanceModeAllowed())
|
cmd.Printf(format, "Maintenance mode allowed", netInfo.MaintenanceModeAllowed())
|
||||||
|
|
||||||
cmd.Println("FrostFS network configuration (other)")
|
cmd.Println("NeoFS network configuration (other)")
|
||||||
netInfo.IterateRawNetworkParameters(func(name string, value []byte) {
|
netInfo.IterateRawNetworkParameters(func(name string, value []byte) {
|
||||||
cmd.Printf(format, name, hex.EncodeToString(value))
|
cmd.Printf(format, name, hex.EncodeToString(value))
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
"github.com/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +25,7 @@ var nodeInfoCmd = &cobra.Command{
|
||||||
prm.SetClient(cli)
|
prm.SetClient(cli)
|
||||||
|
|
||||||
res, err := internalclient.NodeInfo(prm)
|
res, err := internalclient.NodeInfo(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
prettyPrintNodeInfo(cmd, res.NodeInfo())
|
prettyPrintNodeInfo(cmd, res.NodeInfo())
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,9 +2,9 @@ package netmap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,9 +20,9 @@ var snapshotCmd = &cobra.Command{
|
||||||
prm.SetClient(cli)
|
prm.SetClient(cli)
|
||||||
|
|
||||||
res, err := internalclient.NetMapSnapshot(prm)
|
res, err := internalclient.NetMapSnapshot(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
commonCmd.PrettyPrintNetMap(cmd, res.NetMap(), false)
|
common.PrettyPrintNetMap(cmd, res.NetMap())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -15,8 +15,8 @@ import (
|
||||||
var objectDelCmd = &cobra.Command{
|
var objectDelCmd = &cobra.Command{
|
||||||
Use: "delete",
|
Use: "delete",
|
||||||
Aliases: []string{"del"},
|
Aliases: []string{"del"},
|
||||||
Short: "Delete object from FrostFS",
|
Short: "Delete object from NeoFS",
|
||||||
Long: "Delete object from FrostFS",
|
Long: "Delete object from NeoFS",
|
||||||
Run: deleteObject,
|
Run: deleteObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,18 +41,18 @@ func deleteObject(cmd *cobra.Command, _ []string) {
|
||||||
if binary {
|
if binary {
|
||||||
filename, _ := cmd.Flags().GetString(fileFlag)
|
filename, _ := cmd.Flags().GetString(fileFlag)
|
||||||
if filename == "" {
|
if filename == "" {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", fileFlag))
|
common.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", fileFlag))
|
||||||
}
|
}
|
||||||
objAddr = readObjectAddressBin(cmd, &cnr, &obj, filename)
|
objAddr = readObjectAddressBin(cmd, &cnr, &obj, filename)
|
||||||
} else {
|
} else {
|
||||||
cidVal, _ := cmd.Flags().GetString(commonflags.CIDFlag)
|
cidVal, _ := cmd.Flags().GetString(commonflags.CIDFlag)
|
||||||
if cidVal == "" {
|
if cidVal == "" {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", commonflags.CIDFlag))
|
common.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", commonflags.CIDFlag))
|
||||||
}
|
}
|
||||||
|
|
||||||
oidVal, _ := cmd.Flags().GetString(commonflags.OIDFlag)
|
oidVal, _ := cmd.Flags().GetString(commonflags.OIDFlag)
|
||||||
if oidVal == "" {
|
if oidVal == "" {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", commonflags.OIDFlag))
|
common.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", commonflags.OIDFlag))
|
||||||
}
|
}
|
||||||
|
|
||||||
objAddr = readObjectAddress(cmd, &cnr, &obj)
|
objAddr = readObjectAddress(cmd, &cnr, &obj)
|
||||||
|
@ -66,7 +66,7 @@ func deleteObject(cmd *cobra.Command, _ []string) {
|
||||||
prm.SetAddress(objAddr)
|
prm.SetAddress(objAddr)
|
||||||
|
|
||||||
res, err := internalclient.DeleteObject(prm)
|
res, err := internalclient.DeleteObject(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
tomb := res.Tombstone()
|
tomb := res.Tombstone()
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -19,8 +19,8 @@ import (
|
||||||
|
|
||||||
var objectGetCmd = &cobra.Command{
|
var objectGetCmd = &cobra.Command{
|
||||||
Use: "get",
|
Use: "get",
|
||||||
Short: "Get object from FrostFS",
|
Short: "Get object from NeoFS",
|
||||||
Long: "Get object from FrostFS",
|
Long: "Get object from NeoFS",
|
||||||
Run: getObject,
|
Run: getObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ func getObject(cmd *cobra.Command, _ []string) {
|
||||||
} else {
|
} else {
|
||||||
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
common.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
@ -110,17 +110,17 @@ func getObject(cmd *cobra.Command, _ []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if binary {
|
if binary {
|
||||||
objToStore := res.Header()
|
objToStore := res.Header()
|
||||||
// TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
//TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
||||||
objToStore.SetPayload(payloadBuffer.Bytes())
|
objToStore.SetPayload(payloadBuffer.Bytes())
|
||||||
objBytes, err := objToStore.Marshal()
|
objBytes, err := objToStore.Marshal()
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
_, err = out.Write(objBytes)
|
_, err = out.Write(objBytes)
|
||||||
commonCmd.ExitOnErr(cmd, "unable to write binary object in out: %w ", err)
|
common.ExitOnErr(cmd, "unable to write binary object in out: %w ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if filename != "" && !strictOutput(cmd) {
|
if filename != "" && !strictOutput(cmd) {
|
||||||
|
@ -130,7 +130,7 @@ func getObject(cmd *cobra.Command, _ []string) {
|
||||||
// Print header only if file is not streamed to stdout.
|
// Print header only if file is not streamed to stdout.
|
||||||
if filename != "" {
|
if filename != "" {
|
||||||
err = printHeader(cmd, res.Header())
|
err = printHeader(cmd, res.Header())
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/checksum"
|
"github.com/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -54,14 +54,14 @@ func getObjectHash(cmd *cobra.Command, _ []string) {
|
||||||
objAddr := readObjectAddress(cmd, &cnr, &obj)
|
objAddr := readObjectAddress(cmd, &cnr, &obj)
|
||||||
|
|
||||||
ranges, err := getRangeList(cmd)
|
ranges, err := getRangeList(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
typ, err := getHashType(cmd)
|
typ, err := getHashType(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
strSalt := strings.TrimPrefix(cmd.Flag(getRangeHashSaltFlag).Value.String(), "0x")
|
strSalt := strings.TrimPrefix(cmd.Flag(getRangeHashSaltFlag).Value.String(), "0x")
|
||||||
|
|
||||||
salt, err := hex.DecodeString(strSalt)
|
salt, err := hex.DecodeString(strSalt)
|
||||||
commonCmd.ExitOnErr(cmd, "could not decode salt: %w", err)
|
common.ExitOnErr(cmd, "could not decode salt: %w", err)
|
||||||
|
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
|
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
|
||||||
|
@ -76,7 +76,7 @@ func getObjectHash(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
// get hash of full payload through HEAD (may be user can do it through dedicated command?)
|
// get hash of full payload through HEAD (may be user can do it through dedicated command?)
|
||||||
res, err := internalclient.HeadObject(headPrm)
|
res, err := internalclient.HeadObject(headPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
var cs checksum.Checksum
|
var cs checksum.Checksum
|
||||||
var csSet bool
|
var csSet bool
|
||||||
|
@ -109,7 +109,7 @@ func getObjectHash(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := internalclient.HashPayloadRanges(hashPrm)
|
res, err := internalclient.HashPayloadRanges(hashPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
hs := res.HashList()
|
hs := res.HashList()
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -71,11 +70,11 @@ func getObjectHeader(cmd *cobra.Command, _ []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = saveAndPrintHeader(cmd, res.Header(), cmd.Flag(fileFlag).Value.String())
|
err = saveAndPrintHeader(cmd, res.Header(), cmd.Flag(fileFlag).Value.String())
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveAndPrintHeader(cmd *cobra.Command, obj *object.Object, filename string) error {
|
func saveAndPrintHeader(cmd *cobra.Command, obj *object.Object, filename string) error {
|
||||||
|
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
objectSDK "github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -30,7 +29,7 @@ var objectLockCmd = &cobra.Command{
|
||||||
|
|
||||||
var cnr cid.ID
|
var cnr cid.ID
|
||||||
err := cnr.DecodeString(cidRaw)
|
err := cnr.DecodeString(cidRaw)
|
||||||
commonCmd.ExitOnErr(cmd, "Incorrect container arg: %v", err)
|
common.ExitOnErr(cmd, "Incorrect container arg: %v", err)
|
||||||
|
|
||||||
oidsRaw, _ := cmd.Flags().GetStringSlice(commonflags.OIDFlag)
|
oidsRaw, _ := cmd.Flags().GetStringSlice(commonflags.OIDFlag)
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ var objectLockCmd = &cobra.Command{
|
||||||
|
|
||||||
for i := range oidsRaw {
|
for i := range oidsRaw {
|
||||||
err = lockList[i].DecodeString(oidsRaw[i])
|
err = lockList[i].DecodeString(oidsRaw[i])
|
||||||
commonCmd.ExitOnErr(cmd, fmt.Sprintf("Incorrect object arg #%d: %%v", i+1), err)
|
common.ExitOnErr(cmd, fmt.Sprintf("Incorrect object arg #%d: %%v", i+1), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
key := key.GetOrGenerate(cmd)
|
key := key.GetOrGenerate(cmd)
|
||||||
|
@ -52,7 +51,7 @@ var objectLockCmd = &cobra.Command{
|
||||||
exp, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
|
exp, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
|
||||||
lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime)
|
lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime)
|
||||||
if exp == 0 && lifetime == 0 { // mutual exclusion is ensured by cobra
|
if exp == 0 && lifetime == 0 { // mutual exclusion is ensured by cobra
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("either expiration epoch of a lifetime is required"))
|
common.ExitOnErr(cmd, "", errors.New("either expiration epoch of a lifetime is required"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if lifetime != 0 {
|
if lifetime != 0 {
|
||||||
|
@ -62,7 +61,7 @@ var objectLockCmd = &cobra.Command{
|
||||||
endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
|
endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
|
||||||
|
|
||||||
currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint)
|
currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint)
|
||||||
commonCmd.ExitOnErr(cmd, "Request current epoch: %w", err)
|
common.ExitOnErr(cmd, "Request current epoch: %w", err)
|
||||||
|
|
||||||
exp = currEpoch + lifetime
|
exp = currEpoch + lifetime
|
||||||
}
|
}
|
||||||
|
@ -86,7 +85,7 @@ var objectLockCmd = &cobra.Command{
|
||||||
prm.SetHeader(obj)
|
prm.SetHeader(obj)
|
||||||
|
|
||||||
res, err := internalclient.PutObject(prm)
|
res, err := internalclient.PutObject(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "Store lock object in FrostFS: %w", err)
|
common.ExitOnErr(cmd, "Store lock object in NeoFS: %w", err)
|
||||||
|
|
||||||
cmd.Printf("Lock object ID: %s\n", res.ID())
|
cmd.Printf("Lock object ID: %s\n", res.ID())
|
||||||
cmd.Println("Objects successfully locked.")
|
cmd.Println("Objects successfully locked.")
|
||||||
|
|
|
@ -12,9 +12,9 @@ import (
|
||||||
|
|
||||||
objectV2 "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
objectV2 "github.com/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
"github.com/TrueCloudLab/frostfs-sdk-go/user"
|
||||||
|
@ -31,8 +31,8 @@ var putExpiredOn uint64
|
||||||
|
|
||||||
var objectPutCmd = &cobra.Command{
|
var objectPutCmd = &cobra.Command{
|
||||||
Use: "put",
|
Use: "put",
|
||||||
Short: "Put object to FrostFS",
|
Short: "Put object to NeoFS",
|
||||||
Long: "Put object to FrostFS",
|
Long: "Put object to NeoFS",
|
||||||
Run: putObject,
|
Run: putObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
cidVal, _ := cmd.Flags().GetString(commonflags.CIDFlag)
|
cidVal, _ := cmd.Flags().GetString(commonflags.CIDFlag)
|
||||||
|
|
||||||
if !binary && cidVal == "" {
|
if !binary && cidVal == "" {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", commonflags.CIDFlag))
|
common.ExitOnErr(cmd, "", fmt.Errorf("required flag \"%s\" not set", commonflags.CIDFlag))
|
||||||
}
|
}
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
|
@ -73,17 +73,17 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
filename, _ := cmd.Flags().GetString(fileFlag)
|
filename, _ := cmd.Flags().GetString(fileFlag)
|
||||||
f, err := os.OpenFile(filename, os.O_RDONLY, os.ModePerm)
|
f, err := os.OpenFile(filename, os.O_RDONLY, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
common.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
||||||
}
|
}
|
||||||
var payloadReader io.Reader = f
|
var payloadReader io.Reader = f
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
|
|
||||||
if binary {
|
if binary {
|
||||||
buf, err := os.ReadFile(filename)
|
buf, err := os.ReadFile(filename)
|
||||||
commonCmd.ExitOnErr(cmd, "unable to read given file: %w", err)
|
common.ExitOnErr(cmd, "unable to read given file: %w", err)
|
||||||
objTemp := object.New()
|
objTemp := object.New()
|
||||||
// TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
//TODO(@acid-ant): #1932 Use streams to marshal/unmarshal payload
|
||||||
commonCmd.ExitOnErr(cmd, "can't unmarshal object from given file: %w", objTemp.Unmarshal(buf))
|
common.ExitOnErr(cmd, "can't unmarshal object from given file: %w", objTemp.Unmarshal(buf))
|
||||||
payloadReader = bytes.NewReader(objTemp.Payload())
|
payloadReader = bytes.NewReader(objTemp.Payload())
|
||||||
cnr, _ = objTemp.ContainerID()
|
cnr, _ = objTemp.ContainerID()
|
||||||
ownerID = *objTemp.OwnerID()
|
ownerID = *objTemp.OwnerID()
|
||||||
|
@ -93,7 +93,7 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs, err := parseObjectAttrs(cmd)
|
attrs, err := parseObjectAttrs(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse object attributes: %w", err)
|
common.ExitOnErr(cmd, "can't parse object attributes: %w", err)
|
||||||
|
|
||||||
expiresOn, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
|
expiresOn, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
|
||||||
if expiresOn > 0 {
|
if expiresOn > 0 {
|
||||||
|
@ -121,7 +121,7 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
obj.SetAttributes(attrs...)
|
obj.SetAttributes(attrs...)
|
||||||
|
|
||||||
notificationInfo, err := parseObjectNotifications(cmd)
|
notificationInfo, err := parseObjectNotifications(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse object notification information: %w", err)
|
common.ExitOnErr(cmd, "can't parse object notification information: %w", err)
|
||||||
|
|
||||||
if notificationInfo != nil {
|
if notificationInfo != nil {
|
||||||
obj.SetNotification(*notificationInfo)
|
obj.SetNotification(*notificationInfo)
|
||||||
|
@ -163,7 +163,7 @@ func putObject(cmd *cobra.Command, _ []string) {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
p.Finish()
|
p.Finish()
|
||||||
}
|
}
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
cmd.Printf("[%s] Object successfully stored\n", filename)
|
cmd.Printf("[%s] Object successfully stored\n", filename)
|
||||||
cmd.Printf(" OID: %s\n CID: %s\n", res.ID(), cnr)
|
cmd.Printf(" OID: %s\n CID: %s\n", res.ID(), cnr)
|
||||||
|
@ -179,12 +179,12 @@ func parseObjectAttrs(cmd *cobra.Command) ([]object.Attribute, error) {
|
||||||
|
|
||||||
attrs := make([]object.Attribute, len(rawAttrs), len(rawAttrs)+2) // name + timestamp attributes
|
attrs := make([]object.Attribute, len(rawAttrs), len(rawAttrs)+2) // name + timestamp attributes
|
||||||
for i := range rawAttrs {
|
for i := range rawAttrs {
|
||||||
k, v, found := strings.Cut(rawAttrs[i], "=")
|
kv := strings.SplitN(rawAttrs[i], "=", 2)
|
||||||
if !found {
|
if len(kv) != 2 {
|
||||||
return nil, fmt.Errorf("invalid attribute format: %s", rawAttrs[i])
|
return nil, fmt.Errorf("invalid attribute format: %s", rawAttrs[i])
|
||||||
}
|
}
|
||||||
attrs[i].SetKey(k)
|
attrs[i].SetKey(kv[0])
|
||||||
attrs[i].SetValue(v)
|
attrs[i].SetValue(kv[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
disableFilename, _ := cmd.Flags().GetBool("disable-filename")
|
disableFilename, _ := cmd.Flags().GetBool("disable-filename")
|
||||||
|
@ -218,26 +218,26 @@ func parseObjectNotifications(cmd *cobra.Command) (*object.NotificationInfo, err
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
before, after, found := strings.Cut(raw, separator)
|
rawSlice := strings.SplitN(raw, separator, 2)
|
||||||
if !found {
|
if len(rawSlice) != 2 {
|
||||||
return nil, fmt.Errorf("notification must be in the form of: *epoch*%s*topic*, got %s", separator, raw)
|
return nil, fmt.Errorf("notification must be in the form of: *epoch*%s*topic*, got %s", separator, raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
ni := new(object.NotificationInfo)
|
ni := new(object.NotificationInfo)
|
||||||
|
|
||||||
epoch, err := strconv.ParseUint(before, 10, 64)
|
epoch, err := strconv.ParseUint(rawSlice[0], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse notification epoch %s: %w", before, err)
|
return nil, fmt.Errorf("could not parse notification epoch %s: %w", rawSlice[0], err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ni.SetEpoch(epoch)
|
ni.SetEpoch(epoch)
|
||||||
|
|
||||||
if after == "" {
|
if rawSlice[1] == "" {
|
||||||
return nil, fmt.Errorf("incorrect empty topic: use %s to force using default topic", useDefaultTopic)
|
return nil, fmt.Errorf("incorrect empty topic: use %s to force using default topic", useDefaultTopic)
|
||||||
}
|
}
|
||||||
|
|
||||||
if after != useDefaultTopic {
|
if rawSlice[1] != useDefaultTopic {
|
||||||
ni.SetTopic(after)
|
ni.SetTopic(rawSlice[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return ni, nil
|
return ni, nil
|
||||||
|
|
|
@ -10,9 +10,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -50,10 +50,10 @@ func getObjectRange(cmd *cobra.Command, _ []string) {
|
||||||
objAddr := readObjectAddress(cmd, &cnr, &obj)
|
objAddr := readObjectAddress(cmd, &cnr, &obj)
|
||||||
|
|
||||||
ranges, err := getRangeList(cmd)
|
ranges, err := getRangeList(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
if len(ranges) != 1 {
|
if len(ranges) != 1 {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("exactly one range must be specified, got: %d", len(ranges)))
|
common.ExitOnErr(cmd, "", fmt.Errorf("exactly one range must be specified, got: %d", len(ranges)))
|
||||||
}
|
}
|
||||||
|
|
||||||
var out io.Writer
|
var out io.Writer
|
||||||
|
@ -64,7 +64,7 @@ func getObjectRange(cmd *cobra.Command, _ []string) {
|
||||||
} else {
|
} else {
|
||||||
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
common.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
@ -93,7 +93,7 @@ func getObjectRange(cmd *cobra.Command, _ []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "can't get object payload range: %w", err)
|
common.ExitOnErr(cmd, "can't get object payload range: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if filename != "" {
|
if filename != "" {
|
||||||
|
@ -116,7 +116,7 @@ func printSplitInfoErr(cmd *cobra.Command, err error) bool {
|
||||||
|
|
||||||
func printSplitInfo(cmd *cobra.Command, info *object.SplitInfo) {
|
func printSplitInfo(cmd *cobra.Command, info *object.SplitInfo) {
|
||||||
bs, err := marshalSplitInfo(cmd, info)
|
bs, err := marshalSplitInfo(cmd, info)
|
||||||
commonCmd.ExitOnErr(cmd, "can't marshal split info: %w", err)
|
common.ExitOnErr(cmd, "can't marshal split info: %w", err)
|
||||||
|
|
||||||
cmd.Println(string(bs))
|
cmd.Println(string(bs))
|
||||||
}
|
}
|
||||||
|
@ -154,16 +154,16 @@ func getRangeList(cmd *cobra.Command) ([]*object.Range, error) {
|
||||||
vs := strings.Split(v, ",")
|
vs := strings.Split(v, ",")
|
||||||
rs := make([]*object.Range, len(vs))
|
rs := make([]*object.Range, len(vs))
|
||||||
for i := range vs {
|
for i := range vs {
|
||||||
before, after, found := strings.Cut(vs[i], rangeSep)
|
r := strings.Split(vs[i], rangeSep)
|
||||||
if !found {
|
if len(r) != 2 {
|
||||||
return nil, fmt.Errorf("invalid range specifier: %s", vs[i])
|
return nil, fmt.Errorf("invalid range specifier: %s", vs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
offset, err := strconv.ParseUint(before, 10, 64)
|
offset, err := strconv.ParseUint(r[0], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid '%s' range offset specifier: %w", vs[i], err)
|
return nil, fmt.Errorf("invalid '%s' range offset specifier: %w", vs[i], err)
|
||||||
}
|
}
|
||||||
length, err := strconv.ParseUint(after, 10, 64)
|
length, err := strconv.ParseUint(r[1], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid '%s' range length specifier: %w", vs[i], err)
|
return nil, fmt.Errorf("invalid '%s' range length specifier: %w", vs[i], err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oidSDK "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oidSDK "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
|
@ -48,7 +48,7 @@ func searchObject(cmd *cobra.Command, _ []string) {
|
||||||
readCID(cmd, &cnr)
|
readCID(cmd, &cnr)
|
||||||
|
|
||||||
sf, err := parseSearchFilters(cmd)
|
sf, err := parseSearchFilters(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ func searchObject(cmd *cobra.Command, _ []string) {
|
||||||
prm.SetFilters(sf)
|
prm.SetFilters(sf)
|
||||||
|
|
||||||
res, err := internalclient.SearchObjects(prm)
|
res, err := internalclient.SearchObjects(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
ids := res.IDList()
|
ids := res.IDList()
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
sessionCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/session"
|
sessionCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/session"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
"github.com/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
@ -63,12 +62,12 @@ func parseXHeaders(cmd *cobra.Command) []string {
|
||||||
xs := make([]string, 0, 2*len(xHeaders))
|
xs := make([]string, 0, 2*len(xHeaders))
|
||||||
|
|
||||||
for i := range xHeaders {
|
for i := range xHeaders {
|
||||||
k, v, found := strings.Cut(xHeaders[i], "=")
|
kv := strings.SplitN(xHeaders[i], "=", 2)
|
||||||
if !found {
|
if len(kv) != 2 {
|
||||||
panic(fmt.Errorf("invalid X-Header format: %s", xHeaders[i]))
|
panic(fmt.Errorf("invalid X-Header format: %s", xHeaders[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
xs = append(xs, k, v)
|
xs = append(xs, kv[0], kv[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return xs
|
return xs
|
||||||
|
@ -86,9 +85,9 @@ func readObjectAddress(cmd *cobra.Command, cnr *cid.ID, obj *oid.ID) oid.Address
|
||||||
|
|
||||||
func readObjectAddressBin(cmd *cobra.Command, cnr *cid.ID, obj *oid.ID, filename string) oid.Address {
|
func readObjectAddressBin(cmd *cobra.Command, cnr *cid.ID, obj *oid.ID, filename string) oid.Address {
|
||||||
buf, err := os.ReadFile(filename)
|
buf, err := os.ReadFile(filename)
|
||||||
commonCmd.ExitOnErr(cmd, "unable to read given file: %w", err)
|
common.ExitOnErr(cmd, "unable to read given file: %w", err)
|
||||||
objTemp := object.New()
|
objTemp := object.New()
|
||||||
commonCmd.ExitOnErr(cmd, "can't unmarshal object from given file: %w", objTemp.Unmarshal(buf))
|
common.ExitOnErr(cmd, "can't unmarshal object from given file: %w", objTemp.Unmarshal(buf))
|
||||||
|
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
*cnr, _ = objTemp.ContainerID()
|
*cnr, _ = objTemp.ContainerID()
|
||||||
|
@ -100,12 +99,12 @@ func readObjectAddressBin(cmd *cobra.Command, cnr *cid.ID, obj *oid.ID, filename
|
||||||
|
|
||||||
func readCID(cmd *cobra.Command, id *cid.ID) {
|
func readCID(cmd *cobra.Command, id *cid.ID) {
|
||||||
err := id.DecodeString(cmd.Flag(commonflags.CIDFlag).Value.String())
|
err := id.DecodeString(cmd.Flag(commonflags.CIDFlag).Value.String())
|
||||||
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
|
common.ExitOnErr(cmd, "decode container ID string: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readOID(cmd *cobra.Command, id *oid.ID) {
|
func readOID(cmd *cobra.Command, id *oid.ID) {
|
||||||
err := id.DecodeString(cmd.Flag(commonflags.OIDFlag).Value.String())
|
err := id.DecodeString(cmd.Flag(commonflags.OIDFlag).Value.String())
|
||||||
commonCmd.ExitOnErr(cmd, "decode object ID string: %w", err)
|
common.ExitOnErr(cmd, "decode object ID string: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SessionPrm is a common interface of object operation's input which supports
|
// SessionPrm is a common interface of object operation's input which supports
|
||||||
|
@ -141,7 +140,7 @@ func getSession(cmd *cobra.Command) *session.Object {
|
||||||
var tok session.Object
|
var tok session.Object
|
||||||
|
|
||||||
err := common.ReadBinaryOrJSON(cmd, &tok, path)
|
err := common.ReadBinaryOrJSON(cmd, &tok, path)
|
||||||
commonCmd.ExitOnErr(cmd, "read session: %v", err)
|
common.ExitOnErr(cmd, "read session: %v", err)
|
||||||
|
|
||||||
return &tok
|
return &tok
|
||||||
}
|
}
|
||||||
|
@ -190,15 +189,15 @@ func _readVerifiedSession(cmd *cobra.Command, dst SessionPrm, key *ecdsa.Private
|
||||||
|
|
||||||
switch false {
|
switch false {
|
||||||
case tok.AssertContainer(cnr):
|
case tok.AssertContainer(cnr):
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("unrelated container in the session"))
|
common.ExitOnErr(cmd, "", errors.New("unrelated container in the session"))
|
||||||
case obj == nil || tok.AssertObject(*obj):
|
case obj == nil || tok.AssertObject(*obj):
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("unrelated object in the session"))
|
common.ExitOnErr(cmd, "", errors.New("unrelated object in the session"))
|
||||||
case tok.AssertVerb(cmdVerb):
|
case tok.AssertVerb(cmdVerb):
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("wrong verb of the session"))
|
common.ExitOnErr(cmd, "", errors.New("wrong verb of the session"))
|
||||||
case tok.AssertAuthKey((*frostfsecdsa.PublicKey)(&key.PublicKey)):
|
case tok.AssertAuthKey((*frostfsecdsa.PublicKey)(&key.PublicKey)):
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("unrelated key in the session"))
|
common.ExitOnErr(cmd, "", errors.New("unrelated key in the session"))
|
||||||
case tok.VerifySignature():
|
case tok.VerifySignature():
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("invalid signature of the session data"))
|
common.ExitOnErr(cmd, "", errors.New("invalid signature of the session data"))
|
||||||
}
|
}
|
||||||
|
|
||||||
common.PrintVerbose(cmd, "Session is correct.")
|
common.PrintVerbose(cmd, "Session is correct.")
|
||||||
|
@ -274,12 +273,12 @@ func OpenSessionViaClient(cmd *cobra.Command, dst SessionPrm, cli *client.Client
|
||||||
|
|
||||||
var tok session.Object
|
var tok session.Object
|
||||||
|
|
||||||
const sessionLifetime = 10 // in FrostFS epochs
|
const sessionLifetime = 10 // in NeoFS epochs
|
||||||
|
|
||||||
common.PrintVerbose(cmd, "Opening remote session with the node...")
|
common.PrintVerbose(cmd, "Opening remote session with the node...")
|
||||||
|
|
||||||
err := sessionCli.CreateSession(&tok, cli, sessionLifetime)
|
err := sessionCli.CreateSession(&tok, cli, sessionLifetime)
|
||||||
commonCmd.ExitOnErr(cmd, "open remote session: %w", err)
|
common.ExitOnErr(cmd, "open remote session: %w", err)
|
||||||
|
|
||||||
common.PrintVerbose(cmd, "Session successfully opened.")
|
common.PrintVerbose(cmd, "Session successfully opened.")
|
||||||
|
|
||||||
|
@ -322,7 +321,7 @@ func finalizeSession(cmd *cobra.Command, dst SessionPrm, tok *session.Object, ke
|
||||||
common.PrintVerbose(cmd, "Signing session...")
|
common.PrintVerbose(cmd, "Signing session...")
|
||||||
|
|
||||||
err := tok.Sign(*key)
|
err := tok.Sign(*key)
|
||||||
commonCmd.ExitOnErr(cmd, "sign session: %w", err)
|
common.ExitOnErr(cmd, "sign session: %w", err)
|
||||||
|
|
||||||
common.PrintVerbose(cmd, "Session token successfully formed and attached to the request.")
|
common.PrintVerbose(cmd, "Session token successfully formed and attached to the request.")
|
||||||
|
|
||||||
|
@ -360,7 +359,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
commonCmd.ExitOnErr(cmd, "failed to get raw object header: %w", err)
|
common.ExitOnErr(cmd, "failed to get raw object header: %w", err)
|
||||||
case err == nil:
|
case err == nil:
|
||||||
common.PrintVerbose(cmd, "Raw header received - object is singular.")
|
common.PrintVerbose(cmd, "Raw header received - object is singular.")
|
||||||
return nil
|
return nil
|
||||||
|
@ -408,7 +407,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
|
||||||
prm.SetFilters(query)
|
prm.SetFilters(query)
|
||||||
|
|
||||||
res, err := internal.SearchObjects(prm)
|
res, err := internal.SearchObjects(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "failed to search objects by split ID: %w", err)
|
common.ExitOnErr(cmd, "failed to search objects by split ID: %w", err)
|
||||||
|
|
||||||
members := res.IDList()
|
members := res.IDList()
|
||||||
|
|
||||||
|
@ -419,7 +418,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
|
||||||
|
|
||||||
idMember, ok := splitInfo.LastPart()
|
idMember, ok := splitInfo.LastPart()
|
||||||
if !ok {
|
if !ok {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("missing any data in received object split information"))
|
common.ExitOnErr(cmd, "", errors.New("missing any data in received object split information"))
|
||||||
}
|
}
|
||||||
|
|
||||||
common.PrintVerbose(cmd, "Traverse the object split chain in reverse...", idMember)
|
common.PrintVerbose(cmd, "Traverse the object split chain in reverse...", idMember)
|
||||||
|
@ -437,7 +436,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
|
||||||
addrObj.SetObject(idMember)
|
addrObj.SetObject(idMember)
|
||||||
|
|
||||||
res, err = internal.HeadObject(prmHead)
|
res, err = internal.HeadObject(prmHead)
|
||||||
commonCmd.ExitOnErr(cmd, "failed to read split chain member's header: %w", err)
|
common.ExitOnErr(cmd, "failed to read split chain member's header: %w", err)
|
||||||
|
|
||||||
idMember, ok = res.Header().PreviousID()
|
idMember, ok = res.Header().PreviousID()
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -446,7 +445,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok = chainSet[idMember]; ok {
|
if _, ok = chainSet[idMember]; ok {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("duplicated member in the split chain %s", idMember))
|
common.ExitOnErr(cmd, "", fmt.Errorf("duplicated member in the split chain %s", idMember))
|
||||||
}
|
}
|
||||||
|
|
||||||
chain = append(chain, idMember)
|
chain = append(chain, idMember)
|
||||||
|
@ -464,7 +463,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
|
||||||
prmSearch.SetFilters(query)
|
prmSearch.SetFilters(query)
|
||||||
|
|
||||||
resSearch, err := internal.SearchObjects(prmSearch)
|
resSearch, err := internal.SearchObjects(prmSearch)
|
||||||
commonCmd.ExitOnErr(cmd, "failed to find object children: %w", err)
|
common.ExitOnErr(cmd, "failed to find object children: %w", err)
|
||||||
|
|
||||||
list := resSearch.IDList()
|
list := resSearch.IDList()
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,7 @@ import (
|
||||||
sgCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/storagegroup"
|
sgCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/storagegroup"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/tree"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/tree"
|
||||||
utilCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
utilCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/misc"
|
"github.com/TrueCloudLab/frostfs-node/misc"
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/config"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/gendoc"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -27,22 +25,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
envPrefix = "FROSTFS_CLI"
|
envPrefix = "NEOFS_CLI"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Global scope flags.
|
// Global scope flags.
|
||||||
var (
|
var (
|
||||||
cfgFile string
|
cfgFile string
|
||||||
cfgDir string
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands.
|
// rootCmd represents the base command when called without any subcommands.
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "frostfs-cli",
|
Use: "frostfs-cli",
|
||||||
Short: "Command Line Tool to work with FrostFS",
|
Short: "Command Line Tool to work with NeoFS",
|
||||||
Long: `FrostFS CLI provides all basic interactions with FrostFS and it's services.
|
Long: `NeoFS CLI provides all basic interactions with NeoFS and it's services.
|
||||||
|
|
||||||
It contains commands for interaction with FrostFS nodes using different versions
|
It contains commands for interaction with NeoFS nodes using different versions
|
||||||
of frostfs-api and some useful utilities for compiling ACL rules from JSON
|
of frostfs-api and some useful utilities for compiling ACL rules from JSON
|
||||||
notation, managing container access through protocol gates, querying network map
|
notation, managing container access through protocol gates, querying network map
|
||||||
and much more!`,
|
and much more!`,
|
||||||
|
@ -53,7 +50,7 @@ and much more!`,
|
||||||
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
// This is called by main.main(). It only needs to happen once to the rootCmd.
|
||||||
func Execute() {
|
func Execute() {
|
||||||
err := rootCmd.Execute()
|
err := rootCmd.Execute()
|
||||||
commonCmd.ExitOnErr(rootCmd, "", err)
|
common.ExitOnErr(rootCmd, "", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -66,7 +63,6 @@ func init() {
|
||||||
// Cobra supports persistent flags, which, if defined here,
|
// Cobra supports persistent flags, which, if defined here,
|
||||||
// will be global for your application.
|
// will be global for your application.
|
||||||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "Config file (default is $HOME/.config/frostfs-cli/config.yaml)")
|
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "Config file (default is $HOME/.config/frostfs-cli/config.yaml)")
|
||||||
rootCmd.PersistentFlags().StringVar(&cfgDir, "config-dir", "", "Config directory")
|
|
||||||
rootCmd.PersistentFlags().BoolP(commonflags.Verbose, commonflags.VerboseShorthand,
|
rootCmd.PersistentFlags().BoolP(commonflags.Verbose, commonflags.VerboseShorthand,
|
||||||
false, commonflags.VerboseUsage)
|
false, commonflags.VerboseUsage)
|
||||||
|
|
||||||
|
@ -74,7 +70,7 @@ func init() {
|
||||||
|
|
||||||
// Cobra also supports local flags, which will only run
|
// Cobra also supports local flags, which will only run
|
||||||
// when this action is called directly.
|
// when this action is called directly.
|
||||||
rootCmd.Flags().Bool("version", false, "Application version and FrostFS API compatibility")
|
rootCmd.Flags().Bool("version", false, "Application version and NeoFS API compatibility")
|
||||||
|
|
||||||
rootCmd.AddCommand(acl.Cmd)
|
rootCmd.AddCommand(acl.Cmd)
|
||||||
rootCmd.AddCommand(bearerCli.Cmd)
|
rootCmd.AddCommand(bearerCli.Cmd)
|
||||||
|
@ -93,7 +89,7 @@ func init() {
|
||||||
func entryPoint(cmd *cobra.Command, _ []string) {
|
func entryPoint(cmd *cobra.Command, _ []string) {
|
||||||
printVersion, _ := cmd.Flags().GetBool("version")
|
printVersion, _ := cmd.Flags().GetBool("version")
|
||||||
if printVersion {
|
if printVersion {
|
||||||
cmd.Print(misc.BuildInfo("FrostFS CLI"))
|
cmd.Print(misc.BuildInfo("NeoFS CLI"))
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -109,7 +105,7 @@ func initConfig() {
|
||||||
} else {
|
} else {
|
||||||
// Find home directory.
|
// Find home directory.
|
||||||
home, err := homedir.Dir()
|
home, err := homedir.Dir()
|
||||||
commonCmd.ExitOnErr(rootCmd, "", err)
|
common.ExitOnErr(rootCmd, "", err)
|
||||||
|
|
||||||
// Search config in `$HOME/.config/frostfs-cli/` with name "config.yaml"
|
// Search config in `$HOME/.config/frostfs-cli/` with name "config.yaml"
|
||||||
viper.AddConfigPath(filepath.Join(home, ".config", "frostfs-cli"))
|
viper.AddConfigPath(filepath.Join(home, ".config", "frostfs-cli"))
|
||||||
|
@ -124,10 +120,4 @@ func initConfig() {
|
||||||
if err := viper.ReadInConfig(); err == nil {
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
common.PrintVerbose(rootCmd, "Using config file: %s", viper.ConfigFileUsed())
|
common.PrintVerbose(rootCmd, "Using config file: %s", viper.ConfigFileUsed())
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfgDir != "" {
|
|
||||||
if err := config.ReadConfigDir(viper.GetViper(), cfgDir); err != nil {
|
|
||||||
commonCmd.ExitOnErr(rootCmd, "failed to read config dir: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
"github.com/TrueCloudLab/frostfs-sdk-go/client"
|
||||||
frostfsecdsa "github.com/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
frostfsecdsa "github.com/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||||
|
@ -52,10 +52,10 @@ func createSession(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var netAddr network.Address
|
var netAddr network.Address
|
||||||
addrStr, _ := cmd.Flags().GetString(commonflags.RPC)
|
addrStr, _ := cmd.Flags().GetString(commonflags.RPC)
|
||||||
commonCmd.ExitOnErr(cmd, "can't parse endpoint: %w", netAddr.FromString(addrStr))
|
common.ExitOnErr(cmd, "can't parse endpoint: %w", netAddr.FromString(addrStr))
|
||||||
|
|
||||||
c, err := internalclient.GetSDKClient(cmd, privKey, netAddr)
|
c, err := internalclient.GetSDKClient(cmd, privKey, netAddr)
|
||||||
commonCmd.ExitOnErr(cmd, "can't create client: %w", err)
|
common.ExitOnErr(cmd, "can't create client: %w", err)
|
||||||
|
|
||||||
lifetime := uint64(defaultLifetime)
|
lifetime := uint64(defaultLifetime)
|
||||||
if lfArg, _ := cmd.Flags().GetUint64(commonflags.Lifetime); lfArg != 0 {
|
if lfArg, _ := cmd.Flags().GetUint64(commonflags.Lifetime); lfArg != 0 {
|
||||||
|
@ -65,23 +65,23 @@ func createSession(cmd *cobra.Command, _ []string) {
|
||||||
var tok session.Object
|
var tok session.Object
|
||||||
|
|
||||||
err = CreateSession(&tok, c, lifetime)
|
err = CreateSession(&tok, c, lifetime)
|
||||||
commonCmd.ExitOnErr(cmd, "can't create session: %w", err)
|
common.ExitOnErr(cmd, "can't create session: %w", err)
|
||||||
|
|
||||||
var data []byte
|
var data []byte
|
||||||
|
|
||||||
if toJSON, _ := cmd.Flags().GetBool(jsonFlag); toJSON {
|
if toJSON, _ := cmd.Flags().GetBool(jsonFlag); toJSON {
|
||||||
data, err = tok.MarshalJSON()
|
data, err = tok.MarshalJSON()
|
||||||
commonCmd.ExitOnErr(cmd, "can't decode session token JSON: %w", err)
|
common.ExitOnErr(cmd, "can't decode session token JSON: %w", err)
|
||||||
} else {
|
} else {
|
||||||
data = tok.Marshal()
|
data = tok.Marshal()
|
||||||
}
|
}
|
||||||
|
|
||||||
filename, _ := cmd.Flags().GetString(outFlag)
|
filename, _ := cmd.Flags().GetString(outFlag)
|
||||||
err = os.WriteFile(filename, data, 0644)
|
err = os.WriteFile(filename, data, 0644)
|
||||||
commonCmd.ExitOnErr(cmd, "can't write token to file: %w", err)
|
common.ExitOnErr(cmd, "can't write token to file: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateSession opens a new communication with FrostFS storage node using client connection.
|
// CreateSession opens a new communication with NeoFS storage node using client connection.
|
||||||
// The session is expected to be maintained by the storage node during the given
|
// The session is expected to be maintained by the storage node during the given
|
||||||
// number of epochs.
|
// number of epochs.
|
||||||
//
|
//
|
||||||
|
|
|
@ -2,10 +2,10 @@ package storagegroup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -13,8 +13,8 @@ import (
|
||||||
|
|
||||||
var sgDelCmd = &cobra.Command{
|
var sgDelCmd = &cobra.Command{
|
||||||
Use: "delete",
|
Use: "delete",
|
||||||
Short: "Delete storage group from FrostFS",
|
Short: "Delete storage group from NeoFS",
|
||||||
Long: "Delete storage group from FrostFS",
|
Long: "Delete storage group from NeoFS",
|
||||||
Run: delSG,
|
Run: delSG,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ func delSG(cmd *cobra.Command, _ []string) {
|
||||||
prm.SetAddress(addr)
|
prm.SetAddress(addr)
|
||||||
|
|
||||||
res, err := internalclient.DeleteObject(prm)
|
res, err := internalclient.DeleteObject(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
tombstone := res.Tombstone()
|
tombstone := res.Tombstone()
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
storagegroupSDK "github.com/TrueCloudLab/frostfs-sdk-go/storagegroup"
|
storagegroupSDK "github.com/TrueCloudLab/frostfs-sdk-go/storagegroup"
|
||||||
|
@ -19,8 +18,8 @@ var sgID string
|
||||||
|
|
||||||
var sgGetCmd = &cobra.Command{
|
var sgGetCmd = &cobra.Command{
|
||||||
Use: "get",
|
Use: "get",
|
||||||
Short: "Get storage group from FrostFS",
|
Short: "Get storage group from NeoFS",
|
||||||
Long: "Get storage group from FrostFS",
|
Long: "Get storage group from NeoFS",
|
||||||
Run: getSG,
|
Run: getSG,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +57,7 @@ func getSG(cmd *cobra.Command, _ []string) {
|
||||||
prm.SetPayloadWriter(buf)
|
prm.SetPayloadWriter(buf)
|
||||||
|
|
||||||
res, err := internalclient.GetObject(prm)
|
res, err := internalclient.GetObject(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
rawObj := res.Header()
|
rawObj := res.Header()
|
||||||
rawObj.SetPayload(buf.Bytes())
|
rawObj.SetPayload(buf.Bytes())
|
||||||
|
@ -66,7 +65,7 @@ func getSG(cmd *cobra.Command, _ []string) {
|
||||||
var sg storagegroupSDK.StorageGroup
|
var sg storagegroupSDK.StorageGroup
|
||||||
|
|
||||||
err = storagegroupSDK.ReadFromObject(&sg, *rawObj)
|
err = storagegroupSDK.ReadFromObject(&sg, *rawObj)
|
||||||
commonCmd.ExitOnErr(cmd, "could not read storage group from the obj: %w", err)
|
common.ExitOnErr(cmd, "could not read storage group from the obj: %w", err)
|
||||||
|
|
||||||
cmd.Printf("The last active epoch: %d\n", sg.ExpirationEpoch())
|
cmd.Printf("The last active epoch: %d\n", sg.ExpirationEpoch())
|
||||||
cmd.Printf("Group size: %d\n", sg.ValidationDataSize())
|
cmd.Printf("Group size: %d\n", sg.ValidationDataSize())
|
||||||
|
|
|
@ -2,10 +2,10 @@ package storagegroup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/storagegroup"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/storagegroup"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -13,8 +13,8 @@ import (
|
||||||
|
|
||||||
var sgListCmd = &cobra.Command{
|
var sgListCmd = &cobra.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List storage groups in FrostFS container",
|
Short: "List storage groups in NeoFS container",
|
||||||
Long: "List storage groups in FrostFS container",
|
Long: "List storage groups in NeoFS container",
|
||||||
Run: listSG,
|
Run: listSG,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ func listSG(cmd *cobra.Command, _ []string) {
|
||||||
prm.SetFilters(storagegroup.SearchQuery())
|
prm.SetFilters(storagegroup.SearchQuery())
|
||||||
|
|
||||||
res, err := internalclient.SearchObjects(prm)
|
res, err := internalclient.SearchObjects(prm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
ids := res.IDList()
|
ids := res.IDList()
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
objectCli "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/object"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/storagegroup"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/storagegroup"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
"github.com/TrueCloudLab/frostfs-sdk-go/container"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
@ -26,8 +26,8 @@ var sgMembers []string
|
||||||
|
|
||||||
var sgPutCmd = &cobra.Command{
|
var sgPutCmd = &cobra.Command{
|
||||||
Use: "put",
|
Use: "put",
|
||||||
Short: "Put storage group to FrostFS",
|
Short: "Put storage group to NeoFS",
|
||||||
Long: "Put storage group to FrostFS",
|
Long: "Put storage group to NeoFS",
|
||||||
Run: putSG,
|
Run: putSG,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,10 +60,10 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
for i := range sgMembers {
|
for i := range sgMembers {
|
||||||
err := members[i].DecodeString(sgMembers[i])
|
err := members[i].DecodeString(sgMembers[i])
|
||||||
commonCmd.ExitOnErr(cmd, "could not parse object ID: %w", err)
|
common.ExitOnErr(cmd, "could not parse object ID: %w", err)
|
||||||
|
|
||||||
if _, alreadyExists := uniqueFilter[members[i]]; alreadyExists {
|
if _, alreadyExists := uniqueFilter[members[i]]; alreadyExists {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("%s member in not unique", members[i]))
|
common.ExitOnErr(cmd, "", fmt.Errorf("%s member in not unique", members[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
uniqueFilter[members[i]] = struct{}{}
|
uniqueFilter[members[i]] = struct{}{}
|
||||||
|
@ -80,7 +80,7 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
getCnrPrm.SetContainer(cnr)
|
getCnrPrm.SetContainer(cnr)
|
||||||
|
|
||||||
resGetCnr, err := internalclient.GetContainer(getCnrPrm)
|
resGetCnr, err := internalclient.GetContainer(getCnrPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "get container RPC call: %w", err)
|
common.ExitOnErr(cmd, "get container RPC call: %w", err)
|
||||||
|
|
||||||
objectCli.OpenSessionViaClient(cmd, &putPrm, cli, pk, cnr, nil)
|
objectCli.OpenSessionViaClient(cmd, &putPrm, cli, pk, cnr, nil)
|
||||||
objectCli.Prepare(cmd, &headPrm, &putPrm)
|
objectCli.Prepare(cmd, &headPrm, &putPrm)
|
||||||
|
@ -94,13 +94,13 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
ownerID: &ownerID,
|
ownerID: &ownerID,
|
||||||
prm: headPrm,
|
prm: headPrm,
|
||||||
}, cnr, members, !container.IsHomomorphicHashingDisabled(resGetCnr.Container()))
|
}, cnr, members, !container.IsHomomorphicHashingDisabled(resGetCnr.Container()))
|
||||||
commonCmd.ExitOnErr(cmd, "could not collect storage group members: %w", err)
|
common.ExitOnErr(cmd, "could not collect storage group members: %w", err)
|
||||||
|
|
||||||
var netInfoPrm internalclient.NetworkInfoPrm
|
var netInfoPrm internalclient.NetworkInfoPrm
|
||||||
netInfoPrm.SetClient(cli)
|
netInfoPrm.SetClient(cli)
|
||||||
|
|
||||||
ni, err := internalclient.NetworkInfo(netInfoPrm)
|
ni, err := internalclient.NetworkInfo(netInfoPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "can't fetch network info: %w", err)
|
common.ExitOnErr(cmd, "can't fetch network info: %w", err)
|
||||||
|
|
||||||
lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime)
|
lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime)
|
||||||
sg.SetExpirationEpoch(ni.NetworkInfo().CurrentEpoch() + lifetime)
|
sg.SetExpirationEpoch(ni.NetworkInfo().CurrentEpoch() + lifetime)
|
||||||
|
@ -114,7 +114,7 @@ func putSG(cmd *cobra.Command, _ []string) {
|
||||||
putPrm.SetHeader(obj)
|
putPrm.SetHeader(obj)
|
||||||
|
|
||||||
res, err := internalclient.PutObject(putPrm)
|
res, err := internalclient.PutObject(putPrm)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
|
common.ExitOnErr(cmd, "rpc error: %w", err)
|
||||||
|
|
||||||
cmd.Println("Storage group successfully stored")
|
cmd.Println("Storage group successfully stored")
|
||||||
cmd.Printf(" ID: %s\n CID: %s\n", res.ID(), cnr)
|
cmd.Printf(" ID: %s\n CID: %s\n", res.ID(), cnr)
|
||||||
|
@ -127,7 +127,7 @@ type sgHeadReceiver struct {
|
||||||
prm internalclient.HeadObjectPrm
|
prm internalclient.HeadObjectPrm
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c sgHeadReceiver) Head(addr oid.Address) (any, error) {
|
func (c sgHeadReceiver) Head(addr oid.Address) (interface{}, error) {
|
||||||
c.prm.SetAddress(addr)
|
c.prm.SetAddress(addr)
|
||||||
|
|
||||||
res, err := internalclient.HeadObject(c.prm)
|
res, err := internalclient.HeadObject(c.prm)
|
||||||
|
|
|
@ -3,8 +3,8 @@ package storagegroup
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -23,12 +23,12 @@ func readObjectAddress(cmd *cobra.Command, cnr *cid.ID, obj *oid.ID) oid.Address
|
||||||
func readCID(cmd *cobra.Command, id *cid.ID) {
|
func readCID(cmd *cobra.Command, id *cid.ID) {
|
||||||
f := cmd.Flag(commonflags.CIDFlag)
|
f := cmd.Flag(commonflags.CIDFlag)
|
||||||
if f == nil {
|
if f == nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("missing container flag (%s)", commonflags.CIDFlag))
|
common.ExitOnErr(cmd, "", fmt.Errorf("missing container flag (%s)", commonflags.CIDFlag))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := id.DecodeString(f.Value.String())
|
err := id.DecodeString(f.Value.String())
|
||||||
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
|
common.ExitOnErr(cmd, "decode container ID string: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readSGID(cmd *cobra.Command, id *oid.ID) {
|
func readSGID(cmd *cobra.Command, id *oid.ID) {
|
||||||
|
@ -36,10 +36,10 @@ func readSGID(cmd *cobra.Command, id *oid.ID) {
|
||||||
|
|
||||||
f := cmd.Flag(flag)
|
f := cmd.Flag(flag)
|
||||||
if f == nil {
|
if f == nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("missing storage group flag (%s)", flag))
|
common.ExitOnErr(cmd, "", fmt.Errorf("missing storage group flag (%s)", flag))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err := id.DecodeString(f.Value.String())
|
err := id.DecodeString(f.Value.String())
|
||||||
commonCmd.ExitOnErr(cmd, "decode storage group ID string: %w", err)
|
common.ExitOnErr(cmd, "decode storage group ID string: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -38,18 +38,18 @@ func add(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var cnr cid.ID
|
var cnr cid.ID
|
||||||
err := cnr.DecodeString(cmd.Flag(commonflags.CIDFlag).Value.String())
|
err := cnr.DecodeString(cmd.Flag(commonflags.CIDFlag).Value.String())
|
||||||
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
|
common.ExitOnErr(cmd, "decode container ID string: %w", err)
|
||||||
|
|
||||||
tid, _ := cmd.Flags().GetString(treeIDFlagKey)
|
tid, _ := cmd.Flags().GetString(treeIDFlagKey)
|
||||||
pid, _ := cmd.Flags().GetUint64(parentIDFlagKey)
|
pid, _ := cmd.Flags().GetUint64(parentIDFlagKey)
|
||||||
|
|
||||||
meta, err := parseMeta(cmd)
|
meta, err := parseMeta(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "meta data parsing: %w", err)
|
common.ExitOnErr(cmd, "meta data parsing: %w", err)
|
||||||
|
|
||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
|
|
||||||
cli, err := _client(ctx)
|
cli, err := _client(ctx)
|
||||||
commonCmd.ExitOnErr(cmd, "client: %w", err)
|
common.ExitOnErr(cmd, "client: %w", err)
|
||||||
|
|
||||||
rawCID := make([]byte, sha256.Size)
|
rawCID := make([]byte, sha256.Size)
|
||||||
cnr.Encode(rawCID)
|
cnr.Encode(rawCID)
|
||||||
|
@ -63,10 +63,10 @@ func add(cmd *cobra.Command, _ []string) {
|
||||||
BearerToken: nil, // TODO: #1891 add token handling
|
BearerToken: nil, // TODO: #1891 add token handling
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
common.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
||||||
|
|
||||||
resp, err := cli.Add(ctx, req)
|
resp, err := cli.Add(ctx, req)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc call: %w", err)
|
common.ExitOnErr(cmd, "rpc call: %w", err)
|
||||||
|
|
||||||
cmd.Println("Node ID: ", resp.Body.NodeId)
|
cmd.Println("Node ID: ", resp.Body.NodeId)
|
||||||
}
|
}
|
||||||
|
@ -79,14 +79,14 @@ func parseMeta(cmd *cobra.Command) ([]*tree.KeyValue, error) {
|
||||||
|
|
||||||
pairs := make([]*tree.KeyValue, 0, len(raws))
|
pairs := make([]*tree.KeyValue, 0, len(raws))
|
||||||
for i := range raws {
|
for i := range raws {
|
||||||
k, v, found := strings.Cut(raws[i], "=")
|
kv := strings.SplitN(raws[i], "=", 2)
|
||||||
if !found {
|
if len(kv) != 2 {
|
||||||
return nil, fmt.Errorf("invalid meta pair format: %s", raws[i])
|
return nil, fmt.Errorf("invalid meta pair format: %s", raws[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
var pair tree.KeyValue
|
var pair tree.KeyValue
|
||||||
pair.Key = k
|
pair.Key = kv[0]
|
||||||
pair.Value = []byte(v)
|
pair.Value = []byte(kv[1])
|
||||||
|
|
||||||
pairs = append(pairs, &pair)
|
pairs = append(pairs, &pair)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
|
@ -47,19 +46,19 @@ func addByPath(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var cnr cid.ID
|
var cnr cid.ID
|
||||||
err := cnr.DecodeString(cidRaw)
|
err := cnr.DecodeString(cidRaw)
|
||||||
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
|
common.ExitOnErr(cmd, "decode container ID string: %w", err)
|
||||||
|
|
||||||
tid, _ := cmd.Flags().GetString(treeIDFlagKey)
|
tid, _ := cmd.Flags().GetString(treeIDFlagKey)
|
||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
|
|
||||||
cli, err := _client(ctx)
|
cli, err := _client(ctx)
|
||||||
commonCmd.ExitOnErr(cmd, "client: %w", err)
|
common.ExitOnErr(cmd, "client: %w", err)
|
||||||
|
|
||||||
rawCID := make([]byte, sha256.Size)
|
rawCID := make([]byte, sha256.Size)
|
||||||
cnr.Encode(rawCID)
|
cnr.Encode(rawCID)
|
||||||
|
|
||||||
meta, err := parseMeta(cmd)
|
meta, err := parseMeta(cmd)
|
||||||
commonCmd.ExitOnErr(cmd, "meta data parsing: %w", err)
|
common.ExitOnErr(cmd, "meta data parsing: %w", err)
|
||||||
|
|
||||||
path, _ := cmd.Flags().GetString(pathFlagKey)
|
path, _ := cmd.Flags().GetString(pathFlagKey)
|
||||||
//pAttr, _ := cmd.Flags().GetString(pathAttributeFlagKey)
|
//pAttr, _ := cmd.Flags().GetString(pathAttributeFlagKey)
|
||||||
|
@ -75,10 +74,10 @@ func addByPath(cmd *cobra.Command, _ []string) {
|
||||||
BearerToken: nil, // TODO: #1891 add token handling
|
BearerToken: nil, // TODO: #1891 add token handling
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
common.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
||||||
|
|
||||||
resp, err := cli.AddByPath(ctx, req)
|
resp, err := cli.AddByPath(ctx, req)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc call: %w", err)
|
common.ExitOnErr(cmd, "rpc call: %w", err)
|
||||||
|
|
||||||
cmd.Printf("Parent ID: %d\n", resp.GetBody().GetParentId())
|
cmd.Printf("Parent ID: %d\n", resp.GetBody().GetParentId())
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
|
@ -47,13 +46,13 @@ func getByPath(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var cnr cid.ID
|
var cnr cid.ID
|
||||||
err := cnr.DecodeString(cidRaw)
|
err := cnr.DecodeString(cidRaw)
|
||||||
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
|
common.ExitOnErr(cmd, "decode container ID string: %w", err)
|
||||||
|
|
||||||
tid, _ := cmd.Flags().GetString(treeIDFlagKey)
|
tid, _ := cmd.Flags().GetString(treeIDFlagKey)
|
||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
|
|
||||||
cli, err := _client(ctx)
|
cli, err := _client(ctx)
|
||||||
commonCmd.ExitOnErr(cmd, "client: %w", err)
|
common.ExitOnErr(cmd, "client: %w", err)
|
||||||
|
|
||||||
rawCID := make([]byte, sha256.Size)
|
rawCID := make([]byte, sha256.Size)
|
||||||
cnr.Encode(rawCID)
|
cnr.Encode(rawCID)
|
||||||
|
@ -74,10 +73,10 @@ func getByPath(cmd *cobra.Command, _ []string) {
|
||||||
BearerToken: nil, // TODO: #1891 add token handling
|
BearerToken: nil, // TODO: #1891 add token handling
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
common.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
||||||
|
|
||||||
resp, err := cli.GetNodeByPath(ctx, req)
|
resp, err := cli.GetNodeByPath(ctx, req)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc call: %w", err)
|
common.ExitOnErr(cmd, "rpc call: %w", err)
|
||||||
|
|
||||||
nn := resp.GetBody().GetNodes()
|
nn := resp.GetBody().GetNodes()
|
||||||
if len(nn) == 0 {
|
if len(nn) == 0 {
|
||||||
|
|
|
@ -3,9 +3,9 @@ package tree
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
|
||||||
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/tree"
|
||||||
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -36,12 +36,12 @@ func list(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
var cnr cid.ID
|
var cnr cid.ID
|
||||||
err := cnr.DecodeString(cidString)
|
err := cnr.DecodeString(cidString)
|
||||||
commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err)
|
common.ExitOnErr(cmd, "decode container ID string: %w", err)
|
||||||
|
|
||||||
ctx := cmd.Context()
|
ctx := cmd.Context()
|
||||||
|
|
||||||
cli, err := _client(ctx)
|
cli, err := _client(ctx)
|
||||||
commonCmd.ExitOnErr(cmd, "client: %w", err)
|
common.ExitOnErr(cmd, "client: %w", err)
|
||||||
|
|
||||||
rawCID := make([]byte, sha256.Size)
|
rawCID := make([]byte, sha256.Size)
|
||||||
cnr.Encode(rawCID)
|
cnr.Encode(rawCID)
|
||||||
|
@ -52,10 +52,10 @@ func list(cmd *cobra.Command, _ []string) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
common.ExitOnErr(cmd, "message signing: %w", tree.SignMessage(req, pk))
|
||||||
|
|
||||||
resp, err := cli.TreeList(ctx, req)
|
resp, err := cli.TreeList(ctx, req)
|
||||||
commonCmd.ExitOnErr(cmd, "rpc call: %w", err)
|
common.ExitOnErr(cmd, "rpc call: %w", err)
|
||||||
|
|
||||||
for _, treeID := range resp.GetBody().GetIds() {
|
for _, treeID := range resp.GetBody().GetIds() {
|
||||||
cmd.Println(treeID)
|
cmd.Println(treeID)
|
||||||
|
|
|
@ -226,32 +226,35 @@ func parseEACLTable(tb *eacl.Table, args []string) error {
|
||||||
|
|
||||||
func parseEACLRecord(args []string) (*eacl.Record, error) {
|
func parseEACLRecord(args []string) (*eacl.Record, error) {
|
||||||
r := new(eacl.Record)
|
r := new(eacl.Record)
|
||||||
for _, arg := range args {
|
for i := range args {
|
||||||
before, after, found := strings.Cut(arg, ":")
|
ss := strings.SplitN(args[i], ":", 2)
|
||||||
|
|
||||||
switch prefix := strings.ToLower(before); prefix {
|
switch prefix := strings.ToLower(ss[0]); prefix {
|
||||||
case "req", "obj": // filters
|
case "req", "obj": // filters
|
||||||
if !found {
|
if len(ss) != 2 {
|
||||||
return nil, fmt.Errorf("invalid filter or target: %s", arg)
|
return nil, fmt.Errorf("invalid filter or target: %s", args[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
i := strings.Index(ss[1], "=")
|
||||||
|
if i < 0 {
|
||||||
|
return nil, fmt.Errorf("invalid filter key-value pair: %s", ss[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
var key, value string
|
var key, value string
|
||||||
var op eacl.Match
|
var op eacl.Match
|
||||||
var f bool
|
|
||||||
|
|
||||||
key, value, f = strings.Cut(after, "!=")
|
if 0 < i && ss[1][i-1] == '!' {
|
||||||
if f {
|
key = ss[1][:i-1]
|
||||||
op = eacl.MatchStringNotEqual
|
op = eacl.MatchStringNotEqual
|
||||||
} else {
|
} else {
|
||||||
key, value, f = strings.Cut(after, "=")
|
key = ss[1][:i]
|
||||||
if !f {
|
|
||||||
return nil, fmt.Errorf("invalid filter key-value pair: %s", after)
|
|
||||||
}
|
|
||||||
op = eacl.MatchStringEqual
|
op = eacl.MatchStringEqual
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value = ss[1][i+1:]
|
||||||
|
|
||||||
typ := eacl.HeaderFromRequest
|
typ := eacl.HeaderFromRequest
|
||||||
if before == "obj" {
|
if ss[0] == "obj" {
|
||||||
typ = eacl.HeaderFromObject
|
typ = eacl.HeaderFromObject
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,8 +263,8 @@ func parseEACLRecord(args []string) (*eacl.Record, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
var pubs []ecdsa.PublicKey
|
var pubs []ecdsa.PublicKey
|
||||||
if found {
|
if len(ss) == 2 {
|
||||||
pubs, err = parseKeyList(after)
|
pubs, err = parseKeyList(ss[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -278,7 +281,7 @@ func parseEACLRecord(args []string) (*eacl.Record, error) {
|
||||||
eacl.AddFormedTarget(r, role, pubs...)
|
eacl.AddFormedTarget(r, role, pubs...)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invalid prefix: %s", before)
|
return nil, fmt.Errorf("invalid prefix: %s", ss[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import "github.com/spf13/cobra"
|
||||||
|
|
||||||
var convertCmd = &cobra.Command{
|
var convertCmd = &cobra.Command{
|
||||||
Use: "convert",
|
Use: "convert",
|
||||||
Short: "Convert representation of FrostFS structures",
|
Short: "Convert representation of NeoFS structures",
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConvertCmd() {
|
func initConvertCmd() {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,10 +36,10 @@ func convertEACLTable(cmd *cobra.Command, _ []string) {
|
||||||
var err error
|
var err error
|
||||||
if jsonFlag || len(to) == 0 {
|
if jsonFlag || len(to) == 0 {
|
||||||
data, err = table.MarshalJSON()
|
data, err = table.MarshalJSON()
|
||||||
commonCmd.ExitOnErr(cmd, "can't JSON encode extended ACL table: %w", err)
|
common.ExitOnErr(cmd, "can't JSON encode extended ACL table: %w", err)
|
||||||
} else {
|
} else {
|
||||||
data, err = table.Marshal()
|
data, err = table.Marshal()
|
||||||
commonCmd.ExitOnErr(cmd, "can't binary encode extended ACL table: %w", err)
|
common.ExitOnErr(cmd, "can't binary encode extended ACL table: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(to) == 0 {
|
if len(to) == 0 {
|
||||||
|
@ -49,7 +48,7 @@ func convertEACLTable(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile(to, data, 0644)
|
err = os.WriteFile(to, data, 0644)
|
||||||
commonCmd.ExitOnErr(cmd, "can't write exteded ACL table to file: %w", err)
|
common.ExitOnErr(cmd, "can't write exteded ACL table to file: %w", err)
|
||||||
|
|
||||||
cmd.Printf("extended ACL table was successfully dumped to %s\n", to)
|
cmd.Printf("extended ACL table was successfully dumped to %s\n", to)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/keyer"
|
"github.com/TrueCloudLab/frostfs-node/pkg/util/keyer"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -41,7 +41,7 @@ func processKeyer(cmd *cobra.Command, args []string) {
|
||||||
err = result.ParseMultiSig(args)
|
err = result.ParseMultiSig(args)
|
||||||
} else {
|
} else {
|
||||||
if len(args) > 1 {
|
if len(args) > 1 {
|
||||||
commonCmd.ExitOnErr(cmd, "", errKeyerSingleArgument)
|
common.ExitOnErr(cmd, "", errKeyerSingleArgument)
|
||||||
}
|
}
|
||||||
|
|
||||||
var argument string
|
var argument string
|
||||||
|
@ -59,7 +59,7 @@ func processKeyer(cmd *cobra.Command, args []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
result.PrettyPrint(uncompressed, useHex)
|
result.PrettyPrint(uncompressed, useHex)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
// locode section.
|
// locode section.
|
||||||
var locodeCmd = &cobra.Command{
|
var locodeCmd = &cobra.Command{
|
||||||
Use: "locode",
|
Use: "locode",
|
||||||
Short: "Working with FrostFS UN/LOCODE database",
|
Short: "Working with NeoFS UN/LOCODE database",
|
||||||
}
|
}
|
||||||
|
|
||||||
func initLocodeCmd() {
|
func initLocodeCmd() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
locodedb "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db"
|
locodedb "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db"
|
||||||
airportsdb "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db/airports"
|
airportsdb "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db/airports"
|
||||||
locodebolt "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db/boltdb"
|
locodebolt "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db/boltdb"
|
||||||
|
@ -34,7 +34,7 @@ var (
|
||||||
|
|
||||||
locodeGenerateCmd = &cobra.Command{
|
locodeGenerateCmd = &cobra.Command{
|
||||||
Use: "generate",
|
Use: "generate",
|
||||||
Short: "Generate UN/LOCODE database for FrostFS",
|
Short: "Generate UN/LOCODE database for NeoFS",
|
||||||
Run: func(cmd *cobra.Command, _ []string) {
|
Run: func(cmd *cobra.Command, _ []string) {
|
||||||
locodeDB := csvlocode.New(
|
locodeDB := csvlocode.New(
|
||||||
csvlocode.Prm{
|
csvlocode.Prm{
|
||||||
|
@ -58,7 +58,7 @@ var (
|
||||||
})
|
})
|
||||||
|
|
||||||
err := targetDB.Open()
|
err := targetDB.Open()
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
defer targetDB.Close()
|
defer targetDB.Close()
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ var (
|
||||||
}
|
}
|
||||||
|
|
||||||
err = locodedb.FillDatabase(locodeDB, airportDB, continentsDB, names, targetDB)
|
err = locodedb.FillDatabase(locodeDB, airportDB, continentsDB, names, targetDB)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
locodedb "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db"
|
locodedb "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db"
|
||||||
locodebolt "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db/boltdb"
|
locodebolt "github.com/TrueCloudLab/frostfs-node/pkg/util/locode/db/boltdb"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -18,19 +18,19 @@ var (
|
||||||
|
|
||||||
locodeInfoCmd = &cobra.Command{
|
locodeInfoCmd = &cobra.Command{
|
||||||
Use: "info",
|
Use: "info",
|
||||||
Short: "Print information about UN/LOCODE from FrostFS database",
|
Short: "Print information about UN/LOCODE from NeoFS database",
|
||||||
Run: func(cmd *cobra.Command, _ []string) {
|
Run: func(cmd *cobra.Command, _ []string) {
|
||||||
targetDB := locodebolt.New(locodebolt.Prm{
|
targetDB := locodebolt.New(locodebolt.Prm{
|
||||||
Path: locodeInfoDBPath,
|
Path: locodeInfoDBPath,
|
||||||
}, locodebolt.ReadOnly())
|
}, locodebolt.ReadOnly())
|
||||||
|
|
||||||
err := targetDB.Open()
|
err := targetDB.Open()
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
defer targetDB.Close()
|
defer targetDB.Close()
|
||||||
|
|
||||||
record, err := locodedb.LocodeRecord(targetDB, locodeInfoCode)
|
record, err := locodedb.LocodeRecord(targetDB, locodeInfoCode)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
cmd.Printf("Country: %s\n", record.CountryName())
|
cmd.Printf("Country: %s\n", record.CountryName())
|
||||||
cmd.Printf("Location: %s\n", record.LocationName())
|
cmd.Printf("Location: %s\n", record.LocationName())
|
||||||
|
@ -48,7 +48,7 @@ var (
|
||||||
func initUtilLocodeInfoCmd() {
|
func initUtilLocodeInfoCmd() {
|
||||||
flags := locodeInfoCmd.Flags()
|
flags := locodeInfoCmd.Flags()
|
||||||
|
|
||||||
flags.StringVar(&locodeInfoDBPath, locodeInfoDBFlag, "", "Path to FrostFS UN/LOCODE database")
|
flags.StringVar(&locodeInfoDBPath, locodeInfoDBFlag, "", "Path to NeoFS UN/LOCODE database")
|
||||||
_ = locodeInfoCmd.MarkFlagRequired(locodeInfoDBFlag)
|
_ = locodeInfoCmd.MarkFlagRequired(locodeInfoDBFlag)
|
||||||
|
|
||||||
flags.StringVar(&locodeInfoCode, locodeInfoCodeFlag, "", "UN/LOCODE")
|
flags.StringVar(&locodeInfoCode, locodeInfoCodeFlag, "", "UN/LOCODE")
|
||||||
|
|
|
@ -11,7 +11,7 @@ const (
|
||||||
|
|
||||||
var signCmd = &cobra.Command{
|
var signCmd = &cobra.Command{
|
||||||
Use: "sign",
|
Use: "sign",
|
||||||
Short: "Sign FrostFS structure",
|
Short: "Sign NeoFS structure",
|
||||||
}
|
}
|
||||||
|
|
||||||
func initSignCmd() {
|
func initSignCmd() {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ func signBearerToken(cmd *cobra.Command, _ []string) {
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
err := btok.Sign(*pk)
|
err := btok.Sign(*pk)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
to := cmd.Flag(signToFlag).Value.String()
|
to := cmd.Flag(signToFlag).Value.String()
|
||||||
jsonFlag, _ := cmd.Flags().GetBool(signBearerJSONFlag)
|
jsonFlag, _ := cmd.Flags().GetBool(signBearerJSONFlag)
|
||||||
|
@ -46,7 +45,7 @@ func signBearerToken(cmd *cobra.Command, _ []string) {
|
||||||
var data []byte
|
var data []byte
|
||||||
if jsonFlag || len(to) == 0 {
|
if jsonFlag || len(to) == 0 {
|
||||||
data, err = btok.MarshalJSON()
|
data, err = btok.MarshalJSON()
|
||||||
commonCmd.ExitOnErr(cmd, "can't JSON encode bearer token: %w", err)
|
common.ExitOnErr(cmd, "can't JSON encode bearer token: %w", err)
|
||||||
} else {
|
} else {
|
||||||
data = btok.Marshal()
|
data = btok.Marshal()
|
||||||
}
|
}
|
||||||
|
@ -57,7 +56,7 @@ func signBearerToken(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
err = os.WriteFile(to, data, 0644)
|
err = os.WriteFile(to, data, 0644)
|
||||||
commonCmd.ExitOnErr(cmd, "can't write signed bearer token to file: %w", err)
|
common.ExitOnErr(cmd, "can't write signed bearer token to file: %w", err)
|
||||||
|
|
||||||
cmd.Printf("signed bearer token was successfully dumped to %s\n", to)
|
cmd.Printf("signed bearer token was successfully dumped to %s\n", to)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||||
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||||
commonCmd "github.com/TrueCloudLab/frostfs-node/cmd/internal/common"
|
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
"github.com/TrueCloudLab/frostfs-sdk-go/session"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -35,10 +34,10 @@ func initSignSessionCmd() {
|
||||||
|
|
||||||
func signSessionToken(cmd *cobra.Command, _ []string) {
|
func signSessionToken(cmd *cobra.Command, _ []string) {
|
||||||
fPath, err := cmd.Flags().GetString(signFromFlag)
|
fPath, err := cmd.Flags().GetString(signFromFlag)
|
||||||
commonCmd.ExitOnErr(cmd, "", err)
|
common.ExitOnErr(cmd, "", err)
|
||||||
|
|
||||||
if fPath == "" {
|
if fPath == "" {
|
||||||
commonCmd.ExitOnErr(cmd, "", errors.New("missing session token flag"))
|
common.ExitOnErr(cmd, "", errors.New("missing session token flag"))
|
||||||
}
|
}
|
||||||
|
|
||||||
type iTokenSession interface {
|
type iTokenSession interface {
|
||||||
|
@ -60,15 +59,15 @@ func signSessionToken(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commonCmd.ExitOnErr(cmd, "decode session: %v", errLast)
|
common.ExitOnErr(cmd, "decode session: %v", errLast)
|
||||||
|
|
||||||
pk := key.GetOrGenerate(cmd)
|
pk := key.GetOrGenerate(cmd)
|
||||||
|
|
||||||
err = stok.Sign(*pk)
|
err = stok.Sign(*pk)
|
||||||
commonCmd.ExitOnErr(cmd, "can't sign token: %w", err)
|
common.ExitOnErr(cmd, "can't sign token: %w", err)
|
||||||
|
|
||||||
data, err := stok.MarshalJSON()
|
data, err := stok.MarshalJSON()
|
||||||
commonCmd.ExitOnErr(cmd, "can't encode session token: %w", err)
|
common.ExitOnErr(cmd, "can't encode session token: %w", err)
|
||||||
|
|
||||||
to := cmd.Flag(signToFlag).Value.String()
|
to := cmd.Flag(signToFlag).Value.String()
|
||||||
if len(to) == 0 {
|
if len(to) == 0 {
|
||||||
|
@ -78,7 +77,7 @@ func signSessionToken(cmd *cobra.Command, _ []string) {
|
||||||
|
|
||||||
err = os.WriteFile(to, data, 0644)
|
err = os.WriteFile(to, data, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
commonCmd.ExitOnErr(cmd, "", fmt.Errorf("can't write signed session token to %s: %w", to, err))
|
common.ExitOnErr(cmd, "", fmt.Errorf("can't write signed session token to %s: %w", to, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Printf("signed session token saved in %s\n", to)
|
cmd.Printf("signed session token saved in %s\n", to)
|
||||||
|
|
|
@ -4,19 +4,18 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/util/config"
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newConfig(path, directory string) (*viper.Viper, error) {
|
func newConfig(path string) (*viper.Viper, error) {
|
||||||
const envPrefix = "FROSTFS_IR"
|
const innerRingPrefix = "neofs_ir"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
v = viper.New()
|
v = viper.New()
|
||||||
)
|
)
|
||||||
|
|
||||||
v.SetEnvPrefix(envPrefix)
|
v.SetEnvPrefix(innerRingPrefix)
|
||||||
v.AutomaticEnv()
|
v.AutomaticEnv()
|
||||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||||
|
|
||||||
|
@ -29,13 +28,7 @@ func newConfig(path, directory string) (*viper.Viper, error) {
|
||||||
} else {
|
} else {
|
||||||
v.SetConfigType("yml")
|
v.SetConfigType("yml")
|
||||||
}
|
}
|
||||||
if err = v.ReadInConfig(); err != nil {
|
err = v.ReadInConfig()
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if directory != "" {
|
|
||||||
err = config.ReadConfigDir(v, directory)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return v, err
|
return v, err
|
||||||
|
|
|
@ -35,17 +35,16 @@ func exitErr(err error) {
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
configFile := flag.String("config", "", "path to config")
|
configFile := flag.String("config", "", "path to config")
|
||||||
configDir := flag.String("config-dir", "", "path to config directory")
|
|
||||||
versionFlag := flag.Bool("version", false, "frostfs-ir node version")
|
versionFlag := flag.Bool("version", false, "frostfs-ir node version")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if *versionFlag {
|
if *versionFlag {
|
||||||
fmt.Print(misc.BuildInfo("FrostFS Inner Ring node"))
|
fmt.Print(misc.BuildInfo("NeoFS Inner Ring node"))
|
||||||
|
|
||||||
os.Exit(SuccessReturnCode)
|
os.Exit(SuccessReturnCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg, err := newConfig(*configFile, *configDir)
|
cfg, err := newConfig(*configFile)
|
||||||
exitErr(err)
|
exitErr(err)
|
||||||
|
|
||||||
var logPrm logger.Prm
|
var logPrm logger.Prm
|
||||||
|
@ -127,7 +126,7 @@ func initHTTPServers(cfg *viper.Viper, log *logger.Logger) []*httputil.Server {
|
||||||
|
|
||||||
addr := cfg.GetString(item.cfgPrefix + ".address")
|
addr := cfg.GetString(item.cfgPrefix + ".address")
|
||||||
|
|
||||||
var prm httputil.HTTPSrvPrm
|
var prm httputil.Prm
|
||||||
|
|
||||||
prm.Address = addr
|
prm.Address = addr
|
||||||
prm.Handler = item.handler()
|
prm.Handler = item.handler()
|
||||||
|
|
|
@ -13,8 +13,8 @@ import (
|
||||||
|
|
||||||
var command = &cobra.Command{
|
var command = &cobra.Command{
|
||||||
Use: "frostfs-lens",
|
Use: "frostfs-lens",
|
||||||
Short: "FrostFS Storage Engine Lens",
|
Short: "NeoFS Storage Engine Lens",
|
||||||
Long: `FrostFS Storage Engine Lens provides tools to browse the contents of the FrostFS storage engine.`,
|
Long: `NeoFS Storage Engine Lens provides tools to browse the contents of the NeoFS storage engine.`,
|
||||||
RunE: entryPoint,
|
RunE: entryPoint,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ var command = &cobra.Command{
|
||||||
func entryPoint(cmd *cobra.Command, _ []string) error {
|
func entryPoint(cmd *cobra.Command, _ []string) error {
|
||||||
printVersion, _ := cmd.Flags().GetBool("version")
|
printVersion, _ := cmd.Flags().GetBool("version")
|
||||||
if printVersion {
|
if printVersion {
|
||||||
cmd.Print(misc.BuildInfo("FrostFS Lens"))
|
cmd.Print(misc.BuildInfo("NeoFS Lens"))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,9 @@ type valueWithTime[V any] struct {
|
||||||
|
|
||||||
// entity that provides TTL cache interface.
|
// entity that provides TTL cache interface.
|
||||||
type ttlNetCache[K comparable, V any] struct {
|
type ttlNetCache[K comparable, V any] struct {
|
||||||
ttl time.Duration
|
m sync.RWMutex // protects progMap
|
||||||
|
progMap map[K]chan struct{} // contains fetch-in-progress keys
|
||||||
|
ttl time.Duration
|
||||||
|
|
||||||
sz int
|
sz int
|
||||||
|
|
||||||
|
@ -41,13 +43,47 @@ func newNetworkTTLCache[K comparable, V any](sz int, ttl time.Duration, netRdr n
|
||||||
fatalOnErr(err)
|
fatalOnErr(err)
|
||||||
|
|
||||||
return &ttlNetCache[K, V]{
|
return &ttlNetCache[K, V]{
|
||||||
ttl: ttl,
|
ttl: ttl,
|
||||||
sz: sz,
|
sz: sz,
|
||||||
cache: cache,
|
cache: cache,
|
||||||
netRdr: netRdr,
|
netRdr: netRdr,
|
||||||
|
progMap: make(map[K]chan struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ttlNetCache[K, V]) actualValue(val interface{}) (*valueWithTime[V], bool) {
|
||||||
|
valWithTime := val.(*valueWithTime[V])
|
||||||
|
if time.Since(valWithTime.t) < c.ttl {
|
||||||
|
return valWithTime, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ttlNetCache[K, V]) waitForUpdate(key K, ch chan struct{}) (V, error) {
|
||||||
|
// wait for another routine to
|
||||||
|
// finish network fetching
|
||||||
|
<-ch
|
||||||
|
|
||||||
|
val, ok := c.cache.Peek(key)
|
||||||
|
if !ok {
|
||||||
|
// routine finished fetching
|
||||||
|
// but no value found; unexpected,
|
||||||
|
// repeat fetching
|
||||||
|
return c.get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
valWithTime, ok := c.actualValue(val)
|
||||||
|
if !ok {
|
||||||
|
// just updated value is already
|
||||||
|
// expired; unexpected, repeat
|
||||||
|
// fetching
|
||||||
|
return c.get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
return valWithTime.v, valWithTime.e
|
||||||
|
}
|
||||||
|
|
||||||
// reads value by the key.
|
// reads value by the key.
|
||||||
//
|
//
|
||||||
// updates the value from the network on cache miss or by TTL.
|
// updates the value from the network on cache miss or by TTL.
|
||||||
|
@ -56,17 +92,44 @@ func newNetworkTTLCache[K comparable, V any](sz int, ttl time.Duration, netRdr n
|
||||||
func (c *ttlNetCache[K, V]) get(key K) (V, error) {
|
func (c *ttlNetCache[K, V]) get(key K) (V, error) {
|
||||||
val, ok := c.cache.Peek(key)
|
val, ok := c.cache.Peek(key)
|
||||||
if ok {
|
if ok {
|
||||||
if time.Since(val.t) < c.ttl {
|
valWithTime, ok := c.actualValue(val)
|
||||||
return val.v, val.e
|
if ok {
|
||||||
|
return valWithTime.v, valWithTime.e
|
||||||
}
|
}
|
||||||
|
|
||||||
c.cache.Remove(key)
|
c.cache.Remove(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
v, err := c.netRdr(key)
|
c.m.RLock()
|
||||||
|
ch, ok := c.progMap[key]
|
||||||
|
c.m.RUnlock()
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
return c.waitForUpdate(key, ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.m.Lock()
|
||||||
|
ch, ok = c.progMap[key]
|
||||||
|
if ok {
|
||||||
|
c.m.Unlock()
|
||||||
|
return c.waitForUpdate(key, ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = make(chan struct{})
|
||||||
|
c.progMap[key] = ch
|
||||||
|
|
||||||
|
c.m.Unlock()
|
||||||
|
|
||||||
|
v, err := c.netRdr(key)
|
||||||
c.set(key, v, err)
|
c.set(key, v, err)
|
||||||
|
|
||||||
|
c.m.Lock()
|
||||||
|
|
||||||
|
close(ch)
|
||||||
|
delete(c.progMap, key)
|
||||||
|
|
||||||
|
c.m.Unlock()
|
||||||
|
|
||||||
return v, err
|
return v, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
type closer struct {
|
|
||||||
name string
|
|
||||||
fn func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getCloser(c *cfg, name string) *closer {
|
|
||||||
for _, clsr := range c.closers {
|
|
||||||
if clsr.name == name {
|
|
||||||
return &clsr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func delCloser(c *cfg, name string) {
|
|
||||||
for i, clsr := range c.closers {
|
|
||||||
if clsr.name == name {
|
|
||||||
c.closers[i] = c.closers[len(c.closers)-1]
|
|
||||||
c.closers = c.closers[:len(c.closers)-1]
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
blobovniczaconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard/blobstor/blobovnicza"
|
blobovniczaconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard/blobstor/blobovnicza"
|
||||||
fstreeconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard/blobstor/fstree"
|
fstreeconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/engine/shard/blobstor/fstree"
|
||||||
loggerconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/logger"
|
loggerconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/logger"
|
||||||
|
metricsconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/metrics"
|
||||||
nodeconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/node"
|
nodeconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/node"
|
||||||
objectconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/object"
|
objectconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/object"
|
||||||
replicatorconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/replicator"
|
replicatorconfig "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-node/config/replicator"
|
||||||
|
@ -47,7 +48,6 @@ import (
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
"github.com/TrueCloudLab/frostfs-node/pkg/network"
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/network/cache"
|
"github.com/TrueCloudLab/frostfs-node/pkg/network/cache"
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||||
objectService "github.com/TrueCloudLab/frostfs-node/pkg/services/object"
|
|
||||||
getsvc "github.com/TrueCloudLab/frostfs-node/pkg/services/object/get"
|
getsvc "github.com/TrueCloudLab/frostfs-node/pkg/services/object/get"
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/tombstone"
|
"github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/tombstone"
|
||||||
tsourse "github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/tombstone/source"
|
tsourse "github.com/TrueCloudLab/frostfs-node/pkg/services/object_manager/tombstone/source"
|
||||||
|
@ -308,7 +308,7 @@ type internals struct {
|
||||||
|
|
||||||
wg *sync.WaitGroup
|
wg *sync.WaitGroup
|
||||||
workers []worker
|
workers []worker
|
||||||
closers []closer
|
closers []func()
|
||||||
|
|
||||||
apiVersion version.Version
|
apiVersion version.Version
|
||||||
healthStatus *atomic.Int32
|
healthStatus *atomic.Int32
|
||||||
|
@ -342,10 +342,9 @@ type shared struct {
|
||||||
privateTokenStore sessionStorage
|
privateTokenStore sessionStorage
|
||||||
persistate *state.PersistentStorage
|
persistate *state.PersistentStorage
|
||||||
|
|
||||||
clientCache *cache.ClientCache
|
clientCache *cache.ClientCache
|
||||||
bgClientCache *cache.ClientCache
|
bgClientCache *cache.ClientCache
|
||||||
putClientCache *cache.ClientCache
|
localAddr network.AddressGroup
|
||||||
localAddr network.AddressGroup
|
|
||||||
|
|
||||||
key *keys.PrivateKey
|
key *keys.PrivateKey
|
||||||
binPublicKey []byte
|
binPublicKey []byte
|
||||||
|
@ -364,16 +363,12 @@ type shared struct {
|
||||||
treeService *tree.Service
|
treeService *tree.Service
|
||||||
|
|
||||||
metricsCollector *metrics.NodeMetrics
|
metricsCollector *metrics.NodeMetrics
|
||||||
|
|
||||||
metricsSvc *objectService.MetricCollector
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamicConfiguration stores parameters of the
|
// dynamicConfiguration stores parameters of the
|
||||||
// components that supports runtime reconfigurations.
|
// components that supports runtime reconfigurations.
|
||||||
type dynamicConfiguration struct {
|
type dynamicConfiguration struct {
|
||||||
logger *logger.Prm
|
logger *logger.Prm
|
||||||
pprof *httpComponent
|
|
||||||
metrics *httpComponent
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type cfg struct {
|
type cfg struct {
|
||||||
|
@ -477,8 +472,6 @@ type cfgObject struct {
|
||||||
pool cfgObjectRoutines
|
pool cfgObjectRoutines
|
||||||
|
|
||||||
cfgLocalStorage cfgLocalStorage
|
cfgLocalStorage cfgLocalStorage
|
||||||
|
|
||||||
tombstoneLifetime uint64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type cfgNotifications struct {
|
type cfgNotifications struct {
|
||||||
|
@ -496,10 +489,6 @@ type cfgObjectRoutines struct {
|
||||||
|
|
||||||
putRemoteCapacity int
|
putRemoteCapacity int
|
||||||
|
|
||||||
putLocal *ants.Pool
|
|
||||||
|
|
||||||
putLocalCapacity int
|
|
||||||
|
|
||||||
replicatorPoolSize int
|
replicatorPoolSize int
|
||||||
|
|
||||||
replication *ants.Pool
|
replication *ants.Pool
|
||||||
|
@ -579,14 +568,13 @@ func initCfg(appCfg *config.Config) *cfg {
|
||||||
ReconnectTimeout: apiclientconfig.ReconnectTimeout(appCfg),
|
ReconnectTimeout: apiclientconfig.ReconnectTimeout(appCfg),
|
||||||
}
|
}
|
||||||
c.shared = shared{
|
c.shared = shared{
|
||||||
key: key,
|
key: key,
|
||||||
binPublicKey: key.PublicKey().Bytes(),
|
binPublicKey: key.PublicKey().Bytes(),
|
||||||
localAddr: netAddr,
|
localAddr: netAddr,
|
||||||
respSvc: response.NewService(response.WithNetworkState(netState)),
|
respSvc: response.NewService(response.WithNetworkState(netState)),
|
||||||
clientCache: cache.NewSDKClientCache(cacheOpts),
|
clientCache: cache.NewSDKClientCache(cacheOpts),
|
||||||
bgClientCache: cache.NewSDKClientCache(cacheOpts),
|
bgClientCache: cache.NewSDKClientCache(cacheOpts),
|
||||||
putClientCache: cache.NewSDKClientCache(cacheOpts),
|
persistate: persistate,
|
||||||
persistate: persistate,
|
|
||||||
}
|
}
|
||||||
c.cfgAccounting = cfgAccounting{
|
c.cfgAccounting = cfgAccounting{
|
||||||
scriptHash: contractsconfig.Balance(appCfg),
|
scriptHash: contractsconfig.Balance(appCfg),
|
||||||
|
@ -610,8 +598,7 @@ func initCfg(appCfg *config.Config) *cfg {
|
||||||
proxyScriptHash: contractsconfig.Proxy(appCfg),
|
proxyScriptHash: contractsconfig.Proxy(appCfg),
|
||||||
}
|
}
|
||||||
c.cfgObject = cfgObject{
|
c.cfgObject = cfgObject{
|
||||||
pool: initObjectPool(appCfg),
|
pool: initObjectPool(appCfg),
|
||||||
tombstoneLifetime: objectconfig.TombstoneLifetime(appCfg),
|
|
||||||
}
|
}
|
||||||
c.cfgReputation = cfgReputation{
|
c.cfgReputation = cfgReputation{
|
||||||
scriptHash: contractsconfig.Reputation(appCfg),
|
scriptHash: contractsconfig.Reputation(appCfg),
|
||||||
|
@ -620,12 +607,13 @@ func initCfg(appCfg *config.Config) *cfg {
|
||||||
|
|
||||||
user.IDFromKey(&c.ownerIDFromKey, key.PrivateKey.PublicKey)
|
user.IDFromKey(&c.ownerIDFromKey, key.PrivateKey.PublicKey)
|
||||||
|
|
||||||
c.metricsCollector = metrics.NewNodeMetrics()
|
if metricsconfig.Enabled(c.appCfg) {
|
||||||
netState.metrics = c.metricsCollector
|
c.metricsCollector = metrics.NewNodeMetrics()
|
||||||
|
netState.metrics = c.metricsCollector
|
||||||
|
}
|
||||||
|
|
||||||
c.onShutdown(c.clientCache.CloseAll) // clean up connections
|
c.onShutdown(c.clientCache.CloseAll) // clean up connections
|
||||||
c.onShutdown(c.bgClientCache.CloseAll) // clean up connections
|
c.onShutdown(c.bgClientCache.CloseAll) // clean up connections
|
||||||
c.onShutdown(c.putClientCache.CloseAll) // clean up connections
|
|
||||||
c.onShutdown(func() { _ = c.persistate.Close() })
|
c.onShutdown(func() { _ = c.persistate.Close() })
|
||||||
|
|
||||||
return c
|
return c
|
||||||
|
@ -802,18 +790,13 @@ func initLocalStorage(c *cfg) {
|
||||||
tombstone.WithTombstoneSource(tombstoneSrc),
|
tombstone.WithTombstoneSource(tombstoneSrc),
|
||||||
)
|
)
|
||||||
|
|
||||||
var shardsAttached int
|
|
||||||
for _, optsWithMeta := range c.shardOpts() {
|
for _, optsWithMeta := range c.shardOpts() {
|
||||||
id, err := ls.AddShard(append(optsWithMeta.shOpts, shard.WithTombstoneSource(tombstoneSource))...)
|
id, err := ls.AddShard(append(optsWithMeta.shOpts, shard.WithTombstoneSource(tombstoneSource))...)
|
||||||
if err != nil {
|
fatalOnErr(err)
|
||||||
c.log.Error("failed to attach shard to engine", zap.Error(err))
|
|
||||||
} else {
|
c.log.Info("shard attached to engine",
|
||||||
shardsAttached++
|
zap.Stringer("id", id),
|
||||||
c.log.Info("shard attached to engine", zap.Stringer("id", id))
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
if shardsAttached == 0 {
|
|
||||||
fatalOnErr(engineconfig.ErrNoShardConfigured)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c.cfgObject.cfgLocalStorage.localStorage = ls
|
c.cfgObject.cfgLocalStorage.localStorage = ls
|
||||||
|
@ -838,11 +821,8 @@ func initObjectPool(cfg *config.Config) (pool cfgObjectRoutines) {
|
||||||
optNonBlocking := ants.WithNonblocking(true)
|
optNonBlocking := ants.WithNonblocking(true)
|
||||||
|
|
||||||
pool.putRemoteCapacity = objectconfig.Put(cfg).PoolSizeRemote()
|
pool.putRemoteCapacity = objectconfig.Put(cfg).PoolSizeRemote()
|
||||||
pool.putRemote, err = ants.NewPool(pool.putRemoteCapacity, optNonBlocking)
|
|
||||||
fatalOnErr(err)
|
|
||||||
|
|
||||||
pool.putLocalCapacity = objectconfig.Put(cfg).PoolSizeLocal()
|
pool.putRemote, err = ants.NewPool(pool.putRemoteCapacity, optNonBlocking)
|
||||||
pool.putLocal, err = ants.NewPool(pool.putLocalCapacity, optNonBlocking)
|
|
||||||
fatalOnErr(err)
|
fatalOnErr(err)
|
||||||
|
|
||||||
pool.replicatorPoolSize = replicatorconfig.PoolSize(cfg)
|
pool.replicatorPoolSize = replicatorconfig.PoolSize(cfg)
|
||||||
|
@ -869,8 +849,8 @@ func (c *cfg) LocalNodeInfo() (*netmapV2.NodeInfo, error) {
|
||||||
return &res, nil
|
return &res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleLocalNodeInfo rewrites local node info from the FrostFS network map.
|
// handleLocalNodeInfo rewrites local node info from the NeoFS network map.
|
||||||
// Called with nil when storage node is outside the FrostFS network map
|
// Called with nil when storage node is outside the NeoFS network map
|
||||||
// (before entering the network and after leaving it).
|
// (before entering the network and after leaving it).
|
||||||
func (c *cfg) handleLocalNodeInfo(ni *netmap.NodeInfo) {
|
func (c *cfg) handleLocalNodeInfo(ni *netmap.NodeInfo) {
|
||||||
c.cfgNetmap.state.setNodeInfo(ni)
|
c.cfgNetmap.state.setNodeInfo(ni)
|
||||||
|
@ -924,107 +904,67 @@ func (c *cfg) ObjectServiceLoad() float64 {
|
||||||
return float64(c.cfgObject.pool.putRemote.Running()) / float64(c.cfgObject.pool.putRemoteCapacity)
|
return float64(c.cfgObject.pool.putRemote.Running()) / float64(c.cfgObject.pool.putRemoteCapacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
type dCmp struct {
|
type dCfg struct {
|
||||||
name string
|
name string
|
||||||
reloadFunc func() error
|
cfg interface {
|
||||||
|
Reload() error
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cfg) signalWatcher() {
|
func (c *cfg) configWatcher(ctx context.Context) {
|
||||||
ch := make(chan os.Signal, 1)
|
ch := make(chan os.Signal, 1)
|
||||||
signal.Notify(ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(ch, syscall.SIGHUP)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case sig := <-ch:
|
case <-ch:
|
||||||
switch sig {
|
c.log.Info("SIGHUP has been received, rereading configuration...")
|
||||||
case syscall.SIGHUP:
|
|
||||||
c.reloadConfig()
|
|
||||||
case syscall.SIGTERM, syscall.SIGINT:
|
|
||||||
c.log.Info("termination signal has been received, stopping...")
|
|
||||||
// TODO (@acid-ant): #49 need to cover case when stuck at the middle(node health UNDEFINED or STARTING)
|
|
||||||
|
|
||||||
c.shutdown()
|
err := c.readConfig(c.appCfg)
|
||||||
|
if err != nil {
|
||||||
c.log.Info("termination signal processing is complete")
|
c.log.Error("configuration reading", zap.Error(err))
|
||||||
return
|
continue
|
||||||
}
|
}
|
||||||
case err := <-c.internalErr: // internal application error
|
|
||||||
c.log.Warn("internal application error",
|
|
||||||
zap.String("message", err.Error()))
|
|
||||||
|
|
||||||
c.shutdown()
|
// all the components are expected to support
|
||||||
|
// Logger's dynamic reconfiguration approach
|
||||||
|
var components []dCfg
|
||||||
|
|
||||||
c.log.Info("internal error processing is complete")
|
// Logger
|
||||||
|
|
||||||
|
logPrm, err := c.loggerPrm()
|
||||||
|
if err != nil {
|
||||||
|
c.log.Error("logger configuration preparation", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
components = append(components, dCfg{name: "logger", cfg: logPrm})
|
||||||
|
|
||||||
|
// Storage Engine
|
||||||
|
|
||||||
|
var rcfg engine.ReConfiguration
|
||||||
|
for _, optsWithID := range c.shardOpts() {
|
||||||
|
rcfg.AddShard(optsWithID.configID, optsWithID.shOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.cfgObject.cfgLocalStorage.localStorage.Reload(rcfg)
|
||||||
|
if err != nil {
|
||||||
|
c.log.Error("storage engine configuration update", zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, component := range components {
|
||||||
|
err = component.cfg.Reload()
|
||||||
|
if err != nil {
|
||||||
|
c.log.Error("updated configuration applying",
|
||||||
|
zap.String("component", component.name),
|
||||||
|
zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.log.Info("configuration has been reloaded successfully")
|
||||||
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cfg) reloadConfig() {
|
|
||||||
c.log.Info("SIGHUP has been received, rereading configuration...")
|
|
||||||
|
|
||||||
err := c.readConfig(c.appCfg)
|
|
||||||
if err != nil {
|
|
||||||
c.log.Error("configuration reading", zap.Error(err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// all the components are expected to support
|
|
||||||
// Logger's dynamic reconfiguration approach
|
|
||||||
var components []dCmp
|
|
||||||
|
|
||||||
// Logger
|
|
||||||
|
|
||||||
logPrm, err := c.loggerPrm()
|
|
||||||
if err != nil {
|
|
||||||
c.log.Error("logger configuration preparation", zap.Error(err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
components = append(components, dCmp{"logger", logPrm.Reload})
|
|
||||||
if cmp, updated := metricsComponent(c); updated {
|
|
||||||
if cmp.enabled {
|
|
||||||
cmp.preReload = enableMetricsSvc
|
|
||||||
} else {
|
|
||||||
cmp.preReload = disableMetricsSvc
|
|
||||||
}
|
|
||||||
components = append(components, dCmp{cmp.name, cmp.reload})
|
|
||||||
}
|
|
||||||
if cmp, updated := pprofComponent(c); updated {
|
|
||||||
components = append(components, dCmp{cmp.name, cmp.reload})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Storage Engine
|
|
||||||
|
|
||||||
var rcfg engine.ReConfiguration
|
|
||||||
for _, optsWithID := range c.shardOpts() {
|
|
||||||
rcfg.AddShard(optsWithID.configID, optsWithID.shOpts)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = c.cfgObject.cfgLocalStorage.localStorage.Reload(rcfg)
|
|
||||||
if err != nil {
|
|
||||||
c.log.Error("storage engine configuration update", zap.Error(err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, component := range components {
|
|
||||||
err = component.reloadFunc()
|
|
||||||
if err != nil {
|
|
||||||
c.log.Error("updated configuration applying",
|
|
||||||
zap.String("component", component.name),
|
|
||||||
zap.Error(err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
c.log.Info("configuration has been reloaded successfully")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *cfg) shutdown() {
|
|
||||||
c.setHealthStatus(control.HealthStatus_SHUTTING_DOWN)
|
|
||||||
|
|
||||||
c.ctxCancel()
|
|
||||||
for i := range c.closers {
|
|
||||||
c.closers[len(c.closers)-1-i].fn()
|
|
||||||
}
|
|
||||||
close(c.internalErr)
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,10 +9,10 @@ import (
|
||||||
const (
|
const (
|
||||||
subsection = "apiclient"
|
subsection = "apiclient"
|
||||||
|
|
||||||
// DialTimeoutDefault is a default dial timeout of FrostFS API client connection.
|
// DialTimeoutDefault is a default dial timeout of NeoFS API client connection.
|
||||||
DialTimeoutDefault = 5 * time.Second
|
DialTimeoutDefault = 5 * time.Second
|
||||||
|
|
||||||
// StreamTimeoutDefault is a default timeout of FrostFS API streaming operation.
|
// StreamTimeoutDefault is a default timeout of NeoFS API streaming operation.
|
||||||
StreamTimeoutDefault = 15 * time.Second
|
StreamTimeoutDefault = 15 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue