From f9615e10fc6b238e129c5fdc12bcccea98556563 Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Tue, 6 Apr 2021 15:24:15 +0200 Subject: [PATCH 1/2] eos: fixes for enabling file sharing --- changelog/unreleased/eos-file-sharing.md | 3 + pkg/eosclient/eosbinary/eosbinary.go | 103 +++++++++++++++++------ 2 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 changelog/unreleased/eos-file-sharing.md diff --git a/changelog/unreleased/eos-file-sharing.md b/changelog/unreleased/eos-file-sharing.md new file mode 100644 index 0000000000..759d8400db --- /dev/null +++ b/changelog/unreleased/eos-file-sharing.md @@ -0,0 +1,3 @@ +Bugfix: Fixes for enabling file sharing in EOS + +https://github.com/cs3org/reva/pull/1619 diff --git a/pkg/eosclient/eosbinary/eosbinary.go b/pkg/eosclient/eosbinary/eosbinary.go index 17679a21f9..1eaec2823e 100644 --- a/pkg/eosclient/eosbinary/eosbinary.go +++ b/pkg/eosclient/eosbinary/eosbinary.go @@ -27,6 +27,7 @@ import ( "os" "os/exec" "path" + "path/filepath" "strconv" "strings" "syscall" @@ -119,6 +120,9 @@ type Options struct { // SecProtocol is the comma separated list of security protocols used by xrootd. // For example: "sss, unix" SecProtocol string + + // The EOS Version. + EOSVersion eosVersion } func (opt *Options) init() { @@ -263,12 +267,15 @@ func (c *Client) executeEOS(ctx context.Context, cmd *exec.Cmd) (string, string, } func (c *Client) getVersion(ctx context.Context, rootUID, rootGID string) (eosVersion, error) { - cmd := exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "version") - stdout, _, err := c.executeEOS(ctx, cmd) - if err != nil { - return "", err + if c.opt.EOSVersion == "" { + cmd := exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "version") + stdout, _, err := c.executeEOS(ctx, cmd) + if err != nil { + return "", err + } + c.opt.EOSVersion = c.parseVersion(ctx, stdout) } - return c.parseVersion(ctx, stdout), nil + return c.opt.EOSVersion, nil } func (c *Client) parseVersion(ctx context.Context, raw string) eosVersion { @@ -297,24 +304,47 @@ func (c *Client) AddACL(ctx context.Context, uid, gid, rootUID, rootGID, path st return err } - var cmd *exec.Cmd - if version == versionCitrine { - sysACL := a.CitrineSerialize() - cmd = exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "acl", "--sys", "--recursive", sysACL, path) - } else { - acls, err := c.getACLForPath(ctx, uid, gid, path) - if err != nil { + finfo, err := c.GetFileInfoByPath(ctx, uid, gid, path) + if err != nil { + return err + } + if !finfo.IsDir { + userACLAttr := &eosclient.Attribute{ + Type: SystemAttr, + Key: "eval.useracl", + Val: "1", + } + if err = c.SetAttr(ctx, uid, gid, userACLAttr, false, path); err != nil { return err } + } + var args []string + if version == versionCitrine { + sysACL := a.CitrineSerialize() + args = []string{"-r", rootUID, rootGID, "acl"} + if finfo.IsDir { + args = append(args, "--sys", "--recursive") + } else { + args = append(args, "--user") + } + args = append(args, sysACL, path) + } else { + acls := finfo.SysACL err = acls.SetEntry(a.Type, a.Qualifier, a.Permissions) if err != nil { return err } sysACL := acls.Serialize() - cmd = exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "attr", "-r", "set", fmt.Sprintf("sys.acl=%s", sysACL), path) + args = []string{"-r", rootUID, rootGID, "attr"} + if finfo.IsDir { + args = append(args, "-r", "set", fmt.Sprintf("sys.acl=%s", sysACL), path) + } else { + args = append(args, "set", fmt.Sprintf("user.acl=%s", sysACL), path) + } } + cmd := exec.CommandContext(ctx, c.opt.EosBinary, args...) _, _, err = c.executeEOS(ctx, cmd) return err @@ -327,24 +357,45 @@ func (c *Client) RemoveACL(ctx context.Context, uid, gid, rootUID, rootGID, path return err } - var cmd *exec.Cmd - if version == versionCitrine { - sysACL := a.CitrineSerialize() - cmd = exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "acl", "--sys", "--recursive", sysACL, path) - } else { - acls, err := c.getACLForPath(ctx, uid, gid, path) - if err != nil { + finfo, err := c.GetFileInfoByPath(ctx, uid, gid, path) + if err != nil { + return err + } + if !finfo.IsDir { + userACLAttr := &eosclient.Attribute{ + Type: SystemAttr, + Key: "eval.useracl", + } + if err = c.UnsetAttr(ctx, uid, gid, userACLAttr, path); err != nil { return err } + } + var args []string + if version == versionCitrine { + sysACL := a.CitrineSerialize() + args = []string{"-r", rootUID, rootGID, "acl"} + if finfo.IsDir { + args = append(args, "--sys", "--recursive") + } else { + args = append(args, "--user") + } + args = append(args, sysACL, path) + } else { + acls := finfo.SysACL acls.DeleteEntry(a.Type, a.Qualifier) sysACL := acls.Serialize() - cmd = exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "attr", "-r", "set", fmt.Sprintf("sys.acl=%s", sysACL), path) + args = []string{"-r", rootUID, rootGID, "attr"} + if finfo.IsDir { + args = append(args, "-r", "set", fmt.Sprintf("sys.acl=%s", sysACL), path) + } else { + args = append(args, "set", fmt.Sprintf("user.acl=%s", sysACL), path) + } } + cmd := exec.CommandContext(ctx, c.opt.EosBinary, args...) _, _, err = c.executeEOS(ctx, cmd) return err - } // UpdateACL updates the EOS acl. @@ -437,11 +488,9 @@ func (c *Client) GetFileInfoByPath(ctx context.Context, uid, gid, path string) ( } if c.opt.VersionInvariant && !isVersionFolder(path) && !info.IsDir { - inode, err := c.getVersionFolderInode(ctx, uid, gid, path) - if err != nil { - return nil, err + if inode, err := c.getVersionFolderInode(ctx, uid, gid, path); err == nil { + info.Inode = inode } - info.Inode = inode } return info, nil @@ -791,7 +840,7 @@ func (c *Client) parseQuota(path, raw string) (*eosclient.QuotaInfo, error) { // map[maxbytes:2000000000000 maxlogicalbytes:1000000000000 percentageusedbytes:0.49 quota:node uid:gonzalhu space:/eos/scratch/user/ usedbytes:9829986500 usedlogicalbytes:4914993250 statusfiles:ok usedfiles:334 maxfiles:1000000 statusbytes:ok] space := m["space"] - if strings.HasPrefix(path, space) { + if strings.HasPrefix(path, filepath.Clean(space)) { maxBytesString := m["maxlogicalbytes"] usedBytesString := m["usedlogicalbytes"] maxBytes, _ := strconv.ParseUint(maxBytesString, 10, 64) From 11f05c753096cccb919249da29f457a4be538d6e Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 8 Apr 2021 09:36:51 +0200 Subject: [PATCH 2/2] Remove eos version logic as we only support citrine now --- pkg/eosclient/eosbinary/eosbinary.go | 114 ++++----------------------- 1 file changed, 16 insertions(+), 98 deletions(-) diff --git a/pkg/eosclient/eosbinary/eosbinary.go b/pkg/eosclient/eosbinary/eosbinary.go index 1eaec2823e..bb22ce5bcf 100644 --- a/pkg/eosclient/eosbinary/eosbinary.go +++ b/pkg/eosclient/eosbinary/eosbinary.go @@ -41,13 +41,8 @@ import ( "go.opencensus.io/trace" ) -type eosVersion string - const ( versionPrefix = ".sys.v#." - - versionAquamarine = eosVersion("aquamarine") - versionCitrine = eosVersion("citrine") ) const ( @@ -120,9 +115,6 @@ type Options struct { // SecProtocol is the comma separated list of security protocols used by xrootd. // For example: "sss, unix" SecProtocol string - - // The EOS Version. - EOSVersion eosVersion } func (opt *Options) init() { @@ -266,49 +258,19 @@ func (c *Client) executeEOS(ctx context.Context, cmd *exec.Cmd) (string, string, return outBuf.String(), errBuf.String(), err } -func (c *Client) getVersion(ctx context.Context, rootUID, rootGID string) (eosVersion, error) { - if c.opt.EOSVersion == "" { - cmd := exec.CommandContext(ctx, c.opt.EosBinary, "-r", rootUID, rootGID, "version") - stdout, _, err := c.executeEOS(ctx, cmd) - if err != nil { - return "", err - } - c.opt.EOSVersion = c.parseVersion(ctx, stdout) - } - return c.opt.EOSVersion, nil -} - -func (c *Client) parseVersion(ctx context.Context, raw string) eosVersion { - var serverVersion string - rawLines := strings.Split(raw, "\n") - for _, rl := range rawLines { - if rl == "" { - continue - } - if strings.HasPrefix(rl, "EOS_SERVER_VERSION") { - serverVersion = strings.Split(strings.Split(rl, " ")[0], "=")[1] - break - } - } - - if strings.HasPrefix(serverVersion, "4.") { - return versionCitrine - } - return versionAquamarine -} - // AddACL adds an new acl to EOS with the given aclType. func (c *Client) AddACL(ctx context.Context, uid, gid, rootUID, rootGID, path string, a *acl.Entry) error { - version, err := c.getVersion(ctx, rootUID, rootGID) - if err != nil { - return err - } - finfo, err := c.GetFileInfoByPath(ctx, uid, gid, path) if err != nil { return err } - if !finfo.IsDir { + sysACL := a.CitrineSerialize() + args := []string{"-r", rootUID, rootGID, "acl"} + + if finfo.IsDir { + args = append(args, "--sys", "--recursive") + } else { + args = append(args, "--user") userACLAttr := &eosclient.Attribute{ Type: SystemAttr, Key: "eval.useracl", @@ -318,31 +280,7 @@ func (c *Client) AddACL(ctx context.Context, uid, gid, rootUID, rootGID, path st return err } } - - var args []string - if version == versionCitrine { - sysACL := a.CitrineSerialize() - args = []string{"-r", rootUID, rootGID, "acl"} - if finfo.IsDir { - args = append(args, "--sys", "--recursive") - } else { - args = append(args, "--user") - } - args = append(args, sysACL, path) - } else { - acls := finfo.SysACL - err = acls.SetEntry(a.Type, a.Qualifier, a.Permissions) - if err != nil { - return err - } - sysACL := acls.Serialize() - args = []string{"-r", rootUID, rootGID, "attr"} - if finfo.IsDir { - args = append(args, "-r", "set", fmt.Sprintf("sys.acl=%s", sysACL), path) - } else { - args = append(args, "set", fmt.Sprintf("user.acl=%s", sysACL), path) - } - } + args = append(args, sysACL, path) cmd := exec.CommandContext(ctx, c.opt.EosBinary, args...) _, _, err = c.executeEOS(ctx, cmd) @@ -352,16 +290,17 @@ func (c *Client) AddACL(ctx context.Context, uid, gid, rootUID, rootGID, path st // RemoveACL removes the acl from EOS. func (c *Client) RemoveACL(ctx context.Context, uid, gid, rootUID, rootGID, path string, a *acl.Entry) error { - version, err := c.getVersion(ctx, rootUID, rootGID) - if err != nil { - return err - } - finfo, err := c.GetFileInfoByPath(ctx, uid, gid, path) if err != nil { return err } - if !finfo.IsDir { + + sysACL := a.CitrineSerialize() + args := []string{"-r", rootUID, rootGID, "acl"} + if finfo.IsDir { + args = append(args, "--sys", "--recursive") + } else { + args = append(args, "--user") userACLAttr := &eosclient.Attribute{ Type: SystemAttr, Key: "eval.useracl", @@ -370,28 +309,7 @@ func (c *Client) RemoveACL(ctx context.Context, uid, gid, rootUID, rootGID, path return err } } - - var args []string - if version == versionCitrine { - sysACL := a.CitrineSerialize() - args = []string{"-r", rootUID, rootGID, "acl"} - if finfo.IsDir { - args = append(args, "--sys", "--recursive") - } else { - args = append(args, "--user") - } - args = append(args, sysACL, path) - } else { - acls := finfo.SysACL - acls.DeleteEntry(a.Type, a.Qualifier) - sysACL := acls.Serialize() - args = []string{"-r", rootUID, rootGID, "attr"} - if finfo.IsDir { - args = append(args, "-r", "set", fmt.Sprintf("sys.acl=%s", sysACL), path) - } else { - args = append(args, "set", fmt.Sprintf("user.acl=%s", sysACL), path) - } - } + args = append(args, sysACL, path) cmd := exec.CommandContext(ctx, c.opt.EosBinary, args...) _, _, err = c.executeEOS(ctx, cmd)