[#1689] Add new command `morph list-containers` in `neofs-adm`

Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
fyrchik/simplify-services
Anton Nikiforov 2022-10-26 13:58:11 +03:00 committed by fyrchik
parent 98a152256b
commit 51e3810285
4 changed files with 80 additions and 15 deletions

View File

@ -4,6 +4,8 @@ Changelog for NeoFS Node
## [Unreleased] ## [Unreleased]
### Added ### Added
- `morph list-containers` in `neofs-adm` (#1689)
### Changed ### Changed
### Fixed ### Fixed
- Open FSTree in sync mode by default (#1992) - Open FSTree in sync mode by default (#1992)

View File

@ -90,6 +90,8 @@ info. These commands **do not migrate actual objects**.
- `restore-containers` restores previously saved containers by their repeated registration in - `restore-containers` restores previously saved containers by their repeated registration in
the container contract. the container contract.
- `list-containers` output all containers ids.
#### Network info #### Network info
- `dump-config` prints NeoFS network configuration. - `dump-config` prints NeoFS network configuration.

View File

@ -22,6 +22,37 @@ import (
var errInvalidContainerResponse = errors.New("invalid response from container contract") var errInvalidContainerResponse = errors.New("invalid response from container contract")
func getContainerContractHash(cmd *cobra.Command, inv *invoker.Invoker, c Client) (util.Uint160, error) {
s, err := cmd.Flags().GetString(containerContractFlag)
var ch util.Uint160
if err == nil {
ch, err = util.Uint160DecodeStringLE(s)
}
if err != nil {
nnsCs, err := c.GetContractStateByID(1)
if err != nil {
return util.Uint160{}, fmt.Errorf("can't get NNS contract state: %w", err)
}
ch, err = nnsResolveHash(inv, nnsCs.Hash, containerContract+".neofs")
if err != nil {
return util.Uint160{}, err
}
}
return ch, nil
}
func getContainersList(inv *invoker.Invoker, ch util.Uint160) ([][]byte, error) {
res, err := inv.Call(ch, "list", "")
if err != nil {
return nil, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
}
itm, err := unwrap.Item(res, err)
if _, ok := itm.(stackitem.Null); !ok {
return unwrap.ArrayOfBytes(res, err)
}
return nil, nil
}
func dumpContainers(cmd *cobra.Command, _ []string) error { func dumpContainers(cmd *cobra.Command, _ []string) error {
filename, err := cmd.Flags().GetString(containerDumpFlag) filename, err := cmd.Flags().GetString(containerDumpFlag)
if err != nil { if err != nil {
@ -35,24 +66,12 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
inv := invoker.New(c, nil) inv := invoker.New(c, nil)
nnsCs, err := c.GetContractStateByID(1) ch, err := getContainerContractHash(cmd, inv, c)
if err != nil { if err != nil {
return fmt.Errorf("can't get NNS contract state: %w", err) return fmt.Errorf("unable to get contaract hash: %w", err)
} }
var ch util.Uint160 cids, err := getContainersList(inv, ch)
s, err := cmd.Flags().GetString(containerContractFlag)
if err == nil {
ch, err = util.Uint160DecodeStringLE(s)
}
if err != nil {
ch, err = nnsResolveHash(inv, nnsCs.Hash, containerContract+".neofs")
if err != nil {
return err
}
}
cids, err := unwrap.ArrayOfBytes(inv.Call(ch, "list", ""))
if err != nil { if err != nil {
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err) return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
} }
@ -104,6 +123,35 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
return os.WriteFile(filename, out, 0o660) return os.WriteFile(filename, out, 0o660)
} }
func listContainers(cmd *cobra.Command, _ []string) error {
c, err := getN3Client(viper.GetViper())
if err != nil {
return fmt.Errorf("can't create N3 client: %w", err)
}
inv := invoker.New(c, nil)
ch, err := getContainerContractHash(cmd, inv, c)
if err != nil {
return fmt.Errorf("unable to get contaract hash: %w", err)
}
cids, err := getContainersList(inv, ch)
if err != nil {
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
}
for _, id := range cids {
var idCnr cid.ID
err = idCnr.Decode(id)
if err != nil {
return fmt.Errorf("unable to decode container id: %w", err)
}
cmd.Println(idCnr)
}
return nil
}
func restoreContainers(cmd *cobra.Command, _ []string) error { func restoreContainers(cmd *cobra.Command, _ []string) error {
filename, err := cmd.Flags().GetString(containerDumpFlag) filename, err := cmd.Flags().GetString(containerDumpFlag)
if err != nil { if err != nil {

View File

@ -209,6 +209,15 @@ var (
RunE: restoreContainers, RunE: restoreContainers,
} }
listContainersCmd = &cobra.Command{
Use: "list-containers",
Short: "List NeoFS containers",
PreRun: func(cmd *cobra.Command, _ []string) {
_ = viper.BindPFlag(endpointFlag, cmd.Flags().Lookup(endpointFlag))
},
RunE: listContainers,
}
depositNotaryCmd = &cobra.Command{ depositNotaryCmd = &cobra.Command{
Use: "deposit-notary", Use: "deposit-notary",
Short: "Deposit GAS for notary service", Short: "Deposit GAS for notary service",
@ -294,6 +303,10 @@ func init() {
restoreContainersCmd.Flags().String(containerDumpFlag, "", "File to restore containers from") restoreContainersCmd.Flags().String(containerDumpFlag, "", "File to restore containers from")
restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to restore") restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "Containers to restore")
RootCmd.AddCommand(listContainersCmd)
listContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
listContainersCmd.Flags().String(containerContractFlag, "", "Container contract hash (for networks without NNS)")
RootCmd.AddCommand(refillGasCmd) RootCmd.AddCommand(refillGasCmd)
refillGasCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir") refillGasCmd.Flags().String(alphabetWalletsFlag, "", "Path to alphabet wallets dir")
refillGasCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint") refillGasCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")