From 10ad883dd20a88ecc740220a0b3ae1e11cb82e80 Mon Sep 17 00:00:00 2001 From: Giuseppe Lo Presti Date: Fri, 29 Nov 2024 15:39:14 +0100 Subject: [PATCH] WIP --- pkg/storage/utils/eosfs/config.go | 8 +- pkg/storage/utils/eosfs/eosfs.go | 119 ++++++++++++++++-------------- 2 files changed, 66 insertions(+), 61 deletions(-) diff --git a/pkg/storage/utils/eosfs/config.go b/pkg/storage/utils/eosfs/config.go index 6017edf671..1ca9516436 100644 --- a/pkg/storage/utils/eosfs/config.go +++ b/pkg/storage/utils/eosfs/config.go @@ -149,9 +149,6 @@ type Config struct { // revisions-related operations. ImpersonateOwnerforRevisions bool `mapstructure:"impersonate_owner_for_revisions"` - // Whether to enable the post create home hook - EnablePostCreateHomeHook bool `mapstructure:"enable_post_create_home_hook"` - // HTTP connections to EOS: max number of idle conns MaxIdleConns int `mapstructure:"max_idle_conns"` @@ -177,8 +174,9 @@ type Config struct { // Default is 3600 TokenExpiry int - // Path of the script to run after an user home folder has been created - OnPostCreateHomeHook string `mapstructure:"on_post_create_home_hook"` + // Path of the script to run in order to create a user home folder + // TODO(lopresti): to be replaced by a call to the Resource Lifecycle API being developed + CreateHomeHook string `mapstructure:"create_home_hook"` // Maximum entries count a ListRecycle call may return: if exceeded, ListRecycle // will return a BadRequest error diff --git a/pkg/storage/utils/eosfs/eosfs.go b/pkg/storage/utils/eosfs/eosfs.go index d231224756..f799ab6460 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -306,7 +306,7 @@ func (fs *eosfs) getInternalHome(ctx context.Context) (string, error) { u, err := getUser(ctx) if err != nil { - err = errors.Wrap(err, "eosfs: wrap: no user in ctx and home is enabled") + err = errors.Wrap(err, "eosfs: getInternalHome: no user in ctx and home is enabled") return "", err } @@ -314,11 +314,11 @@ func (fs *eosfs) getInternalHome(ctx context.Context) (string, error) { return relativeHome, nil } -func (fs *eosfs) wrapShadow(ctx context.Context, fn string) (internal string) { +func (fs *eosfs) wrapShadow(ctx context.Context, fn string) (internal string, err error) { if fs.conf.EnableHome { layout, err := fs.getInternalHome(ctx) if err != nil { - panic(err) + return "", err } internal = path.Join(fs.conf.ShadowNamespace, layout, fn) } else { @@ -327,11 +327,11 @@ func (fs *eosfs) wrapShadow(ctx context.Context, fn string) (internal string) { return } -func (fs *eosfs) wrap(ctx context.Context, fn string) (internal string) { +func (fs *eosfs) wrap(ctx context.Context, fn string) (internal string, err error) { if fs.conf.EnableHome { layout, err := fs.getInternalHome(ctx) if err != nil { - panic(err) + return "", err } internal = path.Join(fs.conf.Namespace, layout, fn) } else { @@ -397,7 +397,10 @@ func (fs *eosfs) resolveRefForbidShareFolder(ctx context.Context, ref *provider. if fs.isShareFolder(ctx, p) { return "", eosclient.Authorization{}, errtypes.PermissionDenied("eosfs: cannot perform operation under the virtual share folder") } - fn := fs.wrap(ctx, p) + fn, err := fs.wrap(ctx, p) + if err != nil { + return "", eosclient.Authorization{}, errors.Wrap(err, "eosfs: error wrapping reference") + } u, err := getUser(ctx) if err != nil { @@ -416,7 +419,10 @@ func (fs *eosfs) resolveRefAndGetAuth(ctx context.Context, ref *provider.Referen if err != nil { return "", eosclient.Authorization{}, errors.Wrap(err, "eosfs: error resolving reference") } - fn := fs.wrap(ctx, p) + fn, err := fs.wrap(ctx, p) + if err != nil { + return "", eosclient.Authorization{}, errors.Wrap(err, "eosfs: error wrapping reference") + } u, err := getUser(ctx) if err != nil { @@ -688,7 +694,10 @@ func (fs *eosfs) GetLock(ctx context.Context, ref *provider.Reference) (*provide if err != nil { return nil, errors.Wrap(err, "eosfs: error resolving reference") } - path = fs.wrap(ctx, path) + path, err := fs.wrap(ctx, path) + if err != nil { + return nil, errors.Wrap(err, "eosfs: error wrapping reference") + } user, err := getUser(ctx) if err != nil { @@ -1272,7 +1281,10 @@ func (fs *eosfs) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []st } } - fn := fs.wrap(ctx, p) + fn, err := fs.wrap(ctx, p) + if err != nil { + return nil, err + } eosFileInfo, err := fs.c.GetFileInfoByPath(ctx, auth, fn) if err != nil { return nil, err @@ -1282,7 +1294,10 @@ func (fs *eosfs) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []st } func (fs *eosfs) getMDShareFolder(ctx context.Context, p string, mdKeys []string) (*provider.ResourceInfo, error) { - fn := fs.wrapShadow(ctx, p) + fn, err := fs.wrapShadow(ctx, p) + if err != nil { + return nil, err + } auth, err := fs.getRootAuth(ctx) if err != nil { @@ -1365,7 +1380,10 @@ func (fs *eosfs) listWithNominalHome(ctx context.Context, p string) (finfos []*p } func (fs *eosfs) listShareFolderRoot(ctx context.Context, p string) (finfos []*provider.ResourceInfo, err error) { - fn := fs.wrapShadow(ctx, p) + fn, err := fs.wrapShadow(ctx, p) + if err != nil { + return nil, err + } u, err := getUser(ctx) if err != nil { @@ -1443,16 +1461,19 @@ func (fs *eosfs) createShadowHome(ctx context.Context) error { if err != nil { return errors.Wrap(err, "eosfs: no user in ctx") } - rootAuth, err := fs.getRootAuth(ctx) + auth, err := fs.getUserAuth(ctx, u, "") if err != nil { return nil } - home := fs.wrapShadow(ctx, "/") + home, err := fs.wrapShadow(ctx, "/") + if err != nil { + return err + } shadowFolders := []string{fs.conf.ShareFolder} for _, sf := range shadowFolders { fn := path.Join(home, sf) - _, err = fs.c.GetFileInfoByPath(ctx, rootAuth, fn) + _, err = fs.c.GetFileInfoByPath(ctx, auth, fn) if err != nil { if _, ok := err.(errtypes.IsNotFound); !ok { return errors.Wrap(err, "eosfs: error verifying if shadow directory exists") @@ -1477,17 +1498,13 @@ func (fs *eosfs) createNominalHome(ctx context.Context) error { if err != nil { return errors.Wrap(err, "eosfs: no user in ctx") } + auth, err := fs.getUserAuth(ctx, u, "") if err != nil { return err } - rootAuth, err := fs.getRootAuth(ctx) - if err != nil { - return nil - } - - _, err = fs.c.GetFileInfoByPath(ctx, rootAuth, home) + _, err = fs.c.GetFileInfoByPath(ctx, auth, home) if err == nil { // home already exists return nil } @@ -1496,40 +1513,23 @@ func (fs *eosfs) createNominalHome(ctx context.Context) error { return errors.Wrap(err, "eosfs: error verifying if user home directory exists") } - err = fs.createUserDir(ctx, u, home, false) - if err != nil { - err := errors.Wrap(err, "eosfs: error creating user dir") - return err - } - // set quota for user, depending on its type quotaBytes := fs.conf.DefaultQuotaBytes if u.Id.Type != userpb.UserType_USER_TYPE_PRIMARY { quotaBytes = fs.conf.DefaultSecondaryQuotaBytes } - quotaInfo := &eosclient.SetQuotaInfo{ - Username: u.Username, - UID: auth.Role.UID, - GID: auth.Role.GID, - MaxBytes: quotaBytes, - MaxFiles: fs.conf.DefaultQuotaFiles, - QuotaNode: fs.conf.QuotaNode, - } - err = fs.c.SetQuota(ctx, rootAuth, quotaInfo) - if err != nil { - err := errors.Wrap(err, "eosfs: error setting quota") - return err - } - - if fs.conf.EnablePostCreateHomeHook { - if err := fs.runPostCreateHomeHook(ctx); err != nil { + if fs.conf.CreateHomeHook != "" { + err = exec.Command(fs.conf.CreateHomeHook, u.Username, strconv.FormatUint(quotaBytes, 10), strconv.FormatUint(fs.conf.DefaultQuotaFiles, 10)).Run() + if err != nil { return errors.Wrap(err, "eosfs: error running post create home hook") } + } else { + return errtypes.NotFound("eosfs: create home hook not configured") } log := appctx.GetLogger(ctx) - log.Info().Interface("quotaInfo", quotaInfo).Interface("user", u.Id).Msg("created nominal home") + log.Info().Uint64("quotaBytes", quotaBytes).Interface("user", u.Id).Msg("created nominal home") return nil } @@ -1550,11 +1550,6 @@ func (fs *eosfs) CreateHome(ctx context.Context) error { return nil } -func (fs *eosfs) runPostCreateHomeHook(ctx context.Context) error { - user := appctx.ContextMustGetUser(ctx) - return exec.Command(fs.conf.OnPostCreateHomeHook, user.Username).Run() -} - func (fs *eosfs) createUserDir(ctx context.Context, u *userpb.User, path string, recursiveAttr bool) error { rootAuth, err := fs.getRootAuth(ctx) if err != nil { @@ -1666,18 +1661,21 @@ func (fs *eosfs) CreateReference(ctx context.Context, p string, targetURI *url.U return errors.Wrap(err, "eosfs: no user in ctx") } - fn := fs.wrapShadow(ctx, p) + fn, err := fs.wrapShadow(ctx, p) + if err != nil { + return err + } // TODO(labkode): with the grpc plugin we can create a file touching with xattrs. // Current mechanism is: touch to hidden dir, set xattr, rename. dir, base := path.Split(fn) tmp := path.Join(dir, fmt.Sprintf(".sys.reva#.%s", base)) - rootAuth, err := fs.getRootAuth(ctx) + auth, err := fs.getUserAuth(ctx, u, tmp) if err != nil { return nil } - if err := fs.createUserDir(ctx, u, tmp, false); err != nil { + if err := fs.c.CreateDir(ctx, auth, tmp); err != nil { err = errors.Wrapf(err, "eosfs: error creating temporary ref file") return err } @@ -1689,13 +1687,13 @@ func (fs *eosfs) CreateReference(ctx context.Context, p string, targetURI *url.U Val: targetURI.String(), } - if err := fs.c.SetAttr(ctx, rootAuth, attr, false, false, tmp, ""); err != nil { + if err := fs.c.SetAttr(ctx, auth, attr, false, false, tmp, ""); err != nil { err = errors.Wrapf(err, "eosfs: error setting reva.ref attr on file: %q", tmp) return err } // rename to have the file visible in user space. - if err := fs.c.Rename(ctx, rootAuth, tmp, fn); err != nil { + if err := fs.c.Rename(ctx, auth, tmp, fn); err != nil { err = errors.Wrapf(err, "eosfs: error renaming from: %q to %q", tmp, fn) return err } @@ -1733,7 +1731,10 @@ func (fs *eosfs) deleteShadow(ctx context.Context, p string) error { } if fs.isShareFolderChild(ctx, p) { - fn := fs.wrapShadow(ctx, p) + fn, err := fs.wrapShadow(ctx, p) + if err != nil { + return err + } // in order to remove the folder or the file without // moving it to the recycle bin, we should take @@ -1792,8 +1793,14 @@ func (fs *eosfs) moveShadow(ctx context.Context, oldPath, newPath string) error return errtypes.PermissionDenied("eosfs: cannot move references under the virtual share folder") } - oldfn := fs.wrapShadow(ctx, oldPath) - newfn := fs.wrapShadow(ctx, newPath) + oldfn, err := fs.wrapShadow(ctx, oldPath) + if err != nil { + return err + } + newfn, err := fs.wrapShadow(ctx, newPath) + if err != nil { + return err + } u, err := getUser(ctx) if err != nil {