forked from TrueCloudLab/frostfs-node
[#161] adm: Refactor restore-containers command
Resolve funlen linter for restoreContainers function Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
f2e880465e
commit
9534ade716
1 changed files with 79 additions and 38 deletions
|
@ -152,7 +152,6 @@ func listContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// nolint: funlen
|
|
||||||
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 {
|
||||||
|
@ -165,25 +164,14 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
}
|
}
|
||||||
defer wCtx.close()
|
defer wCtx.close()
|
||||||
|
|
||||||
nnsCs, err := wCtx.Client.GetContractStateByID(1)
|
containers, err := parseContainers(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't get NNS contract state: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ch, err := nnsResolveHash(wCtx.ReadOnlyInvoker, nnsCs.Hash, containerContract+".frostfs")
|
ch, err := fetchContainerContractHash(wCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't fetch container contract hash: %w", err)
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
data, err := os.ReadFile(filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("can't read dump file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var containers []Container
|
|
||||||
err = json.Unmarshal(data, &containers)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("can't parse dump file: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isOK, err := getCIDFilterFunc(cmd)
|
isOK, err := getCIDFilterFunc(cmd)
|
||||||
|
@ -191,6 +179,15 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = restoreOrPutContainers(containers, isOK, cmd, wCtx, ch)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return wCtx.awaitTx()
|
||||||
|
}
|
||||||
|
|
||||||
|
func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd *cobra.Command, wCtx *initializeContext, ch util.Uint160) error {
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
for _, cnt := range containers {
|
for _, cnt := range containers {
|
||||||
hv := hash.Sha256(cnt.Value)
|
hv := hash.Sha256(cnt.Value)
|
||||||
|
@ -198,33 +195,18 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
bw.Reset()
|
bw.Reset()
|
||||||
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, hv.BytesBE())
|
restored, err := isContainerRestored(cmd, wCtx, ch, bw, hv)
|
||||||
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't check if container is already restored: %w", err)
|
return err
|
||||||
}
|
}
|
||||||
if len(res.Stack) == 0 {
|
if restored {
|
||||||
return errors.New("empty stack")
|
|
||||||
}
|
|
||||||
|
|
||||||
old := new(Container)
|
|
||||||
if err := old.FromStackItem(res.Stack[0]); err != nil {
|
|
||||||
return fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
|
||||||
}
|
|
||||||
if len(old.Value) != 0 {
|
|
||||||
var id cid.ID
|
|
||||||
id.SetSHA256(hv)
|
|
||||||
cmd.Printf("Container %s is already deployed.\n", id)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
bw.Reset()
|
bw.Reset()
|
||||||
emit.AppCall(bw.BinWriter, ch, "put", callflag.All,
|
|
||||||
cnt.Value, cnt.Signature, cnt.PublicKey, cnt.Token)
|
putContainer(bw, ch, cnt)
|
||||||
if ea := cnt.EACL; ea != nil {
|
|
||||||
emit.AppCall(bw.BinWriter, ch, "setEACL", callflag.All,
|
|
||||||
ea.Value, ea.Signature, ea.PublicKey, ea.Token)
|
|
||||||
}
|
|
||||||
if bw.Err != nil {
|
if bw.Err != nil {
|
||||||
panic(bw.Err)
|
panic(bw.Err)
|
||||||
}
|
}
|
||||||
|
@ -233,8 +215,67 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
return wCtx.awaitTx()
|
func putContainer(bw *io.BufBinWriter, ch util.Uint160, cnt Container) {
|
||||||
|
emit.AppCall(bw.BinWriter, ch, "put", callflag.All,
|
||||||
|
cnt.Value, cnt.Signature, cnt.PublicKey, cnt.Token)
|
||||||
|
if ea := cnt.EACL; ea != nil {
|
||||||
|
emit.AppCall(bw.BinWriter, ch, "setEACL", callflag.All,
|
||||||
|
ea.Value, ea.Signature, ea.PublicKey, ea.Token)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isContainerRestored(cmd *cobra.Command, wCtx *initializeContext, containerHash util.Uint160, bw *io.BufBinWriter, hashValue util.Uint256) (bool, error) {
|
||||||
|
emit.AppCall(bw.BinWriter, containerHash, "get", callflag.All, hashValue.BytesBE())
|
||||||
|
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("can't check if container is already restored: %w", err)
|
||||||
|
}
|
||||||
|
if len(res.Stack) == 0 {
|
||||||
|
return false, errors.New("empty stack")
|
||||||
|
}
|
||||||
|
|
||||||
|
old := new(Container)
|
||||||
|
if err := old.FromStackItem(res.Stack[0]); err != nil {
|
||||||
|
return false, fmt.Errorf("%w: %v", errInvalidContainerResponse, err)
|
||||||
|
}
|
||||||
|
if len(old.Value) != 0 {
|
||||||
|
var id cid.ID
|
||||||
|
id.SetSHA256(hashValue)
|
||||||
|
cmd.Printf("Container %s is already deployed.\n", id)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseContainers(filename string) ([]Container, error) {
|
||||||
|
data, err := os.ReadFile(filename)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("can't read dump file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var containers []Container
|
||||||
|
err = json.Unmarshal(data, &containers)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("can't parse dump file: %w", err)
|
||||||
|
}
|
||||||
|
return containers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchContainerContractHash(wCtx *initializeContext) (util.Uint160, error) {
|
||||||
|
nnsCs, err := wCtx.Client.GetContractStateByID(1)
|
||||||
|
if err != nil {
|
||||||
|
return util.Uint160{}, fmt.Errorf("can't get NNS contract state: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := nnsResolveHash(wCtx.ReadOnlyInvoker, nnsCs.Hash, containerContract+".frostfs")
|
||||||
|
if err != nil {
|
||||||
|
return util.Uint160{}, fmt.Errorf("can't fetch container contract hash: %w", err)
|
||||||
|
}
|
||||||
|
return ch, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Container represents container struct in contract storage.
|
// Container represents container struct in contract storage.
|
||||||
|
|
Loading…
Reference in a new issue