package container import ( "fmt" "time" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user" "github.com/spf13/cobra" ) var deleteContainerCmd = &cobra.Command{ Use: "delete", Short: "Delete existing container", Long: `Delete existing container. Only owner of the container has a permission to remove container.`, Run: func(cmd *cobra.Command, _ []string) { id := parseContainerID(cmd) tok := getSession(cmd) pk := key.Get(cmd) cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC) if force, _ := cmd.Flags().GetBool(commonflags.ForceFlag); !force { common.PrintVerbose(cmd, "Reading the container to check ownership...") getPrm := internalclient.GetContainerPrm{ Client: cli, ClientParams: client.PrmContainerGet{ ContainerID: &id, }, } resGet, err := internalclient.GetContainer(cmd.Context(), getPrm) commonCmd.ExitOnErr(cmd, "can't get the container: %w", err) owner := resGet.Container().Owner() if tok != nil { common.PrintVerbose(cmd, "Checking session issuer...") if !tok.Issuer().Equals(owner) { commonCmd.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer())) } } else { common.PrintVerbose(cmd, "Checking provided account...") var acc user.ID user.IDFromKey(&acc, pk.PublicKey) if !acc.Equals(owner) { commonCmd.ExitOnErr(cmd, "", fmt.Errorf("provided account differs with the container owner: expected %s, has %s", owner, acc)) } } common.PrintVerbose(cmd, "Account matches the container owner.") if tok != nil { common.PrintVerbose(cmd, "Skip searching for LOCK objects - session provided.") } else { fs := objectSDK.NewSearchFilters() fs.AddTypeFilter(objectSDK.MatchStringEqual, objectSDK.TypeLock) var searchPrm internalclient.SearchObjectsPrm searchPrm.SetClient(cli) searchPrm.SetContainerID(id) searchPrm.SetFilters(fs) searchPrm.SetTTL(2) common.PrintVerbose(cmd, "Searching for LOCK objects...") res, err := internalclient.SearchObjects(cmd.Context(), searchPrm) commonCmd.ExitOnErr(cmd, "can't search for LOCK objects: %w", err) if len(res.IDList()) != 0 { commonCmd.ExitOnErr(cmd, "", fmt.Errorf("container wasn't removed because LOCK objects were found, "+ "use --%s flag to remove anyway", commonflags.ForceFlag)) } } } delPrm := internalclient.DeleteContainerPrm{ Client: cli, ClientParams: client.PrmContainerDelete{ ContainerID: &id, Session: tok, }, } _, err := internalclient.DeleteContainer(cmd.Context(), delPrm) commonCmd.ExitOnErr(cmd, "rpc error: %w", err) cmd.Println("container delete method invoked") if containerAwait { cmd.Println("awaiting...") getPrm := internalclient.GetContainerPrm{ Client: cli, ClientParams: client.PrmContainerGet{ ContainerID: &id, }, } for i := 0; i < awaitTimeout; i++ { time.Sleep(1 * time.Second) _, err := internalclient.GetContainer(cmd.Context(), getPrm) if err != nil { cmd.Println("container has been removed:", containerID) return } } commonCmd.ExitOnErr(cmd, "", errDeleteTimeout) } }, } func initContainerDeleteCmd() { flags := deleteContainerCmd.Flags() flags.StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, commonflags.WalletPathDefault, commonflags.WalletPathUsage) flags.StringP(commonflags.Account, commonflags.AccountShorthand, commonflags.AccountDefault, commonflags.AccountUsage) flags.StringP(commonflags.RPC, commonflags.RPCShorthand, commonflags.RPCDefault, commonflags.RPCUsage) flags.Bool(commonflags.TracingFlag, false, commonflags.TracingFlagUsage) flags.StringVar(&containerID, commonflags.CIDFlag, "", commonflags.CIDFlagUsage) flags.BoolVar(&containerAwait, "await", false, "Block execution until container is removed") flags.BoolP(commonflags.ForceFlag, commonflags.ForceFlagShorthand, false, "Skip validation checks (ownership, presence of LOCK objects)") }