From f242b536f1dbd0514b64d1c13648dbe9e475acd8 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 | 168 ++++++++++-------------------- 2 files changed, 60 insertions(+), 116 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 4436262d91..dcc35b84e0 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -289,50 +289,27 @@ func getUser(ctx context.Context) (*userpb.User, error) { func (fs *eosfs) getLayout(ctx context.Context) (layout string) { if fs.conf.EnableHome { - u, err := getUser(ctx) - if err != nil { - panic(err) - } + u := ctx.ContextMustGetUser(ctx) layout = templates.WithUser(u, fs.conf.UserLayout) } return } -func (fs *eosfs) getInternalHome(ctx context.Context) (string, error) { +func (fs *eosfs) getInternalHome(ctx context.Context) (string) { if !fs.conf.EnableHome { - return "", errtypes.NotSupported("eos: get home not supported") - } - - u, err := getUser(ctx) - if err != nil { - err = errors.Wrap(err, "eosfs: wrap: no user in ctx and home is enabled") - return "", err + // TODO(lopresti): this is to be removed as we always want to support home, + // cf. https://github.com/cs3org/reva/pull/4940 + return "/" } + u := ctx.ContextMustGetUser(ctx) relativeHome := templates.WithUser(u, fs.conf.UserLayout) - return relativeHome, nil -} - -func (fs *eosfs) wrapShadow(ctx context.Context, fn string) (internal string) { - if fs.conf.EnableHome { - layout, err := fs.getInternalHome(ctx) - if err != nil { - panic(err) - } - internal = path.Join(fs.conf.ShadowNamespace, layout, fn) - } else { - internal = path.Join(fs.conf.ShadowNamespace, fn) - } - return + return relativeHome } func (fs *eosfs) wrap(ctx context.Context, fn string) (internal string) { if fs.conf.EnableHome { - layout, err := fs.getInternalHome(ctx) - if err != nil { - panic(err) - } - internal = path.Join(fs.conf.Namespace, layout, fn) + internal = path.Join(fs.conf.Namespace, fs.getInternalHome(ctx), fn) } else { internal = path.Join(fs.conf.Namespace, fn) } @@ -396,7 +373,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 { @@ -415,7 +395,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 { @@ -668,7 +651,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 { @@ -1205,7 +1191,10 @@ func (fs *eosfs) GetMD(ctx context.Context, ref *provider.Reference, mdKeys []st } p := ref.Path - fn := fs.wrap(ctx, p) + fn, err := fs.wrap(ctx, p) + if err != nil { + return nil, err + } // We use daemon for auth because we need access to the file in order to stat it // We cannot use the current user, because the file may be a shared file @@ -1256,7 +1245,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 := utils.GetDaemonAuth() @@ -1336,7 +1328,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 { @@ -1406,37 +1401,6 @@ func (fs *eosfs) GetHome(ctx context.Context) (string, error) { return "/", nil } -func (fs *eosfs) createShadowHome(ctx context.Context) error { - u, err := getUser(ctx) - if err != nil { - return errors.Wrap(err, "eosfs: no user in ctx") - } - - daemonAuth := utils.GetDaemonAuth() - - home := fs.wrapShadow(ctx, "/") - shadowFolders := []string{fs.conf.ShareFolder} - - for _, sf := range shadowFolders { - fn := path.Join(home, sf) - _, err = fs.c.GetFileInfoByPath(ctx, daemonAuth, fn) - if err != nil { - if _, ok := err.(errtypes.IsNotFound); !ok { - return errors.Wrap(err, "eosfs: error verifying if shadow directory exists") - } - err = fs.createUserDir(ctx, u, fn, false) - if err != nil { - return err - } - } - } - - log := appctx.GetLogger(ctx) - log.Info().Str("home", home).Interface("user", u.Id).Msg("created shadow home") - - return nil -} - func (fs *eosfs) createNominalHome(ctx context.Context) error { home := fs.wrap(ctx, "/") @@ -1444,17 +1408,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 } @@ -1463,40 +1423,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 } @@ -1510,18 +1453,9 @@ func (fs *eosfs) CreateHome(ctx context.Context) error { return errors.Wrap(err, "eosfs: error creating nominal home") } - if err := fs.createShadowHome(ctx); err != nil { - return errors.Wrap(err, "eosfs: error creating shadow home") - } - 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 { @@ -1633,7 +1567,10 @@ 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. @@ -1641,7 +1578,7 @@ func (fs *eosfs) CreateReference(ctx context.Context, p string, targetURI *url.U tmp := path.Join(dir, fmt.Sprintf(".sys.reva#.%s", base)) cboxAuth := utils.GetEmptyAuth() - 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 } @@ -1697,7 +1634,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 @@ -1756,8 +1696,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 {