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