From 79ac4947a3a75e2d35ff425d04b7e02b6989d148 Mon Sep 17 00:00:00 2001 From: Giuseppe Lo Presti Date: Mon, 2 Dec 2024 18:18:41 +0100 Subject: [PATCH] Replaced home creation function with external script, removed shadow namespace and related code --- pkg/storage/utils/eosfs/config.go | 15 ++---- pkg/storage/utils/eosfs/eosfs.go | 79 ++++++++----------------------- pkg/storage/utils/eosfs/upload.go | 4 -- 3 files changed, 23 insertions(+), 75 deletions(-) diff --git a/pkg/storage/utils/eosfs/config.go b/pkg/storage/utils/eosfs/config.go index 6017edf671..b1e459b16a 100644 --- a/pkg/storage/utils/eosfs/config.go +++ b/pkg/storage/utils/eosfs/config.go @@ -35,16 +35,9 @@ type Config struct { // DefaultQuotaFiles sets the default maximum files available for a user DefaultQuotaFiles uint64 `mapstructure:"default_quota_files"` - // ShadowNamespace for storing shadow data - ShadowNamespace string `mapstructure:"shadow_namespace"` - // UploadsNamespace for storing upload data UploadsNamespace string `mapstructure:"uploads_namespace"` - // ShareFolder defines the name of the folder in the - // shadowed namespace. Ex: /eos/user/.shadow/h/hugo/MyShares - ShareFolder string `mapstructure:"share_folder"` - // Location of the eos binary. // Default is /usr/bin/eos. EosBinary string `mapstructure:"eos_binary"` @@ -149,9 +142,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 +167,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 4ba982519e..14121c67ed 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -86,10 +86,6 @@ func (c *Config) ApplyDefaults() { c.Namespace = "/" } - if c.ShadowNamespace == "" { - c.ShadowNamespace = path.Join(c.Namespace, ".shadow") - } - // Quota node defaults to namespace if empty if c.QuotaNode == "" { c.QuotaNode = c.Namespace @@ -105,12 +101,6 @@ func (c *Config) ApplyDefaults() { c.DefaultQuotaFiles = 1000000 // 1 Million } - if c.ShareFolder == "" { - c.ShareFolder = "/MyShares" - } - // ensure share folder always starts with slash - c.ShareFolder = path.Join("/", c.ShareFolder) - if c.EosBinary == "" { c.EosBinary = "/usr/bin/eos" } @@ -289,20 +279,20 @@ func getUser(ctx context.Context) (*userpb.User, error) { func (fs *eosfs) getLayout(ctx context.Context) (layout string) { if fs.conf.EnableHome { - u := ctx.ContextMustGetUser(ctx) + u := appctx.ContextMustGetUser(ctx) layout = templates.WithUser(u, fs.conf.UserLayout) } return } -func (fs *eosfs) getInternalHome(ctx context.Context) (string) { +func (fs *eosfs) getInternalHome(ctx context.Context) string { if !fs.conf.EnableHome { // 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) + u := appctx.ContextMustGetUser(ctx) relativeHome := templates.WithUser(u, fs.conf.UserLayout) return relativeHome } @@ -321,7 +311,7 @@ func (fs *eosfs) wrap(ctx context.Context, fn string) (internal string) { func (fs *eosfs) unwrap(ctx context.Context, internal string) (string, error) { log := appctx.GetLogger(ctx) layout := fs.getLayout(ctx) - ns, err := fs.getNsMatch(internal, []string{fs.conf.Namespace, fs.conf.ShadowNamespace}) + ns, err := fs.getNsMatch(internal, []string{fs.conf.Namespace}) if err != nil { return "", err } @@ -375,11 +365,11 @@ func (fs *eosfs) resolveRefAndGetAuth(ctx context.Context, ref *provider.Referen if err != nil { return "", eosclient.Authorization{}, errors.Wrap(err, "eosfs: no user in ctx") } + fn := fs.wrap(ctx, p) auth, err := fs.getUserAuth(ctx, u, fn) if err != nil { return "", eosclient.Authorization{}, err } - fn := fs.wrap(ctx, p) return fn, auth, nil } @@ -1265,17 +1255,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 } @@ -1284,40 +1270,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 } @@ -1331,18 +1300,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 { @@ -1441,18 +1401,19 @@ func (fs *eosfs) TouchFile(ctx context.Context, ref *provider.Reference) error { } func (fs *eosfs) CreateReference(ctx context.Context, p string, targetURI *url.URL) error { - u, err := getUser(ctx) + _, err := getUser(ctx) if err != nil { return errors.Wrap(err, "eosfs: no user in ctx") } // TODO(labkode): with the grpc plugin we can create a file touching with xattrs. // Current mechanism is: touch to hidden location, set xattr, rename. + fn := fs.wrap(ctx, p) dir, base := path.Split(fn) tmp := path.Join(dir, fmt.Sprintf(".sys.reva#.%s", base)) cboxAuth := utils.GetEmptyAuth() - if err := fs.c.CreateDir(ctx, auth, tmp); err != nil { + if err := fs.c.CreateDir(ctx, cboxAuth, tmp); err != nil { err = errors.Wrapf(err, "eosfs: error creating temporary ref file") return err } @@ -1523,7 +1484,7 @@ func (fs *eosfs) Move(ctx context.Context, oldRef, newRef *provider.Reference) e } func (fs *eosfs) Download(ctx context.Context, ref *provider.Reference) (io.ReadCloser, error) { - fn, auth, err := fs.resolveRefForbidShareFolder(ctx, ref) + fn, auth, err := fs.resolveRefAndGetAuth(ctx, ref) if err != nil { return nil, err } @@ -1555,7 +1516,7 @@ func (fs *eosfs) ListRevisions(ctx context.Context, ref *provider.Reference) ([] return nil, errtypes.PermissionDenied("eosfs: user doesn't have permissions to list revisions") } } else { - fn, auth, err = fs.resolveRefForbidShareFolder(ctx, ref) + fn, auth, err = fs.resolveRefAndGetAuth(ctx, ref) if err != nil { return nil, err } @@ -1598,7 +1559,7 @@ func (fs *eosfs) DownloadRevision(ctx context.Context, ref *provider.Reference, return nil, errtypes.PermissionDenied("eosfs: user doesn't have permissions to download revisions") } } else { - fn, auth, err = fs.resolveRefForbidShareFolder(ctx, ref) + fn, auth, err = fs.resolveRefAndGetAuth(ctx, ref) if err != nil { return nil, err } @@ -1631,7 +1592,7 @@ func (fs *eosfs) RestoreRevision(ctx context.Context, ref *provider.Reference, r return errtypes.PermissionDenied("eosfs: user doesn't have permissions to restore revisions") } } else { - fn, auth, err = fs.resolveRefForbidShareFolder(ctx, ref) + fn, auth, err = fs.resolveRefAndGetAuth(ctx, ref) if err != nil { return err } diff --git a/pkg/storage/utils/eosfs/upload.go b/pkg/storage/utils/eosfs/upload.go index fb46c2699d..5de666ae97 100644 --- a/pkg/storage/utils/eosfs/upload.go +++ b/pkg/storage/utils/eosfs/upload.go @@ -36,10 +36,6 @@ func (fs *eosfs) Upload(ctx context.Context, ref *provider.Reference, r io.ReadC return errors.Wrap(err, "eos: error resolving reference") } - if fs.isShareFolder(ctx, p) { - return errtypes.PermissionDenied("eos: cannot upload under the virtual share folder") - } - ok, err := chunking.IsChunked(p) if err != nil { return errors.Wrap(err, "eos: error checking path")