From 24cfab72b6c8bd91c36f9deb229aabeee961f8af Mon Sep 17 00:00:00 2001 From: Silvan Kaiser Date: Thu, 2 May 2019 14:55:24 +0200 Subject: [PATCH] Adds subfolder creation upon volume creation If a volume name contains a slash ('/') based path the name of the new volume is based on the string up to the first slash. The following string is used as a directory path to be created in the new volume. --- README.md | 10 ++++++++++ quobyte_driver.go | 50 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5b5689d..0f09daf 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,16 @@ $ docker volume create --driver quobyte --name $ docker volume create --driver quobyte --name --opt user=docker --opt group=docker --opt configuration_name=SSD_ONLY ``` +#### Create a volume with an inital directory path + +You can create a new volume with a specific initial directory path inside by adding the directory path to be initialized to the volume name: + +``` +$ docker volume create --driver quobyte --name +``` + +This results in a new volume with name `volumename` containing the directory path `/with/a/path`. + ### Delete a volume __Important__: Be careful when using this. The volume removal allows removing any volume accessible in the configured tenant! diff --git a/quobyte_driver.go b/quobyte_driver.go index 92973d0..f4713b4 100644 --- a/quobyte_driver.go +++ b/quobyte_driver.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "log" "os" + "path" "path/filepath" "strings" "sync" @@ -38,11 +39,26 @@ func newQuobyteDriver(apiURL string, username string, password string, quobyteMo return driver } +func (driver quobyteDriver) stripVolumeName(requestName string) (strippedVolumeName string, subdirPath string) { + nameElems := strings.SplitN(requestName, "/", 2) + if len(nameElems) == 2 { + subDir := path.Clean(nameElems[1]) + return nameElems[0], subDir + } + return nameElems[0], "" +} + func (driver quobyteDriver) Create(request volume.Request) volume.Response { - log.Printf("Creating volume %s\n", request.Name) driver.m.Lock() defer driver.m.Unlock() + volumeName, subDirs := driver.stripVolumeName(request.Name) + if subDirs == "" { + log.Printf("Creating volume %s\n", volumeName) + } else { + log.Printf("Creating volume %s with subdir(s) %s\n", volumeName, subDirs) + } + user, group := "root", "root" configurationName := driver.configName retryPolicy := "INTERACTIVE" @@ -62,7 +78,7 @@ func (driver quobyteDriver) Create(request volume.Request) volume.Response { } if _, err := driver.client.CreateVolume(&quobyte_api.CreateVolumeRequest{ - Name: request.Name, + Name: volumeName, RootUserID: user, RootGroupID: group, ConfigurationName: configurationName, @@ -76,12 +92,19 @@ func (driver quobyteDriver) Create(request volume.Request) volume.Response { } } - mPoint := filepath.Join(driver.quobyteMount, request.Name) - log.Printf("Validate mounting volume %s on %s\n", request.Name, mPoint) + mPoint := filepath.Join(driver.quobyteMount, volumeName) + log.Printf("Validate mounting volume %s on %s\n", volumeName, mPoint) if err := driver.checkMountPoint(mPoint); err != nil { return volume.Response{Err: err.Error()} } + if subDirs != "" { + log.Printf("Creating subdir(s) %s for new volume %s\n", subDirs, volumeName) + if csdErr := os.MkdirAll(filepath.Join(mPoint, subDirs), 0755); csdErr != nil { + log.Printf("Unable to create subdirs in new volume: %s", csdErr) + } + } + return volume.Response{Err: ""} } @@ -105,11 +128,12 @@ func (driver quobyteDriver) checkMountPoint(mPoint string) error { } func (driver quobyteDriver) Remove(request volume.Request) volume.Response { - log.Printf("Removing volume %s\n", request.Name) driver.m.Lock() defer driver.m.Unlock() - if err := driver.client.DeleteVolumeByName(request.Name, driver.tenantID); err != nil { + volumeName, _ := driver.stripVolumeName(request.Name) + log.Printf("Removing volume %s\n", volumeName) + if err := driver.client.DeleteVolumeByName(volumeName, driver.tenantID); err != nil { log.Println(err) return volume.Response{Err: err.Error()} } @@ -120,13 +144,15 @@ func (driver quobyteDriver) Remove(request volume.Request) volume.Response { func (driver quobyteDriver) Mount(request volume.MountRequest) volume.Response { driver.m.Lock() defer driver.m.Unlock() - mPoint := filepath.Join(driver.quobyteMount, request.Name) - log.Printf("Mounting volume %s on %s\n", request.Name, mPoint) + volumeName, _ := driver.stripVolumeName(request.Name) + mPoint := filepath.Join(driver.quobyteMount, volumeName) + log.Printf("Mounting volume %s on %s\n", volumeName, mPoint) return volume.Response{Err: "", Mountpoint: mPoint} } func (driver quobyteDriver) Path(request volume.Request) volume.Response { - return volume.Response{Mountpoint: filepath.Join(driver.quobyteMount, request.Name)} + volumeName, _ := driver.stripVolumeName(request.Name) + return volume.Response{Mountpoint: filepath.Join(driver.quobyteMount, volumeName)} } func (driver quobyteDriver) Unmount(request volume.UnmountRequest) volume.Response { @@ -137,7 +163,8 @@ func (driver quobyteDriver) Get(request volume.Request) volume.Response { driver.m.Lock() defer driver.m.Unlock() - mPoint := filepath.Join(driver.quobyteMount, request.Name) + volumeName, _ := driver.stripVolumeName(request.Name) + mPoint := filepath.Join(driver.quobyteMount, volumeName) if fi, err := os.Lstat(mPoint); err != nil || !fi.IsDir() { log.Println(err) @@ -160,7 +187,8 @@ func (driver quobyteDriver) List(request volume.Request) volume.Response { for _, entry := range files { if entry.IsDir() { - vols = append(vols, &volume.Volume{Name: entry.Name(), Mountpoint: filepath.Join(driver.quobyteMount, entry.Name())}) + volumeName, _ := driver.stripVolumeName(entry.Name()) + vols = append(vols, &volume.Volume{Name: entry.Name(), Mountpoint: filepath.Join(driver.quobyteMount, volumeName)}) } }