From f02ca844ad8e5eeabdb7e4a4d5f04bdbabcee02d Mon Sep 17 00:00:00 2001 From: Illyoung Choi Date: Fri, 29 Mar 2024 14:06:48 -0700 Subject: [PATCH] Add rmmeta --- cmd/gocmd.go | 1 + cmd/subcmd/rmmeta.go | 225 +++++++++++++++++++++++++++++++++++++++++ cmd/subcmd/rmticket.go | 2 +- commons/number.go | 11 ++ 4 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 cmd/subcmd/rmmeta.go create mode 100644 commons/number.go diff --git a/cmd/gocmd.go b/cmd/gocmd.go index 48f9a68..e2b58df 100644 --- a/cmd/gocmd.go +++ b/cmd/gocmd.go @@ -91,6 +91,7 @@ func main() { subcmd.AddPsCommand(rootCmd) subcmd.AddLsmetaCommand(rootCmd) subcmd.AddAddmetaCommand(rootCmd) + subcmd.AddRmmetaCommand(rootCmd) subcmd.AddCopySftpIdCommand(rootCmd) subcmd.AddLsticketCommand(rootCmd) subcmd.AddRmticketCommand(rootCmd) diff --git a/cmd/subcmd/rmmeta.go b/cmd/subcmd/rmmeta.go new file mode 100644 index 0000000..e272e5d --- /dev/null +++ b/cmd/subcmd/rmmeta.go @@ -0,0 +1,225 @@ +package subcmd + +import ( + "strconv" + + irodsclient_fs "github.com/cyverse/go-irodsclient/fs" + "github.com/cyverse/gocommands/cmd/flag" + "github.com/cyverse/gocommands/commons" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "golang.org/x/xerrors" +) + +var rmmetaCmd = &cobra.Command{ + Use: "rmmeta [AVU ID|attribute name] ...", + Aliases: []string{"rm_meta", "remove_meta", "rm_metadata", "remove_metadata", "delete_meta", "delete_metadata"}, + Short: "Remove metadatas for the user", + Long: `This removes metadata of the given collection, data object, user, or a resource.`, + RunE: processRmmetaCommand, + Args: cobra.MinimumNArgs(1), +} + +func AddRmmetaCommand(rootCmd *cobra.Command) { + // attach common flags + flag.SetCommonFlags(rmmetaCmd, true) + + flag.SetTargetObjectFlags(rmmetaCmd) + + rootCmd.AddCommand(rmmetaCmd) +} + +func processRmmetaCommand(command *cobra.Command, args []string) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "processRmmetaCommand", + }) + + cont, err := flag.ProcessCommonFlags(command) + if err != nil { + return xerrors.Errorf("failed to process common flags: %w", err) + } + + if !cont { + return nil + } + + // handle local flags + _, err = commons.InputMissingFields() + if err != nil { + return xerrors.Errorf("failed to input missing fields: %w", err) + } + + targetObjectFlagValues := flag.GetTargetObjectFlagValues(command) + + // Create a file system + account := commons.GetAccount() + filesystem, err := commons.GetIRODSFSClient(account) + if err != nil { + return xerrors.Errorf("failed to get iRODS FS Client: %w", err) + } + + defer filesystem.Release() + + for _, avuidString := range args { + if commons.IsDigitsOnly(avuidString) { + // avuid + avuid, err := strconv.ParseInt(avuidString, 10, 64) + if err != nil { + return xerrors.Errorf("failed to parse AVUID: %w", err) + } + + if targetObjectFlagValues.PathUpdated { + err = removeMetaFromPath(filesystem, targetObjectFlagValues.Path, avuid) + if err != nil { + return err + } + } else if targetObjectFlagValues.UserUpdated { + err = removeMetaFromUser(filesystem, targetObjectFlagValues.User, avuid) + if err != nil { + return err + } + } else if targetObjectFlagValues.ResourceUpdated { + err = removeMetaFromResource(filesystem, targetObjectFlagValues.Resource, avuid) + if err != nil { + return err + } + } else { + // nothing updated + return xerrors.Errorf("path, user, or resource must be given") + } + } else { + // possibly name + attr := avuidString + logger.Debugf("remove metadata with name %s", attr) + + if targetObjectFlagValues.PathUpdated { + err = removeMetaFromPathByName(filesystem, targetObjectFlagValues.Path, attr) + if err != nil { + return err + } + } else if targetObjectFlagValues.UserUpdated { + err = removeMetaFromUserByName(filesystem, targetObjectFlagValues.User, attr) + if err != nil { + return err + } + } else if targetObjectFlagValues.ResourceUpdated { + err = removeMetaFromResourceByName(filesystem, targetObjectFlagValues.Resource, attr) + if err != nil { + return err + } + } else { + // nothing updated + return xerrors.Errorf("path, user, or resource must be given") + } + } + + } + return nil +} + +func removeMetaFromPath(fs *irodsclient_fs.FileSystem, targetPath string, avuid int64) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "removeMetaFromPath", + }) + + logger.Debugf("remove metadata %d from path %s", avuid, targetPath) + + cwd := commons.GetCWD() + home := commons.GetHomeDir() + zone := commons.GetZone() + targetPath = commons.MakeIRODSPath(cwd, home, zone, targetPath) + + err := fs.DeleteMetadata(targetPath, avuid) + if err != nil { + return xerrors.Errorf("failed to delete metadata %d from path %s: %w", avuid, targetPath, err) + } + + return nil +} + +func removeMetaFromUser(fs *irodsclient_fs.FileSystem, username string, avuid int64) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "removeMetaFromUser", + }) + + logger.Debugf("remove metadata %d from user %s", avuid, username) + + err := fs.DeleteUserMetadata(username, avuid) + if err != nil { + return xerrors.Errorf("failed to delete metadata %d from user %s: %w", avuid, username, err) + } + + return nil +} + +func removeMetaFromResource(fs *irodsclient_fs.FileSystem, resource string, avuid int64) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "removeMetaFromResource", + }) + + logger.Debugf("remove metadata %d from resource %s", avuid, resource) + + err := fs.DeleteResourceMetadata(resource, avuid) + if err != nil { + return xerrors.Errorf("failed to delete metadata %d from resource %s: %w", avuid, resource, err) + } + + return nil +} + +func removeMetaFromPathByName(fs *irodsclient_fs.FileSystem, targetPath string, attr string) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "removeMetaFromPathByName", + }) + + logger.Debugf("remove metadata %s from path %s by name", attr, targetPath) + + cwd := commons.GetCWD() + home := commons.GetHomeDir() + zone := commons.GetZone() + targetPath = commons.MakeIRODSPath(cwd, home, zone, targetPath) + + err := fs.DeleteMetadataByName(targetPath, attr) + if err != nil { + return xerrors.Errorf("failed to delete metadata %s from path %s by name: %w", attr, targetPath, err) + } + + return nil +} + +func removeMetaFromUserByName(fs *irodsclient_fs.FileSystem, username string, attr string) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "removeMetaFromUserByName", + }) + + logger.Debugf("remove metadata %s from user %s by name", attr, username) + + err := fs.DeleteUserMetadataByName(username, attr) + if err != nil { + return xerrors.Errorf("failed to delete metadata %s from user %s by name: %w", attr, username, err) + } + + return nil +} + +func removeMetaFromResourceByName(fs *irodsclient_fs.FileSystem, resource string, attr string) error { + logger := log.WithFields(log.Fields{ + "package": "subcmd", + "function": "removeMetaFromResourceByName", + }) + + logger.Debugf("remove metadata %s from resource %s by name", attr, resource) + + err := fs.DeleteResourceMetadataByName(resource, attr) + if err != nil { + return xerrors.Errorf("failed to delete metadata %s from resource %s by name: %w", attr, resource, err) + } + + return nil +} diff --git a/cmd/subcmd/rmticket.go b/cmd/subcmd/rmticket.go index cb403d9..0845a3c 100644 --- a/cmd/subcmd/rmticket.go +++ b/cmd/subcmd/rmticket.go @@ -53,7 +53,7 @@ func processRmticketCommand(command *cobra.Command, args []string) error { for _, ticketName := range args { err = removeTicket(filesystem, ticketName) if err != nil { - return xerrors.Errorf("failed to perform remove ticket %s: %w", ticketName, err) + return err } } return nil diff --git a/commons/number.go b/commons/number.go new file mode 100644 index 0000000..5567429 --- /dev/null +++ b/commons/number.go @@ -0,0 +1,11 @@ +package commons + +// IsDigitsOnly checks if the given string contains only digits +func IsDigitsOnly(s string) bool { + for _, c := range s { + if c < '0' || c > '9' { + return false + } + } + return true +}