forked from TrueCloudLab/frostfs-node
[#755] neofs-adm: allow to filter containers by ID
`--cid <cid1> --cid <cid2>` as well as `--cid <cid1>,<cid2>` is supported. Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
00a299c1a4
commit
72b8d919fe
2 changed files with 51 additions and 0 deletions
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||
|
@ -67,9 +68,17 @@ func dumpContainers(cmd *cobra.Command, _ []string) error {
|
|||
cids = append(cids, id)
|
||||
}
|
||||
|
||||
isOK, err := getCIDFilterFunc(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var containers []*Container
|
||||
bw := io.NewBufBinWriter()
|
||||
for _, id := range cids {
|
||||
if !isOK(id) {
|
||||
continue
|
||||
}
|
||||
bw.Reset()
|
||||
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, id)
|
||||
emit.AppCall(bw.BinWriter, ch, "eACL", callflag.All, id)
|
||||
|
@ -138,9 +147,17 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
|||
return fmt.Errorf("can't parse dump file: %w", err)
|
||||
}
|
||||
|
||||
isOK, err := getCIDFilterFunc(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
bw := io.NewBufBinWriter()
|
||||
for _, cnt := range containers {
|
||||
hv := hash.Sha256(cnt.Value)
|
||||
if !isOK(hv[:]) {
|
||||
continue
|
||||
}
|
||||
bw.Reset()
|
||||
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, hv.BytesBE())
|
||||
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
||||
|
@ -285,3 +302,34 @@ func (c *EACL) FromStackItem(item stackitem.Item) error {
|
|||
c.Token = tok
|
||||
return nil
|
||||
}
|
||||
|
||||
// getCIDFilterFunc returns filtering function for container IDs.
|
||||
// Raw byte slices are used because it works with structures returned
|
||||
// from contract.
|
||||
func getCIDFilterFunc(cmd *cobra.Command) (func([]byte) bool, error) {
|
||||
rawIDs, err := cmd.Flags().GetStringSlice(containerIDsFlag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rawIDs) == 0 {
|
||||
return func([]byte) bool { return true }, nil
|
||||
}
|
||||
|
||||
for i := range rawIDs {
|
||||
err := cid.New().Parse(rawIDs[i])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't parse CID %s: %w", rawIDs[i], err)
|
||||
}
|
||||
}
|
||||
sort.Strings(rawIDs)
|
||||
return func(rawID []byte) bool {
|
||||
var v [32]byte
|
||||
copy(v[:], rawID)
|
||||
|
||||
id := cid.New()
|
||||
id.SetSHA256(v)
|
||||
idStr := id.String()
|
||||
n := sort.Search(len(rawIDs), func(i int) bool { return rawIDs[i] >= idStr })
|
||||
return n < len(rawIDs) && rawIDs[n] == idStr
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ const (
|
|||
withdrawFeeCLIFlag = "withdraw-fee"
|
||||
containerDumpFlag = "dump"
|
||||
containerContractFlag = "container-contract"
|
||||
containerIDsFlag = "cid"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -171,9 +172,11 @@ func init() {
|
|||
dumpContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
dumpContainersCmd.Flags().String(containerDumpFlag, "", "file where to save dumped containers")
|
||||
dumpContainersCmd.Flags().String(containerContractFlag, "", "container contract hash (for networks without NNS)")
|
||||
dumpContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "containers to dump")
|
||||
|
||||
RootCmd.AddCommand(restoreContainersCmd)
|
||||
restoreContainersCmd.Flags().String(alphabetWalletsFlag, "", "path to alphabet wallets dir")
|
||||
restoreContainersCmd.Flags().StringP(endpointFlag, "r", "", "N3 RPC node endpoint")
|
||||
restoreContainersCmd.Flags().String(containerDumpFlag, "", "file to restore containers from")
|
||||
restoreContainersCmd.Flags().StringSlice(containerIDsFlag, nil, "containers to restore")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue