[#161] adm: Refactor restore-containers command

Resolve funlen linter for restoreContainers function

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
pull/176/head
Dmitrii Stepanov 2023-03-22 17:25:35 +03:00 committed by Gitea
parent f2e880465e
commit 9534ade716
1 changed files with 79 additions and 38 deletions

View File

@ -152,7 +152,6 @@ func listContainers(cmd *cobra.Command, _ []string) error {
return nil
}
// nolint: funlen
func restoreContainers(cmd *cobra.Command, _ []string) error {
filename, err := cmd.Flags().GetString(containerDumpFlag)
if err != nil {
@ -165,25 +164,14 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
}
defer wCtx.close()
nnsCs, err := wCtx.Client.GetContractStateByID(1)
containers, err := parseContainers(filename)
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 {
return fmt.Errorf("can't fetch container contract hash: %w", 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)
return err
}
isOK, err := getCIDFilterFunc(cmd)
@ -191,6 +179,15 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
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()
for _, cnt := range containers {
hv := hash.Sha256(cnt.Value)
@ -198,33 +195,18 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
continue
}
bw.Reset()
emit.AppCall(bw.BinWriter, ch, "get", callflag.All, hv.BytesBE())
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
restored, err := isContainerRestored(cmd, wCtx, ch, bw, hv)
if err != nil {
return fmt.Errorf("can't check if container is already restored: %w", err)
return err
}
if len(res.Stack) == 0 {
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)
if restored {
continue
}
bw.Reset()
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)
}
putContainer(bw, ch, cnt)
if bw.Err != nil {
panic(bw.Err)
}
@ -233,8 +215,67 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
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.