The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6563

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
From 37a690ca88ab52a6653f4e7fb2083b9b56b83cab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgra...@ubuntu.com>
Date: Thu, 5 Dec 2019 15:13:42 -0500
Subject: [PATCH] lxd/storage: Remove legacy cephfs implementation
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Stéphane Graber <stgra...@ubuntu.com>
---
 lxd/storage.go        |   27 +-
 lxd/storage_cephfs.go | 1098 -----------------------------------------
 2 files changed, 2 insertions(+), 1123 deletions(-)
 delete mode 100644 lxd/storage_cephfs.go

diff --git a/lxd/storage.go b/lxd/storage.go
index 64172414df..2ac2fa3230 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -101,7 +101,6 @@ type storageType int
 const (
        storageTypeBtrfs storageType = iota
        storageTypeCeph
-       storageTypeCephFs
        storageTypeDir
        storageTypeLvm
        storageTypeMock
@@ -116,8 +115,6 @@ func storageTypeToString(sType storageType) (string, error) 
{
                return "btrfs", nil
        case storageTypeCeph:
                return "ceph", nil
-       case storageTypeCephFs:
-               return "cephfs", nil
        case storageTypeDir:
                return "dir", nil
        case storageTypeLvm:
@@ -128,7 +125,7 @@ func storageTypeToString(sType storageType) (string, error) 
{
                return "zfs", nil
        }
 
-       return "", fmt.Errorf("invalid storage type")
+       return "", fmt.Errorf("Invalid storage type")
 }
 
 func storageStringToType(sName string) (storageType, error) {
@@ -137,8 +134,6 @@ func storageStringToType(sName string) (storageType, error) 
{
                return storageTypeBtrfs, nil
        case "ceph":
                return storageTypeCeph, nil
-       case "cephfs":
-               return storageTypeCephFs, nil
        case "dir":
                return storageTypeDir, nil
        case "lvm":
@@ -149,7 +144,7 @@ func storageStringToType(sName string) (storageType, error) 
{
                return storageTypeZfs, nil
        }
 
-       return -1, fmt.Errorf("invalid storage type name")
+       return -1, fmt.Errorf("Invalid storage type name")
 }
 
 // The storage interface defines the functions needed to implement a storage
@@ -286,13 +281,6 @@ func storageCoreInit(driver string) (storage, error) {
                        return nil, err
                }
                return &ceph, nil
-       case storageTypeCephFs:
-               cephfs := storageCephFs{}
-               err = cephfs.StorageCoreInit()
-               if err != nil {
-                       return nil, err
-               }
-               return &cephfs, nil
        case storageTypeLvm:
                lvm := storageLvm{}
                err = lvm.StorageCoreInit()
@@ -383,17 +371,6 @@ func storageInit(s *state.State, project, poolName, 
volumeName string, volumeTyp
                        return nil, err
                }
                return &ceph, nil
-       case storageTypeCephFs:
-               cephfs := storageCephFs{}
-               cephfs.poolID = poolID
-               cephfs.pool = pool
-               cephfs.volume = volume
-               cephfs.s = s
-               err = cephfs.StoragePoolInit()
-               if err != nil {
-                       return nil, err
-               }
-               return &cephfs, nil
        case storageTypeLvm:
                lvm := storageLvm{}
                lvm.poolID = poolID
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
deleted file mode 100644
index 51e694e098..0000000000
--- a/lxd/storage_cephfs.go
+++ /dev/null
@@ -1,1098 +0,0 @@
-package main
-
-import (
-       "bufio"
-       "fmt"
-       "io"
-       "io/ioutil"
-       "os"
-       "path/filepath"
-       "strings"
-       "syscall"
-
-       "github.com/gorilla/websocket"
-       "github.com/pkg/errors"
-
-       "github.com/lxc/lxd/lxd/backup"
-       "github.com/lxc/lxd/lxd/instance"
-       "github.com/lxc/lxd/lxd/migration"
-       "github.com/lxc/lxd/lxd/operations"
-       "github.com/lxc/lxd/lxd/rsync"
-       "github.com/lxc/lxd/lxd/state"
-       driver "github.com/lxc/lxd/lxd/storage"
-       "github.com/lxc/lxd/shared"
-       "github.com/lxc/lxd/shared/api"
-       "github.com/lxc/lxd/shared/ioprogress"
-       "github.com/lxc/lxd/shared/logger"
-       "github.com/lxc/lxd/shared/units"
-)
-
-type storageCephFs struct {
-       ClusterName string
-       FsName      string
-       UserName    string
-       storageShared
-}
-
-func (s *storageCephFs) StorageCoreInit() error {
-       s.sType = storageTypeCeph
-       typeName, err := storageTypeToString(s.sType)
-       if err != nil {
-               return err
-       }
-       s.sTypeName = typeName
-
-       if cephVersion != "" {
-               s.sTypeVersion = cephVersion
-               return nil
-       }
-
-       msg, err := shared.RunCommand("rbd", "--version")
-       if err != nil {
-               return fmt.Errorf("Error getting CEPH version: %s", err)
-       }
-       s.sTypeVersion = strings.TrimSpace(msg)
-       cephVersion = s.sTypeVersion
-
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolInit() error {
-       var err error
-
-       err = s.StorageCoreInit()
-       if err != nil {
-               return errors.Wrap(err, "Storage pool init")
-       }
-
-       // set cluster name
-       if s.pool.Config["cephfs.cluster_name"] != "" {
-               s.ClusterName = s.pool.Config["cephfs.cluster_name"]
-       } else {
-               s.ClusterName = "ceph"
-       }
-
-       // set ceph user name
-       if s.pool.Config["cephfs.user.name"] != "" {
-               s.UserName = s.pool.Config["cephfs.user.name"]
-       } else {
-               s.UserName = "admin"
-       }
-
-       // set osd pool name
-       if s.pool.Config["cephfs.path"] != "" {
-               s.FsName = s.pool.Config["cephfs.path"]
-       }
-
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolCheck() error {
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolCreate() error {
-       logger.Infof(`Creating CEPHFS storage pool "%s" in cluster "%s"`, 
s.pool.Name, s.ClusterName)
-
-       // Setup config
-       s.pool.Config["volatile.initial_source"] = s.pool.Config["source"]
-
-       if s.pool.Config["source"] == "" {
-               return fmt.Errorf("A CEPHFS name or name/path source is 
required")
-       }
-
-       if s.pool.Config["cephfs.path"] != "" && s.pool.Config["cephfs.path"] 
!= s.pool.Config["source"] {
-               return fmt.Errorf("cephfs.path must match the source")
-       }
-
-       if s.pool.Config["cephfs.cluster_name"] == "" {
-               s.pool.Config["cephfs.cluster_name"] = "ceph"
-       }
-
-       if s.pool.Config["cephfs.user.name"] != "" {
-               s.pool.Config["cephfs.user.name"] = "admin"
-       }
-
-       s.pool.Config["cephfs.path"] = s.pool.Config["source"]
-       s.FsName = s.pool.Config["source"]
-
-       // Parse the namespace / path
-       fields := strings.SplitN(s.FsName, "/", 2)
-       fsName := fields[0]
-       fsPath := "/"
-       if len(fields) > 1 {
-               fsPath = fields[1]
-       }
-
-       // Check that the filesystem exists
-       if !cephFsExists(s.ClusterName, s.UserName, fsName) {
-               return fmt.Errorf("The requested '%v' CEPHFS doesn't exist", 
fsName)
-       }
-
-       // Create a temporary mountpoint
-       mountPath, err := ioutil.TempDir("", "lxd_cephfs_")
-       if err != nil {
-               return err
-       }
-       defer os.RemoveAll(mountPath)
-
-       err = os.Chmod(mountPath, 0700)
-       if err != nil {
-               return err
-       }
-
-       mountPoint := filepath.Join(mountPath, "mount")
-       err = os.Mkdir(mountPoint, 0700)
-       if err != nil {
-               return err
-       }
-
-       // Get the credentials and host
-       monAddresses, userSecret, err := cephFsConfig(s.ClusterName, s.UserName)
-       if err != nil {
-               return err
-       }
-
-       connected := false
-       for _, monAddress := range monAddresses {
-               uri := fmt.Sprintf("%s:6789:/", monAddress)
-               err = driver.TryMount(uri, mountPoint, "ceph", 0, 
fmt.Sprintf("name=%v,secret=%v,mds_namespace=%v", s.UserName, userSecret, 
fsName))
-               if err != nil {
-                       continue
-               }
-
-               connected = true
-               defer driver.TryUnmount(mountPoint, syscall.MNT_DETACH)
-               break
-       }
-
-       if !connected {
-               return err
-       }
-
-       // Create the path if missing
-       err = os.MkdirAll(filepath.Join(mountPoint, fsPath), 0755)
-       if err != nil {
-               return err
-       }
-
-       // Check that the existing path is empty
-       ok, _ := shared.PathIsEmpty(filepath.Join(mountPoint, fsPath))
-       if !ok {
-               return fmt.Errorf("Only empty CEPHFS paths can be used as a LXD 
storage pool")
-       }
-
-       // Create the mountpoint for the storage pool.
-       poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
-       err = os.MkdirAll(poolMntPoint, 0711)
-       if err != nil {
-               return err
-       }
-
-       logger.Infof(`Created CEPHFS storage pool "%s" in cluster "%s"`, 
s.pool.Name, s.ClusterName)
-
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolDelete() error {
-       logger.Infof(`Deleting CEPHFS storage pool "%s" in cluster "%s"`, 
s.pool.Name, s.ClusterName)
-
-       // Parse the namespace / path
-       fields := strings.SplitN(s.FsName, "/", 2)
-       fsName := fields[0]
-       fsPath := "/"
-       if len(fields) > 1 {
-               fsPath = fields[1]
-       }
-
-       // Create a temporary mountpoint
-       mountPath, err := ioutil.TempDir("", "lxd_cephfs_")
-       if err != nil {
-               return err
-       }
-       defer os.RemoveAll(mountPath)
-
-       err = os.Chmod(mountPath, 0700)
-       if err != nil {
-               return err
-       }
-
-       mountPoint := filepath.Join(mountPath, "mount")
-       err = os.Mkdir(mountPoint, 0700)
-       if err != nil {
-               return err
-       }
-
-       // Get the credentials and host
-       monAddresses, userSecret, err := cephFsConfig(s.ClusterName, s.UserName)
-       if err != nil {
-               return err
-       }
-
-       connected := false
-       for _, monAddress := range monAddresses {
-               uri := fmt.Sprintf("%s:6789:/", monAddress)
-               err = driver.TryMount(uri, mountPoint, "ceph", 0, 
fmt.Sprintf("name=%v,secret=%v,mds_namespace=%v", s.UserName, userSecret, 
fsName))
-               if err != nil {
-                       continue
-               }
-
-               connected = true
-               defer driver.TryUnmount(mountPoint, syscall.MNT_DETACH)
-               break
-       }
-
-       if !connected {
-               return err
-       }
-
-       if shared.PathExists(filepath.Join(mountPoint, fsPath)) {
-               // Delete the usual directories
-               for _, dir := range []string{"custom", "custom-snapshots"} {
-                       if shared.PathExists(filepath.Join(mountPoint, fsPath, 
dir)) {
-                               err = os.Remove(filepath.Join(mountPoint, 
fsPath, dir))
-                               if err != nil {
-                                       return err
-                               }
-                       }
-               }
-
-               // Confirm that the path is now empty
-               ok, _ := shared.PathIsEmpty(filepath.Join(mountPoint, fsPath))
-               if !ok {
-                       return fmt.Errorf("Only empty CEPHFS paths can be used 
as a LXD storage pool")
-               }
-
-               // Delete the path itself
-               if fsPath != "" && fsPath != "/" {
-                       err = os.Remove(filepath.Join(mountPoint, fsPath))
-                       if err != nil {
-                               return err
-                       }
-               }
-       }
-
-       // Make sure the existing pool is unmounted
-       _, err = s.StoragePoolUmount()
-       if err != nil {
-               return err
-       }
-
-       // Delete the mountpoint for the storage pool
-       poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
-       if shared.PathExists(poolMntPoint) {
-               err := os.RemoveAll(poolMntPoint)
-               if err != nil {
-                       return err
-               }
-               logger.Debugf(`Deleted mountpoint "%s" for CEPHFS storage pool 
"%s" in cluster "%s"`, poolMntPoint, s.FsName, s.ClusterName)
-       }
-
-       logger.Infof(`Deleted CEPHFS storage pool "%s" in cluster "%s"`, 
s.pool.Name, s.ClusterName)
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolMount() (bool, error) {
-       logger.Debugf("Mounting CEPHFS storage pool \"%s\"", s.pool.Name)
-
-       // Locking
-       poolMountLockID := getPoolMountLockID(s.pool.Name)
-       lxdStorageMapLock.Lock()
-       if waitChannel, ok := lxdStorageOngoingOperationMap[poolMountLockID]; 
ok {
-               lxdStorageMapLock.Unlock()
-               if _, ok := <-waitChannel; ok {
-                       logger.Warnf("Received value over semaphore, this 
should not have happened")
-               }
-               // Give the benefit of the doubt and assume that the other
-               // thread actually succeeded in mounting the storage pool.
-               return false, nil
-       }
-
-       lxdStorageOngoingOperationMap[poolMountLockID] = make(chan bool)
-       lxdStorageMapLock.Unlock()
-
-       removeLockFromMap := func() {
-               lxdStorageMapLock.Lock()
-               if waitChannel, ok := 
lxdStorageOngoingOperationMap[poolMountLockID]; ok {
-                       close(waitChannel)
-                       delete(lxdStorageOngoingOperationMap, poolMountLockID)
-               }
-               lxdStorageMapLock.Unlock()
-       }
-       defer removeLockFromMap()
-
-       // Check if already mounted
-       poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
-       if shared.IsMountPoint(poolMntPoint) {
-               return false, nil
-       }
-
-       // Parse the namespace / path
-       fields := strings.SplitN(s.FsName, "/", 2)
-       fsName := fields[0]
-       fsPath := "/"
-       if len(fields) > 1 {
-               fsPath = fields[1]
-       }
-
-       // Get the credentials and host
-       monAddresses, secret, err := cephFsConfig(s.ClusterName, s.UserName)
-       if err != nil {
-               return false, err
-       }
-
-       // Do the actual mount
-       connected := false
-       for _, monAddress := range monAddresses {
-               uri := fmt.Sprintf("%s:6789:/%s", monAddress, fsPath)
-               err = driver.TryMount(uri, poolMntPoint, "ceph", 0, 
fmt.Sprintf("name=%v,secret=%v,mds_namespace=%v", s.UserName, secret, fsName))
-               if err != nil {
-                       continue
-               }
-
-               connected = true
-               break
-       }
-
-       if !connected {
-               return false, err
-       }
-
-       logger.Debugf("Mounted CEPHFS storage pool \"%s\"", s.pool.Name)
-
-       return true, nil
-}
-
-func (s *storageCephFs) StoragePoolUmount() (bool, error) {
-       logger.Debugf("Unmounting CEPHFS storage pool \"%s\"", s.pool.Name)
-
-       // Locking
-       poolUmountLockID := getPoolUmountLockID(s.pool.Name)
-       lxdStorageMapLock.Lock()
-       if waitChannel, ok := lxdStorageOngoingOperationMap[poolUmountLockID]; 
ok {
-               lxdStorageMapLock.Unlock()
-               if _, ok := <-waitChannel; ok {
-                       logger.Warnf("Received value over semaphore, this 
should not have happened")
-               }
-               // Give the benefit of the doubt and assume that the other
-               // thread actually succeeded in unmounting the storage pool.
-               return false, nil
-       }
-
-       lxdStorageOngoingOperationMap[poolUmountLockID] = make(chan bool)
-       lxdStorageMapLock.Unlock()
-
-       removeLockFromMap := func() {
-               lxdStorageMapLock.Lock()
-               if waitChannel, ok := 
lxdStorageOngoingOperationMap[poolUmountLockID]; ok {
-                       close(waitChannel)
-                       delete(lxdStorageOngoingOperationMap, poolUmountLockID)
-               }
-               lxdStorageMapLock.Unlock()
-       }
-
-       defer removeLockFromMap()
-
-       // Check if already unmounted
-       poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
-       if !shared.IsMountPoint(poolMntPoint) {
-               return false, nil
-       }
-
-       // Unmount
-       err := driver.TryUnmount(poolMntPoint, syscall.MNT_DETACH)
-       if err != nil {
-               return false, err
-       }
-
-       logger.Debugf("Unmounted CEPHFS pool \"%s\"", s.pool.Name)
-       return true, nil
-}
-
-func (s *storageCephFs) GetStoragePoolWritable() api.StoragePoolPut {
-       return s.pool.Writable()
-}
-
-func (s *storageCephFs) GetStoragePoolVolumeWritable() api.StorageVolumePut {
-       return s.volume.Writable()
-}
-
-func (s *storageCephFs) SetStoragePoolWritable(writable *api.StoragePoolPut) {
-       s.pool.StoragePoolPut = *writable
-}
-
-func (s *storageCephFs) SetStoragePoolVolumeWritable(writable 
*api.StorageVolumePut) {
-       s.volume.StorageVolumePut = *writable
-}
-
-func (s *storageCephFs) GetContainerPoolInfo() (int64, string, string) {
-       return s.poolID, s.pool.Name, s.pool.Name
-}
-
-func (s *storageCephFs) StoragePoolUpdate(writable *api.StoragePoolPut, 
changedConfig []string) error {
-       logger.Infof(`Updating CEPHFS storage pool "%s"`, s.pool.Name)
-
-       // Validate the properties
-       changeable := changeableStoragePoolProperties["cephfs"]
-       unchangeable := []string{}
-       for _, change := range changedConfig {
-               if !shared.StringInSlice(change, changeable) {
-                       unchangeable = append(unchangeable, change)
-               }
-       }
-
-       if len(unchangeable) > 0 {
-               return updateStoragePoolError(unchangeable, "cephfs")
-       }
-
-       logger.Infof(`Updated CEPHFS storage pool "%s"`, s.pool.Name)
-       return nil
-}
-
-// Functions dealing with storage pools.
-func (s *storageCephFs) StoragePoolVolumeCreate() error {
-       logger.Infof("Creating CEPHFS storage volume \"%s\" on storage pool 
\"%s\"", s.volume.Name, s.pool.Name)
-
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return err
-       }
-
-       // Create the volume
-       storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
s.volume.Name)
-       err = os.MkdirAll(storageVolumePath, 0711)
-       if err != nil {
-               return err
-       }
-
-       logger.Infof("Created CEPHFS storage volume \"%s\" on storage pool 
\"%s\"", s.volume.Name, s.pool.Name)
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolVolumeDelete() error {
-       logger.Infof("Deleting CEPHFS storage volume \"%s\" on storage pool 
\"%s\"", s.volume.Name, s.pool.Name)
-
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return err
-       }
-
-       // Check if not gone already
-       storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
s.volume.Name)
-       if !shared.PathExists(storageVolumePath) {
-               return nil
-       }
-
-       // Delete the volume
-       err = os.RemoveAll(storageVolumePath)
-       if err != nil {
-               return err
-       }
-
-       // Delete the snapshot directory
-       err = 
os.Remove(driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, 
s.volume.Name))
-       if err != nil && !os.IsNotExist(err) {
-               return err
-       }
-
-       // Delete the database entry
-       err = s.s.Cluster.StoragePoolVolumeDelete("default", s.volume.Name, 
storagePoolVolumeTypeCustom, s.poolID)
-       if err != nil {
-               return err
-       }
-
-       logger.Infof("Deleted CEPHFS storage volume \"%s\" on storage pool 
\"%s\"", s.volume.Name, s.pool.Name)
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolVolumeMount() (bool, error) {
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return true, err
-       }
-
-       return true, nil
-}
-
-func (s *storageCephFs) StoragePoolVolumeUmount() (bool, error) {
-       return true, nil
-}
-
-func (s *storageCephFs) StoragePoolVolumeUpdate(writable 
*api.StorageVolumePut, changedConfig []string) error {
-       // Snapshot restores
-       if writable.Restore != "" {
-               logger.Infof(`Restoring CEPHFS storage volume "%s" from 
snapshot "%s"`, s.volume.Name, writable.Restore)
-
-               // Make sure the pool is currently mounted
-               _, err := s.StoragePoolMount()
-               if err != nil {
-                       return err
-               }
-
-               targetPath := 
driver.GetStoragePoolVolumeMountPoint(s.pool.Name, s.volume.Name)
-               sourcePath := filepath.Join(targetPath, ".snap", 
writable.Restore)
-
-               // Restore using rsync
-               bwlimit := s.pool.Config["rsync.bwlimit"]
-               output, err := rsync.LocalCopy(sourcePath, targetPath, bwlimit, 
false)
-               if err != nil {
-                       return fmt.Errorf("Failed to rsync container: %s: %s", 
string(output), err)
-               }
-
-               logger.Infof(`Restored CEPHFS storage volume "%s" from snapshot 
"%s"`, s.volume.Name, writable.Restore)
-               return nil
-       }
-
-       // Config updates
-       logger.Infof(`Updating CEPHFS storage volume "%s"`, s.volume.Name)
-
-       // Validate the properties
-       changeable := changeableStoragePoolVolumeProperties["cephfs"]
-       unchangeable := []string{}
-       for _, change := range changedConfig {
-               if !shared.StringInSlice(change, changeable) {
-                       unchangeable = append(unchangeable, change)
-               }
-       }
-
-       if len(unchangeable) > 0 {
-               return updateStoragePoolVolumeError(unchangeable, "cephfs")
-       }
-
-       // Handle setting quotas
-       if shared.StringInSlice("size", changedConfig) {
-               if s.volume.Type != storagePoolVolumeTypeNameCustom {
-                       return updateStoragePoolVolumeError([]string{"size"}, 
"cephfs")
-               }
-
-               if s.volume.Config["size"] != writable.Config["size"] {
-                       size, err := 
units.ParseByteSizeString(writable.Config["size"])
-                       if err != nil {
-                               return err
-                       }
-
-                       err = 
s.StorageEntitySetQuota(storagePoolVolumeTypeCustom, size, nil)
-                       if err != nil {
-                               return err
-                       }
-               }
-       }
-
-       logger.Infof(`Updated CEPHFS storage volume "%s"`, s.volume.Name)
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolVolumeRename(newName string) error {
-       logger.Infof(`Renaming CEPHFS storage volume on storage pool "%s" from 
"%s" to "%s`, s.pool.Name, s.volume.Name, newName)
-
-       // Sanity check
-       usedBy, err := storagePoolVolumeUsedByInstancesGet(s.s, "default", 
s.pool.Name, s.volume.Name)
-       if err != nil {
-               return err
-       }
-       if len(usedBy) > 0 {
-               return fmt.Errorf(`CEPHFS storage volume "%s" on storage pool 
"%s" is attached to containers`,
-                       s.volume.Name, s.pool.Name)
-       }
-
-       // Make sure the pool is currently mounted
-       _, err = s.StoragePoolMount()
-       if err != nil {
-               return err
-       }
-
-       // Rename the directory
-       oldPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
s.volume.Name)
-       newPath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, newName)
-       err = os.Rename(oldPath, newPath)
-       if err != nil {
-               return err
-       }
-
-       // Update the database entry
-       err = s.s.Cluster.StoragePoolVolumeRename("default", s.volume.Name, 
newName, storagePoolVolumeTypeCustom, s.poolID)
-       if err != nil {
-               return err
-       }
-
-       logger.Infof(`Renamed CEPHFS storage volume on storage pool "%s" from 
"%s" to "%s`, s.pool.Name, s.volume.Name, newName)
-       return nil
-}
-
-func (s *storageCephFs) ContainerStorageReady(container instance.Instance) 
bool {
-       containerMntPoint := driver.GetContainerMountPoint(container.Project(), 
s.pool.Name, container.Name())
-       ok, _ := shared.PathIsEmpty(containerMntPoint)
-       return !ok
-}
-
-func (s *storageCephFs) ContainerCreate(container instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerCreateFromImage(container instance.Instance, 
imageFingerprint string, tracker *ioprogress.ProgressTracker) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerCanRestore(container instance.Instance, 
sourceContainer instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerDelete(container instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerCopy(target instance.Instance, source 
instance.Instance, containerOnly bool) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerRefresh(target instance.Instance, source 
instance.Instance, snapshots []instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerMount(c instance.Instance) (bool, error) {
-       return false, fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerUmount(c instance.Instance, path string) 
(bool, error) {
-       return false, fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerRename(container instance.Instance, newName 
string) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerRestore(container instance.Instance, 
sourceContainer instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerGetUsage(c instance.Instance) (int64, error) {
-       return -1, fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerSnapshotCreate(snapshotContainer 
instance.Instance, sourceContainer instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerSnapshotCreateEmpty(snapshotContainer 
instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerSnapshotDelete(snapshotContainer 
instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerSnapshotRename(snapshotContainer 
instance.Instance, newName string) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerSnapshotStart(container instance.Instance) 
(bool, error) {
-       return false, fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerSnapshotStop(container instance.Instance) 
(bool, error) {
-       return false, fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerBackupCreate(path string, backup 
backup.Backup, source instance.Instance) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ContainerBackupLoad(info backup.Info, data 
io.ReadSeeker, tarArgs []string) error {
-       return fmt.Errorf("CEPHFS cannot be used for containers")
-}
-
-func (s *storageCephFs) ImageCreate(fingerprint string, tracker 
*ioprogress.ProgressTracker) error {
-       return fmt.Errorf("CEPHFS cannot be used for images")
-}
-
-func (s *storageCephFs) ImageDelete(fingerprint string) error {
-       return fmt.Errorf("CEPHFS cannot be used for images")
-}
-
-func (s *storageCephFs) ImageMount(fingerprint string) (bool, error) {
-       return false, fmt.Errorf("CEPHFS cannot be used for images")
-}
-
-func (s *storageCephFs) ImageUmount(fingerprint string) (bool, error) {
-       return false, fmt.Errorf("CEPHFS cannot be used for images")
-}
-
-func (s *storageCephFs) MigrationType() migration.MigrationFSType {
-       return migration.MigrationFSType_RSYNC
-}
-
-func (s *storageCephFs) PreservesInodes() bool {
-       return false
-}
-
-func (s *storageCephFs) MigrationSource(args MigrationSourceArgs) 
(MigrationStorageSourceDriver, error) {
-       return rsyncMigrationSource(args)
-}
-
-func (s *storageCephFs) MigrationSink(conn *websocket.Conn, op 
*operations.Operation, args MigrationSinkArgs) error {
-       return rsyncMigrationSink(conn, op, args)
-}
-
-func (s *storageCephFs) StorageEntitySetQuota(volumeType int, size int64, data 
interface{}) error {
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return nil
-       }
-
-       // Apply the limit
-       storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
s.volume.Name)
-       _, err = shared.RunCommand("setfattr", "-n", "ceph.quota.max_bytes", 
"-v", fmt.Sprintf("%d", size), storageVolumePath)
-       if err != nil {
-               return err
-       }
-
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolResources() (*api.ResourcesStoragePool, 
error) {
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return nil, err
-       }
-
-       poolMntPoint := driver.GetStoragePoolMountPoint(s.pool.Name)
-       return driver.GetStorageResource(poolMntPoint)
-}
-
-func (s *storageCephFs) StoragePoolVolumeCopy(source *api.StorageVolumeSource) 
error {
-       logger.Infof("Copying CEPHFS storage volume \"%s\" on storage pool 
\"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, 
s.volume.Name, s.pool.Name)
-
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return err
-       }
-
-       // Setup storage for the source volume
-       if s.pool.Name != source.Pool {
-               srcStorage, err := storagePoolVolumeInit(s.s, "default", 
source.Pool, source.Name, storagePoolVolumeTypeCustom)
-               if err != nil {
-                       logger.Errorf("Failed to initialize CEPHFS storage 
volume \"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
-                       return err
-               }
-
-               ourMount, err := srcStorage.StoragePoolMount()
-               if err != nil {
-                       logger.Errorf("Failed to mount CEPHFS storage volume 
\"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
-                       return err
-               }
-               if ourMount {
-                       defer srcStorage.StoragePoolUmount()
-               }
-       }
-
-       // Create empty volume
-       storageVolumePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
s.volume.Name)
-       err = os.MkdirAll(storageVolumePath, 0711)
-       if err != nil {
-               return err
-       }
-
-       // Copy the snapshots
-       if !source.VolumeOnly {
-               snapshots, err := driver.VolumeSnapshotsGet(s.s, source.Pool, 
source.Name, storagePoolVolumeTypeCustom)
-               if err != nil {
-                       return err
-               }
-
-               for _, snap := range snapshots {
-                       _, snapOnlyName, _ := 
shared.InstanceGetParentAndSnapshotName(snap.Name)
-                       err = s.copyVolume(source.Pool, snap.Name, 
fmt.Sprintf("%s/%s", s.volume.Name, snapOnlyName))
-                       if err != nil {
-                               return err
-                       }
-               }
-       }
-
-       // Copy the main volume
-       err = s.copyVolume(source.Pool, source.Name, s.volume.Name)
-       if err != nil {
-               return err
-       }
-
-       logger.Infof("Copied CEPHFS storage volume \"%s\" on storage pool 
\"%s\" as \"%s\" to storage pool \"%s\"", source.Name, source.Pool, 
s.volume.Name, s.pool.Name)
-       return nil
-}
-
-func (s *storageCephFs) StorageMigrationSource(args MigrationSourceArgs) 
(MigrationStorageSourceDriver, error) {
-       return rsyncStorageMigrationSource(args)
-}
-
-func (s *storageCephFs) StorageMigrationSink(conn *websocket.Conn, op 
*operations.Operation, args MigrationSinkArgs) error {
-       return rsyncStorageMigrationSink(conn, op, args)
-}
-
-func (s *storageCephFs) GetStoragePool() *api.StoragePool {
-       return s.pool
-}
-
-func (s *storageCephFs) GetStoragePoolVolume() *api.StorageVolume {
-       return s.volume
-}
-
-func (s *storageCephFs) GetState() *state.State {
-       return s.s
-}
-
-func (s *storageCephFs) StoragePoolVolumeSnapshotCreate(target 
*api.StorageVolumeSnapshotsPost) error {
-       logger.Infof("Creating CEPHFS storage volume snapshot \"%s\" on storage 
pool \"%s\"", s.volume.Name, s.pool.Name)
-
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return err
-       }
-
-       // Parse the name
-       sourceName, snapName, ok := 
shared.InstanceGetParentAndSnapshotName(target.Name)
-       if !ok {
-               return fmt.Errorf("Not a snapshot name")
-       }
-
-       // Create the snapshot
-       sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
sourceName)
-       cephSnapPath := filepath.Join(sourcePath, ".snap", snapName)
-
-       err = os.Mkdir(cephSnapPath, 0711)
-       if err != nil {
-               return err
-       }
-
-       // Make the snapshot path a symlink
-       targetPath := 
driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target.Name)
-       err = os.MkdirAll(filepath.Dir(targetPath), 0711)
-       if err != nil {
-               return err
-       }
-
-       err = os.Symlink(cephSnapPath, targetPath)
-       if err != nil {
-               return err
-       }
-
-       logger.Infof("Created CEPHFS storage volume snapshot \"%s\" on storage 
pool \"%s\"", s.volume.Name, s.pool.Name)
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolVolumeSnapshotDelete() error {
-       logger.Infof("Deleting CEPHFS storage volume snapshot \"%s\" on storage 
pool \"%s\"", s.volume.Name, s.pool.Name)
-
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return err
-       }
-
-       // Parse the name
-       sourceName, snapName, ok := 
shared.InstanceGetParentAndSnapshotName(s.volume.Name)
-       if !ok {
-               return fmt.Errorf("Not a snapshot name")
-       }
-
-       // Create the snapshot
-       sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
sourceName)
-       cephSnapPath := filepath.Join(sourcePath, ".snap", snapName)
-
-       err = os.Remove(cephSnapPath)
-       if err != nil && !os.IsNotExist(err) {
-               return err
-       }
-
-       // Make the snapshot path a symlink
-       targetPath := 
driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, s.volume.Name)
-       err = os.Remove(targetPath)
-       if err != nil && !os.IsNotExist(err) {
-               return err
-       }
-
-       // Delete the database entry
-       err = s.s.Cluster.StoragePoolVolumeDelete("default", s.volume.Name, 
storagePoolVolumeTypeCustom, s.poolID)
-       if err != nil {
-               logger.Errorf(`Failed to delete database entry for CEPHFS 
storage volume snapshot "%s" on storage pool "%s"`, s.volume.Name, s.pool.Name)
-               return err
-       }
-
-       logger.Infof("Deleted CEPHFS storage volume snapshot \"%s\" on storage 
pool \"%s\"", s.volume.Name, s.pool.Name)
-       return nil
-}
-
-func (s *storageCephFs) StoragePoolVolumeSnapshotRename(newName string) error {
-       logger.Infof("Renaming CEPHFS storage volume on storage pool \"%s\" 
from \"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
-
-       // Make sure the pool is currently mounted
-       _, err := s.StoragePoolMount()
-       if err != nil {
-               return err
-       }
-
-       // Rename the snapshot entry
-       sourceName, oldSnapName, _ := 
shared.InstanceGetParentAndSnapshotName(s.volume.Name)
-       sourcePath := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
sourceName)
-       oldCephSnapPath := filepath.Join(sourcePath, ".snap", oldSnapName)
-       newCephSnapPath := filepath.Join(sourcePath, ".snap", newName)
-
-       err = os.Rename(oldCephSnapPath, newCephSnapPath)
-       if err != nil {
-               return err
-       }
-
-       // Re-generate the snapshot symlink
-       oldPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, 
s.volume.Name)
-       err = os.Remove(oldPath)
-       if err != nil {
-               return err
-       }
-
-       newPath := driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, 
filepath.Join(sourceName, newName))
-       err = os.Symlink(newCephSnapPath, newPath)
-       if err != nil {
-               return err
-       }
-
-       // Update the database record
-       fullSnapshotName := fmt.Sprintf("%s%s%s", sourceName, 
shared.SnapshotDelimiter, newName)
-       err = s.s.Cluster.StoragePoolVolumeRename("default", s.volume.Name, 
fullSnapshotName, storagePoolVolumeTypeCustom, s.poolID)
-       if err != nil {
-               return err
-       }
-
-       logger.Infof("Renamed CEPHFS storage volume on storage pool \"%s\" from 
\"%s\" to \"%s\"", s.pool.Name, s.volume.Name, newName)
-       return nil
-}
-
-func (s *storageCephFs) copyVolume(sourcePool string, source string, target 
string) error {
-       // Figure out the mountpoints
-       var srcMountPoint string
-       if shared.IsSnapshot(source) {
-               srcMountPoint = 
driver.GetStoragePoolVolumeSnapshotMountPoint(sourcePool, source)
-       } else {
-               srcMountPoint = 
driver.GetStoragePoolVolumeMountPoint(sourcePool, source)
-       }
-
-       // Split target name
-       targetVolName, targetSnapName, ok := 
shared.InstanceGetParentAndSnapshotName(target)
-
-       // Figure out target path
-       dstMountPoint := driver.GetStoragePoolVolumeMountPoint(s.pool.Name, 
targetVolName)
-
-       // Sync data on target
-       bwlimit := s.pool.Config["rsync.bwlimit"]
-       _, err := rsync.LocalCopy(srcMountPoint, dstMountPoint, bwlimit, false)
-       if err != nil {
-               logger.Errorf("Failed to rsync into CEPHFS storage volume 
\"%s\" on storage pool \"%s\": %s", s.volume.Name, s.pool.Name, err)
-               return err
-       }
-
-       // Snapshot target
-       if ok {
-               cephSnapPath := filepath.Join(dstMountPoint, ".snap", 
targetSnapName)
-               err := os.Mkdir(cephSnapPath, 0711)
-               if err != nil {
-                       return err
-               }
-
-               // Make the snapshot path a symlink
-               targetPath := 
driver.GetStoragePoolVolumeSnapshotMountPoint(s.pool.Name, target)
-               err = os.MkdirAll(filepath.Dir(targetPath), 0711)
-               if err != nil {
-                       return err
-               }
-
-               err = os.Symlink(cephSnapPath, targetPath)
-               if err != nil {
-                       return err
-               }
-       }
-
-       return nil
-}
-
-func cephFsExists(clusterName string, userName string, fsName string) bool {
-       _, err := shared.RunCommand("ceph", "--name", fmt.Sprintf("client.%s", 
userName), "--cluster", clusterName, "fs", "get", fsName)
-       if err != nil {
-               return false
-       }
-
-       return true
-}
-
-func cephFsConfig(clusterName string, userName string) ([]string, string, 
error) {
-       // Parse the CEPH configuration
-       cephConf, err := os.Open(fmt.Sprintf("/etc/ceph/%s.conf", clusterName))
-       if err != nil {
-               return nil, "", err
-       }
-
-       cephMon := []string{}
-
-       scan := bufio.NewScanner(cephConf)
-       for scan.Scan() {
-               line := scan.Text()
-               line = strings.TrimSpace(line)
-
-               if line == "" {
-                       continue
-               }
-
-               if strings.HasPrefix(line, "mon_host") {
-                       fields := strings.SplitN(line, "=", 2)
-                       if len(fields) < 2 {
-                               continue
-                       }
-
-                       servers := strings.Split(fields[1], ",")
-                       for _, server := range servers {
-                               cephMon = append(cephMon, 
strings.TrimSpace(server))
-                       }
-                       break
-               }
-       }
-
-       if len(cephMon) == 0 {
-               return nil, "", fmt.Errorf("Couldn't find a CPEH mon")
-       }
-
-       // Parse the CEPH keyring
-       cephKeyring, err := 
os.Open(fmt.Sprintf("/etc/ceph/%v.client.%v.keyring", clusterName, userName))
-       if err != nil {
-               return nil, "", err
-       }
-
-       var cephSecret string
-
-       scan = bufio.NewScanner(cephKeyring)
-       for scan.Scan() {
-               line := scan.Text()
-               line = strings.TrimSpace(line)
-
-               if line == "" {
-                       continue
-               }
-
-               if strings.HasPrefix(line, "key") {
-                       fields := strings.SplitN(line, "=", 2)
-                       if len(fields) < 2 {
-                               continue
-                       }
-
-                       cephSecret = strings.TrimSpace(fields[1])
-                       break
-               }
-       }
-
-       if cephSecret == "" {
-               return nil, "", fmt.Errorf("Couldn't find a keyring entry")
-       }
-
-       return cephMon, cephSecret, nil
-}
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to