From e9b2fd1dab9fbd3c014368f3a9bbf8fef9b0f0b7 Mon Sep 17 00:00:00 2001 From: Fabrizio Furano Date: Wed, 24 Feb 2021 09:09:51 +0100 Subject: [PATCH] First working implementation of HTTP GET/PUT towards EOS --- pkg/eosclient/eosgrpc/eosgrpc.go | 76 +++++++++++++++++++------------- pkg/storage/utils/eosfs/eosfs.go | 20 ++++----- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/pkg/eosclient/eosgrpc/eosgrpc.go b/pkg/eosclient/eosgrpc/eosgrpc.go index 65730faea6..8591c650c2 100644 --- a/pkg/eosclient/eosgrpc/eosgrpc.go +++ b/pkg/eosclient/eosgrpc/eosgrpc.go @@ -23,7 +23,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "os" "os/exec" "path" @@ -35,6 +34,7 @@ import ( "github.com/cs3org/reva/pkg/appctx" "github.com/cs3org/reva/pkg/eosclient" erpc "github.com/cs3org/reva/pkg/eosclient/eosgrpc/eos_grpc" + ehttp "github.com/cs3org/reva/pkg/eosclient/eosgrpc/eos_http" "github.com/cs3org/reva/pkg/errtypes" "github.com/cs3org/reva/pkg/storage/utils/acl" "github.com/google/uuid" @@ -59,10 +59,6 @@ const ( // Options to configure the Client. type Options struct { - // ForceSingleUserMode forces all connections to use only one user. - // This is the case when access to EOS is done from FUSE under apache or www-data. - ForceSingleUserMode bool - // UseKeyTabAuth changes will authenticate requests by using an EOS keytab. UseKeytab bool @@ -70,10 +66,6 @@ type Options struct { // Requires extra metadata operations if set to true VersionInvariant bool - // SingleUsername is the username to use when connecting to EOS. - // Defaults to apache - SingleUsername string - // Location of the xrdcopy binary. // Default is /opt/eos/xrootd/bin/xrdcopy. XrdcopyBinary string @@ -99,12 +91,11 @@ type Options struct { // SecProtocol is the comma separated list of security protocols used by xrootd. // For example: "sss, unix" SecProtocol string + + httpopts ehttp.Options } func (opt *Options) init() { - if opt.ForceSingleUserMode && opt.SingleUsername != "" { - opt.SingleUsername = "apache" - } if opt.XrdcopyBinary == "" { opt.XrdcopyBinary = "/opt/eos/xrootd/bin/xrdcopy" @@ -117,6 +108,10 @@ func (opt *Options) init() { if opt.CacheDirectory == "" { opt.CacheDirectory = os.TempDir() } + + opt.httpopts.Init() + opt.httpopts.BaseURL = opt.URL + } // Client performs actions against a EOS management node (MGM) @@ -126,6 +121,10 @@ type Client struct { cl erpc.EosClient } +func (c *Client) GetHttpCl() *ehttp.EosHttpClient { + return ehttp.New(&c.opt.httpopts) +} + // Create and connect a grpc eos Client func newgrpc(ctx context.Context, opt *Options) (erpc.EosClient, error) { log := appctx.GetLogger(ctx) @@ -979,11 +978,24 @@ func (c *Client) Read(ctx context.Context, uid, gid, path string) (io.ReadCloser localTarget := fmt.Sprintf("%s/%s", c.opt.CacheDirectory, rand) defer os.RemoveAll(localTarget) - xrdPath := fmt.Sprintf("%s//%s", c.opt.URL, path) - cmd := exec.CommandContext(ctx, c.opt.XrdcopyBinary, "--nopbar", "--silent", "-f", xrdPath, localTarget, fmt.Sprintf("-OSeos.ruid=%s&eos.rgid=%s", uid, gid)) - if _, _, err := c.execute(ctx, cmd); err != nil { - return nil, err + localfile, err := os.Create(localTarget) + if err != nil { + log.Error().Str("func", "Read").Str("path", path).Str("uid,gid", uid+","+gid).Str("err", err.Error()).Msg("") + return nil, errtypes.InternalError(fmt.Sprintf("can't open local cache file '%s'", localTarget)) } + + // xrdPath := fmt.Sprintf("%s//%s", c.opt.URL, path) + // cmd := exec.CommandContext(ctx, c.opt.XrdcopyBinary, "--nopbar", "--silent", "-f", xrdPath, localTarget, fmt.Sprintf("-OSeos.ruid=%s&eos.rgid=%s", uid, gid)) + // if _, _, err := c.execute(ctx, cmd); err != nil { + // return nil, err + // } + + err = c.GetHttpCl().GETFile(ctx, "", uid, gid, path, localfile) + if err != nil { + log.Error().Str("func", "Read").Str("path", path).Str("uid,gid", uid+","+gid).Str("err", err.Error()).Msg("") + return nil, errtypes.InternalError(fmt.Sprintf("can't GET local cache file '%s'", localTarget)) + } + return os.Open(localTarget) } @@ -992,24 +1004,28 @@ func (c *Client) Write(ctx context.Context, uid, gid, path string, stream io.Rea log := appctx.GetLogger(ctx) log.Info().Str("func", "Write").Str("uid,gid", uid+","+gid).Str("path", path).Msg("") - fd, err := ioutil.TempFile(c.opt.CacheDirectory, "eoswrite-") - if err != nil { - return err - } - defer fd.Close() - defer os.RemoveAll(fd.Name()) - - // copy stream to local temp file - _, err = io.Copy(fd, stream) - if err != nil { - return err - } - - return c.WriteFile(ctx, uid, gid, path, fd.Name()) + //fd, err := ioutil.TempFile(c.opt.CacheDirectory, "eoswrite-") + //if err != nil { + // return err + // } + // defer fd.Close() + // defer os.RemoveAll(fd.Name()) + // + // // copy stream to local temp file + // _, err = io.Copy(fd, stream) + // if err != nil { + //return err + //} + + return c.GetHttpCl().PUTFile(ctx, "", uid, gid, path, stream) + + //return c.GetHttpCl().PUTFile(ctx, remoteuser, uid, gid, urlpathng, stream) + //return c.WriteFile(ctx, uid, gid, path, fd.Name()) } // WriteFile writes an existing file to the mgm func (c *Client) WriteFile(ctx context.Context, uid, gid, path, source string) error { + log := appctx.GetLogger(ctx) log.Info().Str("func", "WriteFile").Str("uid,gid", uid+","+gid).Str("path", path).Str("source", source).Msg("") diff --git a/pkg/storage/utils/eosfs/eosfs.go b/pkg/storage/utils/eosfs/eosfs.go index 08f38bd17c..6f44ef112d 100644 --- a/pkg/storage/utils/eosfs/eosfs.go +++ b/pkg/storage/utils/eosfs/eosfs.go @@ -145,17 +145,15 @@ func NewEOSFS(c *Config) (storage.FS, error) { var eosClient eosclient.EOSClient if c.UseGRPC { eosClientOpts := &eosgrpc.Options{ - XrdcopyBinary: c.XrdcopyBinary, - URL: c.MasterURL, - GrpcURI: c.GrpcURI, - CacheDirectory: c.CacheDirectory, - ForceSingleUserMode: c.ForceSingleUserMode, - SingleUsername: c.SingleUsername, - UseKeytab: c.UseKeytab, - Keytab: c.Keytab, - Authkey: c.GRPCAuthkey, - SecProtocol: c.SecProtocol, - VersionInvariant: c.VersionInvariant, + XrdcopyBinary: c.XrdcopyBinary, + URL: c.MasterURL, + GrpcURI: c.GrpcURI, + CacheDirectory: c.CacheDirectory, + UseKeytab: c.UseKeytab, + Keytab: c.Keytab, + Authkey: c.GRPCAuthkey, + SecProtocol: c.SecProtocol, + VersionInvariant: c.VersionInvariant, } eosClient = eosgrpc.New(eosClientOpts) } else {