forked from TrueCloudLab/frostfs-node
[#1593] adm: Support changing network config
Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
1e034c8d48
commit
466b9b4273
3 changed files with 110 additions and 0 deletions
|
@ -70,6 +70,8 @@ credentials: # passwords for consensus node / alphabet wallets
|
||||||
|
|
||||||
#### Network maintenance
|
#### Network maintenance
|
||||||
|
|
||||||
|
- `set-config` add/update configuration values in the Netmap contract.
|
||||||
|
|
||||||
- `force-new-epoch` increments NeoFS epoch number and executes new epoch
|
- `force-new-epoch` increments NeoFS epoch number and executes new epoch
|
||||||
handlers in NeoFS nodes.
|
handlers in NeoFS nodes.
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
|
@ -21,6 +23,8 @@ import (
|
||||||
|
|
||||||
const lastGlagoliticLetter = 41
|
const lastGlagoliticLetter = 41
|
||||||
|
|
||||||
|
const forceConfigSet = "force"
|
||||||
|
|
||||||
type contractDumpInfo struct {
|
type contractDumpInfo struct {
|
||||||
hash util.Uint160
|
hash util.Uint160
|
||||||
name string
|
name string
|
||||||
|
@ -209,3 +213,90 @@ func dumpNetworkConfig(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setConfigCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return errors.New("empty config pairs")
|
||||||
|
}
|
||||||
|
|
||||||
|
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't initialize context: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cs, err := wCtx.Client.GetContractStateByID(1)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't get NNS contract info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nmHash, err := nnsResolveHash(wCtx.Client, cs.Hash, netmapContract+".neofs")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't get netmap contract hash: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
forceFlag, _ := cmd.Flags().GetBool(forceConfigSet)
|
||||||
|
|
||||||
|
bw := io.NewBufBinWriter()
|
||||||
|
for _, arg := range args {
|
||||||
|
k, v, err := parseConfigPair(arg, forceFlag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// In NeoFS this is done via Notary contract. Here, however, we can form the
|
||||||
|
// transaction locally. The first `nil` argument is required only for notary
|
||||||
|
// disabled environment which is not supported by that command.
|
||||||
|
emit.AppCall(bw.BinWriter, nmHash, "setConfig", callflag.All, nil, k, v)
|
||||||
|
if bw.Err != nil {
|
||||||
|
return fmt.Errorf("can't form raw transaction: %w", bw.Err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = wCtx.sendCommitteeTx(bw.Bytes(), -1, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return wCtx.awaitTx()
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseConfigPair(kvStr string, force bool) (key string, val interface{}, err error) {
|
||||||
|
kv := strings.SplitN(kvStr, "=", 2)
|
||||||
|
if len(kv) != 2 {
|
||||||
|
return "", nil, fmt.Errorf("invalid parameter format: must be 'key=val', got: %s", kvStr)
|
||||||
|
}
|
||||||
|
|
||||||
|
key = kv[0]
|
||||||
|
valRaw := kv[1]
|
||||||
|
|
||||||
|
switch key {
|
||||||
|
case netmapAuditFeeKey, netmapBasicIncomeRateKey,
|
||||||
|
netmapContainerFeeKey, netmapContainerAliasFeeKey,
|
||||||
|
netmapEigenTrustIterationsKey,
|
||||||
|
netmapEpochKey, netmapInnerRingCandidateFeeKey,
|
||||||
|
netmapMaxObjectSizeKey, netmapWithdrawFeeKey:
|
||||||
|
val, err = strconv.ParseInt(valRaw, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("could not parse %s's value '%s' as int: %w", key, valRaw, err)
|
||||||
|
}
|
||||||
|
case netmapEigenTrustAlphaKey:
|
||||||
|
// just check that it could
|
||||||
|
// be parsed correctly
|
||||||
|
_, err = strconv.ParseFloat(kv[1], 64)
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("could not parse %s's value '%s' as float: %w", key, valRaw, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
val = valRaw
|
||||||
|
default:
|
||||||
|
if !force {
|
||||||
|
return "", nil, fmt.Errorf(
|
||||||
|
"'%s' key is not well-known, use '--%s' flag if want to set it anyway",
|
||||||
|
key, forceConfigSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
val = valRaw
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
|
@ -122,6 +122,18 @@ var (
|
||||||
RunE: removeNodesCmd,
|
RunE: removeNodesCmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setConfig = &cobra.Command{
|
||||||
|
Use: "set-config key1=val1 [key2=val2 ...]",
|
||||||
|
DisableFlagsInUseLine: true,
|
||||||
|
Short: "Add/update global config value in the NeoFS network",
|
||||||
|
PreRun: func(cmd *cobra.Command, _ []string) {
|
||||||
|
_ = viper.BindPFlag(alphabetWalletsFlag, cmd.Flags().Lookup(alphabetWalletsFlag))
|
||||||
|
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
|
||||||
|
},
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
RunE: setConfigCmd,
|
||||||
|
}
|
||||||
|
|
||||||
setPolicy = &cobra.Command{
|
setPolicy = &cobra.Command{
|
||||||
Use: "set-policy [ExecFeeFactor=<n1>] [StoragePrice=<n2>] [FeePerByte=<n3>]",
|
Use: "set-policy [ExecFeeFactor=<n1>] [StoragePrice=<n2>] [FeePerByte=<n3>]",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
|
@ -241,6 +253,11 @@ func init() {
|
||||||
RootCmd.AddCommand(dumpNetworkConfigCmd)
|
RootCmd.AddCommand(dumpNetworkConfigCmd)
|
||||||
dumpNetworkConfigCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
dumpNetworkConfigCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
|
|
||||||
|
RootCmd.AddCommand(setConfig)
|
||||||
|
setConfig.Flags().String(alphabetWalletsFlag, "", "path to alphabet wallets dir")
|
||||||
|
setConfig.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
|
setConfig.Flags().Bool(forceConfigSet, false, "Force setting not well-known configuration key")
|
||||||
|
|
||||||
RootCmd.AddCommand(dumpBalancesCmd)
|
RootCmd.AddCommand(dumpBalancesCmd)
|
||||||
dumpBalancesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
dumpBalancesCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||||
dumpBalancesCmd.Flags().BoolP(dumpBalancesStorageFlag, "s", false, "dump balances of storage nodes from the current netmap")
|
dumpBalancesCmd.Flags().BoolP(dumpBalancesStorageFlag, "s", false, "dump balances of storage nodes from the current netmap")
|
||||||
|
|
Loading…
Reference in a new issue