From e46440d1fa19fb53890a5b543d37bdc369f1a23d Mon Sep 17 00:00:00 2001 From: Cyrill Troxler Date: Fri, 27 Jul 2018 21:37:32 +0200 Subject: [PATCH] Add fs prefix (directory) This ensures the fs root is clean and does not mess with the metadata. Also in the future this will allow for multiple filesystems to be created in one bucket. --- pkg/s3/controllerserver.go | 11 +++++++---- pkg/s3/mounter_goofys.go | 3 ++- pkg/s3/mounter_s3backer.go | 9 ++++++++- pkg/s3/mounter_s3fs.go | 2 +- pkg/s3/mounter_s3ql.go | 4 +++- pkg/s3/s3-client.go | 10 ++++++++++ 6 files changed, 31 insertions(+), 8 deletions(-) diff --git a/pkg/s3/controllerserver.go b/pkg/s3/controllerserver.go index cb5bf08..6809115 100644 --- a/pkg/s3/controllerserver.go +++ b/pkg/s3/controllerserver.go @@ -61,7 +61,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol var b *bucket b, err = cs.s3.client.getBucket(volumeID) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to get bucket: %v", err) } // Check if volume capacity requested is bigger than the already existing capacity if capacityBytes > b.CapacityBytes { @@ -69,16 +69,19 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol } } else { if err = cs.s3.client.createBucket(volumeID); err != nil { - glog.V(3).Infof("failed to create volume: %v", err) - return nil, err + return nil, fmt.Errorf("failed to create volume: %v", err) + } + if err = cs.s3.client.createPrefix(volumeID, fsPrefix); err != nil { + return nil, fmt.Errorf("failed to create prefix: %v", err) } } b := &bucket{ Name: volumeID, CapacityBytes: capacityBytes, + FSPath: fsPrefix, } if err := cs.s3.client.setBucket(b); err != nil { - return nil, err + return nil, fmt.Errorf("Error setting bucket metadata: %v", err) } glog.V(4).Infof("create volume %s", volumeID) diff --git a/pkg/s3/mounter_goofys.go b/pkg/s3/mounter_goofys.go index 326596e..6e93bb0 100644 --- a/pkg/s3/mounter_goofys.go +++ b/pkg/s3/mounter_goofys.go @@ -60,8 +60,9 @@ func (goofys *goofysMounter) Mount(source string, target string) error { os.Setenv("AWS_ACCESS_KEY_ID", goofys.accessKeyID) os.Setenv("AWS_SECRET_ACCESS_KEY", goofys.secretAccessKey) + fullPath := fmt.Sprintf("%s:%s", goofys.bucket.Name, goofys.bucket.FSPath) - _, _, err := goofysApi.Mount(context.Background(), goofys.bucket.Name, goofysCfg) + _, _, err := goofysApi.Mount(context.Background(), fullPath, goofysCfg) if err != nil { return fmt.Errorf("Error mounting via goofys: %s", err) diff --git a/pkg/s3/mounter_s3backer.go b/pkg/s3/mounter_s3backer.go index 3d43b4e..55d0379 100644 --- a/pkg/s3/mounter_s3backer.go +++ b/pkg/s3/mounter_s3backer.go @@ -2,6 +2,7 @@ package s3 import ( "fmt" + "net/url" "os" "os/exec" "path" @@ -29,6 +30,11 @@ const ( ) func newS3backerMounter(bucket *bucket, cfg *Config) (Mounter, error) { + url, err := url.Parse(cfg.Endpoint) + if err != nil { + return nil, err + } + url.Path = path.Join(url.Path, bucket.Name, bucket.FSPath) // s3backer cannot work with 0 size volumes if bucket.CapacityBytes == 0 { bucket.CapacityBytes = s3backerDefaultSize @@ -88,8 +94,9 @@ func (s3backer *s3backerMounter) mountInit(path string) error { args := []string{ // baseURL must end with / fmt.Sprintf("--baseURL=%s/", s3backer.url), - fmt.Sprintf("--blockSize=%v", s3backerBlockSize), + fmt.Sprintf("--blockSize=%s", s3backerBlockSize), fmt.Sprintf("--size=%v", s3backer.bucket.CapacityBytes), + fmt.Sprintf("--prefix=%s/", s3backer.bucket.FSPath), "--listBlocks", s3backer.bucket.Name, path, diff --git a/pkg/s3/mounter_s3fs.go b/pkg/s3/mounter_s3fs.go index e6d6f42..e332557 100644 --- a/pkg/s3/mounter_s3fs.go +++ b/pkg/s3/mounter_s3fs.go @@ -39,7 +39,7 @@ func (s3fs *s3fsMounter) Mount(source string, target string) error { return err } args := []string{ - fmt.Sprintf("%s", s3fs.bucket.Name), + fmt.Sprintf("%s:/%s", s3fs.bucket.Name, s3fs.bucket.FSPath), fmt.Sprintf("%s", target), "-o", "sigv2", "-o", "use_path_request_style", diff --git a/pkg/s3/mounter_s3ql.go b/pkg/s3/mounter_s3ql.go index 80facaa..1f90481 100644 --- a/pkg/s3/mounter_s3ql.go +++ b/pkg/s3/mounter_s3ql.go @@ -49,7 +49,9 @@ func newS3qlMounter(b *bucket, cfg *Config) (Mounter, error) { ssl: ssl, } - url.Path = path.Join(url.Path, b.Name) + // s3ql requires a trailing slash or it will just + // prepend the fspath to the s3ql files + url.Path = path.Join(url.Path, b.Name, b.FSPath) + "/" s3ql.bucketURL = url.String() if !ssl { diff --git a/pkg/s3/s3-client.go b/pkg/s3/s3-client.go index 69dc676..e3c76bc 100644 --- a/pkg/s3/s3-client.go +++ b/pkg/s3/s3-client.go @@ -13,6 +13,7 @@ import ( const ( metadataName = ".metadata.json" + fsPrefix = "csi-fs" ) type s3Client struct { @@ -22,6 +23,7 @@ type s3Client struct { type bucket struct { Name string + FSPath string CapacityBytes int64 } @@ -54,6 +56,14 @@ func (client *s3Client) createBucket(bucketName string) error { return client.minio.MakeBucket(bucketName, client.cfg.Region) } +func (client *s3Client) createPrefix(bucketName string, prefix string) error { + _, err := client.minio.PutObject(bucketName, prefix+"/", bytes.NewReader([]byte("")), 0, minio.PutObjectOptions{}) + if err != nil { + return err + } + return nil +} + func (client *s3Client) removeBucket(bucketName string) error { if err := client.emptyBucket(bucketName); err != nil { return err