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

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) ===
Fixes an issue that means that block custom volumes were incorrectly populated with filesystem options, which prevented future modification of the volume as failed validation.
From 432633b96f40a2efce03dfb36bdf02228fdf386c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:42:23 +0000
Subject: [PATCH 01/13] lxd/patches/utils: Adds legacy volumeFillDefault
 function for patches

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/patches_utils.go | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/lxd/patches_utils.go b/lxd/patches_utils.go
index 256422f32e..fa00348024 100644
--- a/lxd/patches_utils.go
+++ b/lxd/patches_utils.go
@@ -14,6 +14,7 @@ import (
        "github.com/lxc/lxd/lxd/state"
        storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
        "github.com/lxc/lxd/shared"
+       "github.com/lxc/lxd/shared/api"
        "github.com/lxc/lxd/shared/units"
 )
 
@@ -223,3 +224,27 @@ func lvmGetLVSize(lvPath string) (string, error) {
 
        return detectedSize, nil
 }
+
+// volumeFillDefault fills default settings into a volume config.
+// Deprecated. Please use FillInstanceConfig() on the storage pool.
+func volumeFillDefault(config map[string]string, parentPool *api.StoragePool) 
error {
+       if parentPool.Driver == "lvm" || parentPool.Driver == "ceph" {
+               if config["block.filesystem"] == "" {
+                       config["block.filesystem"] = 
parentPool.Config["volume.block.filesystem"]
+               }
+               if config["block.filesystem"] == "" {
+                       // Unchangeable volume property: Set unconditionally.
+                       config["block.filesystem"] = 
storageDrivers.DefaultFilesystem
+               }
+
+               if config["block.mount_options"] == "" {
+                       config["block.mount_options"] = 
parentPool.Config["volume.block.mount_options"]
+               }
+               if config["block.mount_options"] == "" {
+                       // Unchangeable volume property: Set unconditionally.
+                       config["block.mount_options"] = "discard"
+               }
+       }
+
+       return nil
+}

From f0daf911c1f8ca9cf322a1184bb506eb6e1c529a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:44:13 +0000
Subject: [PATCH 02/13] lxd/patches: Updates patches to switch from
 driver.VolumeFillDefault to volumeFillDefault

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/patches.go | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lxd/patches.go b/lxd/patches.go
index ef0bbee33c..194a5695c9 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -877,7 +877,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, 
defaultPoolName string,
                // Initialize empty storage volume configuration for the
                // container.
                containerPoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(containerPoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(containerPoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -965,7 +965,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, 
defaultPoolName string,
                        // Initialize empty storage volume configuration for the
                        // container.
                        snapshotPoolVolumeConfig := map[string]string{}
-                       err = 
driver.VolumeFillDefault(snapshotPoolVolumeConfig, defaultPool)
+                       err = volumeFillDefault(snapshotPoolVolumeConfig, 
defaultPool)
                        if err != nil {
                                return err
                        }
@@ -1046,7 +1046,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, 
defaultPoolName string,
        images := append(imgPublic, imgPrivate...)
        for _, img := range images {
                imagePoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(imagePoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(imagePoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -1167,7 +1167,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, 
defaultPoolName string, d
                // Initialize empty storage volume configuration for the
                // container.
                containerPoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(containerPoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(containerPoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -1284,7 +1284,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, 
defaultPoolName string, d
                // Initialize empty storage volume configuration for the
                // container.
                snapshotPoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(snapshotPoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(snapshotPoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -1314,7 +1314,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, 
defaultPoolName string, d
        images := append(imgPublic, imgPrivate...)
        for _, img := range images {
                imagePoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(imagePoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(imagePoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -1476,7 +1476,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, 
defaultPoolName string, d
                // Initialize empty storage volume configuration for the
                // container.
                containerPoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(containerPoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(containerPoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -1634,7 +1634,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, 
defaultPoolName string, d
                        // Initialize empty storage volume configuration for the
                        // container.
                        snapshotPoolVolumeConfig := map[string]string{}
-                       err = 
driver.VolumeFillDefault(snapshotPoolVolumeConfig, defaultPool)
+                       err = volumeFillDefault(snapshotPoolVolumeConfig, 
defaultPool)
                        if err != nil {
                                return err
                        }
@@ -1814,7 +1814,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, 
defaultPoolName string, d
 
        for _, img := range images {
                imagePoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(imagePoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(imagePoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -2006,7 +2006,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, 
defaultPoolName string, d
                // Initialize empty storage volume configuration for the
                // container.
                containerPoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(containerPoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(containerPoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -2092,7 +2092,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, 
defaultPoolName string, d
                        // Initialize empty storage volume configuration for the
                        // container.
                        snapshotPoolVolumeConfig := map[string]string{}
-                       err = 
driver.VolumeFillDefault(snapshotPoolVolumeConfig, defaultPool)
+                       err = volumeFillDefault(snapshotPoolVolumeConfig, 
defaultPool)
                        if err != nil {
                                return err
                        }
@@ -2148,7 +2148,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, 
defaultPoolName string, d
        images := append(imgPublic, imgPrivate...)
        for _, img := range images {
                imagePoolVolumeConfig := map[string]string{}
-               err = driver.VolumeFillDefault(imagePoolVolumeConfig, 
defaultPool)
+               err = volumeFillDefault(imagePoolVolumeConfig, defaultPool)
                if err != nil {
                        return err
                }
@@ -2640,7 +2640,7 @@ func patchStorageApiUpdateStorageConfigs(name string, d 
*Daemon) error {
                        }
 
                        // Insert default values.
-                       err := driver.VolumeFillDefault(volume.Config, pool)
+                       err := volumeFillDefault(volume.Config, pool)
                        if err != nil {
                                return err
                        }
@@ -2816,7 +2816,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) 
error {
                                volume.Config = map[string]string{}
 
                                // Insert default values.
-                               err := driver.VolumeFillDefault(volume.Config, 
pool)
+                               err := volumeFillDefault(volume.Config, pool)
                                if err != nil {
                                        return err
                                }

From c54218714cd930771a1a9f33a544048fe8e448b2 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:45:29 +0000
Subject: [PATCH 03/13] lxd/storage/drivers/interface: Adds FillVolumeConfig

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/interface.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lxd/storage/drivers/interface.go b/lxd/storage/drivers/interface.go
index 82450ad5e5..7e04b92e1a 100644
--- a/lxd/storage/drivers/interface.go
+++ b/lxd/storage/drivers/interface.go
@@ -46,6 +46,7 @@ type Driver interface {
        ApplyPatch(name string) error
 
        // Volumes.
+       FillVolumeConfig(vol Volume) error
        ValidateVolume(vol Volume, removeUnknownKeys bool) error
        CreateVolume(vol Volume, filler *VolumeFiller, op 
*operations.Operation) error
        CreateVolumeFromCopy(vol Volume, srcVol Volume, copySnapshots bool, op 
*operations.Operation) error

From 940cdb499856182c99087c0f5f9597188b31220f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:45:43 +0000
Subject: [PATCH 04/13] lxd/storage/drivers/driver/common: Adds
 FillVolumeConfig no-op for common drivers

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/driver_common.go | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/lxd/storage/drivers/driver_common.go 
b/lxd/storage/drivers/driver_common.go
index e15950acad..1aaa5561fe 100644
--- a/lxd/storage/drivers/driver_common.go
+++ b/lxd/storage/drivers/driver_common.go
@@ -77,6 +77,11 @@ func (d *common) validatePool(config map[string]string, 
driverRules map[string]f
        return nil
 }
 
+// FillVolumeConfig populate volume with default config.
+func (d *common) FillVolumeConfig(vol Volume) error {
+       return nil
+}
+
 // validateVolume validates a volume config against common rules and optional 
driver specific rules.
 // This functions has a removeUnknownKeys option that if set to true will 
remove any unknown fields
 // (excluding those starting with "user.") which can be used when translating 
a volume config to a

From bcd4898f938f6fdc0e6e843aa33b2b90fe12a737 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:47:31 +0000
Subject: [PATCH 05/13] lxd/storage/drivers/driver/{ceph,lvm}: Adds
 FillVolumeConfig function to populate default filesystem settings

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/drivers/driver_ceph_volumes.go | 31 ++++++++++++++++++++++
 lxd/storage/drivers/driver_lvm_volumes.go  | 31 ++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/lxd/storage/drivers/driver_ceph_volumes.go 
b/lxd/storage/drivers/driver_ceph_volumes.go
index be2143c02c..8d1b302236 100644
--- a/lxd/storage/drivers/driver_ceph_volumes.go
+++ b/lxd/storage/drivers/driver_ceph_volumes.go
@@ -708,6 +708,37 @@ func (d *ceph) HasVolume(vol Volume) bool {
        return err == nil
 }
 
+// FillVolumeConfig populate volume with default config.
+func (d *ceph) FillVolumeConfig(vol Volume) error {
+       // Only validate filesystem config keys for filesystem volumes or VM 
block volumes (which have an
+       // associated filesystem volume).
+       if vol.ContentType() == ContentTypeFS || vol.IsVMBlock() {
+               // Inherit filesystem from pool if not set.
+               if vol.config["block.filesystem"] == "" {
+                       vol.config["block.filesystem"] = 
d.config["volume.block.filesystem"]
+               }
+
+               // Default filesystem if neither volume nor pool specify an 
override.
+               if vol.config["block.filesystem"] == "" {
+                       // Unchangeable volume property: Set unconditionally.
+                       vol.config["block.filesystem"] = DefaultFilesystem
+               }
+
+               // Inherit filesystem mount options from pool if not set.
+               if vol.config["block.mount_options"] == "" {
+                       vol.config["block.mount_options"] = 
d.config["volume.block.mount_options"]
+               }
+
+               // Default filesystem mount options if neither volume nor pool 
specify an override.
+               if vol.config["block.mount_options"] == "" {
+                       // Unchangeable volume property: Set unconditionally.
+                       vol.config["block.mount_options"] = "discard"
+               }
+       }
+
+       return nil
+}
+
 // ValidateVolume validates the supplied volume config.
 func (d *ceph) ValidateVolume(vol Volume, removeUnknownKeys bool) error {
        rules := map[string]func(value string) error{
diff --git a/lxd/storage/drivers/driver_lvm_volumes.go 
b/lxd/storage/drivers/driver_lvm_volumes.go
index 2e0561f1b1..6580fc206b 100644
--- a/lxd/storage/drivers/driver_lvm_volumes.go
+++ b/lxd/storage/drivers/driver_lvm_volumes.go
@@ -239,6 +239,37 @@ func (d *lvm) HasVolume(vol Volume) bool {
        return volExists
 }
 
+// FillVolumeConfig populate volume with default config.
+func (d *lvm) FillVolumeConfig(vol Volume) error {
+       // Only validate filesystem config keys for filesystem volumes or VM 
block volumes (which have an
+       // associated filesystem volume).
+       if vol.ContentType() == ContentTypeFS || vol.IsVMBlock() {
+               // Inherit filesystem from pool if not set.
+               if vol.config["block.filesystem"] == "" {
+                       vol.config["block.filesystem"] = 
d.config["volume.block.filesystem"]
+               }
+
+               // Default filesystem if neither volume nor pool specify an 
override.
+               if vol.config["block.filesystem"] == "" {
+                       // Unchangeable volume property: Set unconditionally.
+                       vol.config["block.filesystem"] = DefaultFilesystem
+               }
+
+               // Inherit filesystem mount options from pool if not set.
+               if vol.config["block.mount_options"] == "" {
+                       vol.config["block.mount_options"] = 
d.config["volume.block.mount_options"]
+               }
+
+               // Default filesystem mount options if neither volume nor pool 
specify an override.
+               if vol.config["block.mount_options"] == "" {
+                       // Unchangeable volume property: Set unconditionally.
+                       vol.config["block.mount_options"] = "discard"
+               }
+       }
+
+       return nil
+}
+
 // ValidateVolume validates the supplied volume config.
 func (d *lvm) ValidateVolume(vol Volume, removeUnknownKeys bool) error {
        rules := map[string]func(value string) error{

From aeee0a8d5b2a057f70166952afcc6964102be4cf Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:49:29 +0000
Subject: [PATCH 06/13] lxd/storage/utils: Updates VolumeDBCreate to accept a
 Pool and call driver.FillVolumeConfig

 - Avoids extra pool lookup.
 - Allows per-drive volume defaults to be populated.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/utils.go | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index 393d8dbad6..8cabd43f9c 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -192,7 +192,7 @@ func VolumeContentTypeNameToContentType(contentTypeName 
string) (int, error) {
 }
 
 // VolumeDBCreate creates a volume in the database.
-func VolumeDBCreate(s *state.State, project, poolName, volumeName, 
volumeDescription, volumeTypeName string, snapshot bool, volumeConfig 
map[string]string, expiryDate time.Time, contentTypeName string) error {
+func VolumeDBCreate(s *state.State, pool Pool, projectName string, volumeName 
string, volumeDescription string, volumeTypeName string, snapshot bool, 
volumeConfig map[string]string, expiryDate time.Time, contentTypeName string) 
error {
        // Convert the volume type name to our internal integer representation.
        volDBType, err := VolumeTypeNameToDBType(volumeTypeName)
        if err != nil {
@@ -204,14 +204,8 @@ func VolumeDBCreate(s *state.State, project, poolName, 
volumeName, volumeDescrip
                return err
        }
 
-       // Load storage pool the volume will be attached to.
-       poolID, poolStruct, err := s.Cluster.GetStoragePool(poolName)
-       if err != nil {
-               return err
-       }
-
        // Check that a storage volume of the same storage volume type does not 
already exist.
-       volumeID, _ := s.Cluster.GetStoragePoolNodeVolumeID(project, 
volumeName, volDBType, poolID)
+       volumeID, _ := s.Cluster.GetStoragePoolNodeVolumeID(projectName, 
volumeName, volDBType, pool.ID())
        if volumeID > 0 {
                return fmt.Errorf("A storage volume of type %s already exists", 
volumeTypeName)
        }
@@ -226,25 +220,28 @@ func VolumeDBCreate(s *state.State, project, poolName, 
volumeName, volumeDescrip
                return err
        }
 
-       // Validate the requested storage volume configuration.
-       err = VolumeValidateConfig(s, volumeName, volType, volumeConfig, 
poolStruct)
+       vol := drivers.NewVolume(pool.Driver(), pool.Name(), volType, 
drivers.ContentType(contentTypeName), volumeName, volumeConfig, 
pool.Driver().Config())
+
+       // Fill default config.
+       err = pool.Driver().FillVolumeConfig(vol)
        if err != nil {
                return err
        }
 
-       err = VolumeFillDefault(volumeConfig, poolStruct)
+       // Validate config.
+       err = pool.Driver().ValidateVolume(vol, false)
        if err != nil {
                return err
        }
 
        // Create the database entry for the storage volume.
        if snapshot {
-               _, err = s.Cluster.CreateStorageVolumeSnapshot(project, 
volumeName, volumeDescription, volDBType, poolID, volumeConfig, expiryDate)
+               _, err = s.Cluster.CreateStorageVolumeSnapshot(projectName, 
volumeName, volumeDescription, volDBType, pool.ID(), vol.Config(), expiryDate)
        } else {
-               _, err = s.Cluster.CreateStoragePoolVolume(project, volumeName, 
volumeDescription, volDBType, poolID, volumeConfig, volDBContentType)
+               _, err = s.Cluster.CreateStoragePoolVolume(projectName, 
volumeName, volumeDescription, volDBType, pool.ID(), vol.Config(), 
volDBContentType)
        }
        if err != nil {
-               return fmt.Errorf("Error inserting %q of type %q into database 
%q", poolName, volumeTypeName, err)
+               return fmt.Errorf("Error inserting %q of type %q into database 
%q", pool.Name(), volumeTypeName, err)
        }
 
        return nil

From b78d3f2c19a171dd32ae746e3e397ead685d04ff Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:50:32 +0000
Subject: [PATCH 07/13] lxd/storage/backend/lxd: VolumeDBCreate usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/backend_lxd.go | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index 74cd942d07..a411e36df1 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -2222,7 +2222,7 @@ func (b *lxdBackend) EnsureImage(fingerprint string, op 
*operations.Operation) e
                }
        }
 
-       err = VolumeDBCreate(b.state, project.Default, b.name, fingerprint, "", 
db.StoragePoolVolumeTypeNameImage, false, volConfig, time.Time{}, dbContentType)
+       err = VolumeDBCreate(b.state, b, project.Default, fingerprint, "", 
db.StoragePoolVolumeTypeNameImage, false, volConfig, time.Time{}, dbContentType)
        if err != nil {
                return err
        }
@@ -2335,7 +2335,7 @@ func (b *lxdBackend) CreateCustomVolume(projectName 
string, volName string, desc
        }
 
        // Create database entry for new storage volume.
-       err = VolumeDBCreate(b.state, projectName, b.name, volName, desc, 
db.StoragePoolVolumeTypeNameCustom, false, vol.Config(), time.Time{}, 
string(contentType))
+       err = VolumeDBCreate(b.state, b, projectName, volName, desc, 
db.StoragePoolVolumeTypeNameCustom, false, vol.Config(), time.Time{}, 
string(contentType))
        if err != nil {
                return err
        }
@@ -2459,7 +2459,7 @@ func (b *lxdBackend) 
CreateCustomVolumeFromCopy(projectName string, volName stri
                }
 
                // Create database entry for new storage volume.
-               err = VolumeDBCreate(b.state, projectName, b.name, volName, 
desc, db.StoragePoolVolumeTypeNameCustom, false, vol.Config(), time.Time{}, 
string(contentType))
+               err = VolumeDBCreate(b.state, b, projectName, volName, desc, 
db.StoragePoolVolumeTypeNameCustom, false, vol.Config(), time.Time{}, 
string(contentType))
                if err != nil {
                        return err
                }
@@ -2471,7 +2471,7 @@ func (b *lxdBackend) 
CreateCustomVolumeFromCopy(projectName string, volName stri
                                newSnapshotName := 
drivers.GetSnapshotVolumeName(volName, snapName)
 
                                // Create database entry for new storage volume 
snapshot.
-                               err = VolumeDBCreate(b.state, projectName, 
b.name, newSnapshotName, desc, db.StoragePoolVolumeTypeNameCustom, true, 
vol.Config(), time.Time{}, string(contentType))
+                               err = VolumeDBCreate(b.state, b, projectName, 
newSnapshotName, desc, db.StoragePoolVolumeTypeNameCustom, true, vol.Config(), 
time.Time{}, string(contentType))
                                if err != nil {
                                        return err
                                }
@@ -2653,7 +2653,7 @@ func (b *lxdBackend) 
CreateCustomVolumeFromMigration(projectName string, conn io
        }
 
        // Create database entry for new storage volume.
-       err = VolumeDBCreate(b.state, projectName, b.name, args.Name, 
args.Description, db.StoragePoolVolumeTypeNameCustom, false, vol.Config(), 
time.Time{}, args.ContentType)
+       err = VolumeDBCreate(b.state, b, projectName, args.Name, 
args.Description, db.StoragePoolVolumeTypeNameCustom, false, vol.Config(), 
time.Time{}, args.ContentType)
        if err != nil {
                return err
        }
@@ -2665,7 +2665,7 @@ func (b *lxdBackend) 
CreateCustomVolumeFromMigration(projectName string, conn io
                        newSnapshotName := 
drivers.GetSnapshotVolumeName(args.Name, snapName)
 
                        // Create database entry for new storage volume 
snapshot.
-                       err = VolumeDBCreate(b.state, projectName, b.name, 
newSnapshotName, args.Description, db.StoragePoolVolumeTypeNameCustom, true, 
vol.Config(), time.Time{}, args.ContentType)
+                       err = VolumeDBCreate(b.state, b, projectName, 
newSnapshotName, args.Description, db.StoragePoolVolumeTypeNameCustom, true, 
vol.Config(), time.Time{}, args.ContentType)
                        if err != nil {
                                return err
                        }
@@ -3124,7 +3124,7 @@ func (b *lxdBackend) 
CreateCustomVolumeSnapshot(projectName, volName string, new
        }
 
        // Create database entry for new storage volume snapshot.
-       err = VolumeDBCreate(b.state, projectName, b.name, fullSnapshotName, 
parentVol.Description, db.StoragePoolVolumeTypeNameCustom, true, 
parentVol.Config, newExpiryDate, parentVol.ContentType)
+       err = VolumeDBCreate(b.state, b, projectName, fullSnapshotName, 
parentVol.Description, db.StoragePoolVolumeTypeNameCustom, true, 
parentVol.Config, newExpiryDate, parentVol.ContentType)
        if err != nil {
                return err
        }
@@ -3629,7 +3629,7 @@ func (b *lxdBackend) 
CreateCustomVolumeFromBackup(srcBackup backup.Info, srcData
        }
 
        // Create database entry for new storage volume using the validated 
config.
-       err = VolumeDBCreate(b.state, srcBackup.Project, b.name, 
srcBackup.Name, srcBackup.Config.Volume.Description, 
db.StoragePoolVolumeTypeNameCustom, false, vol.Config(), time.Time{}, 
string(vol.ContentType()))
+       err = VolumeDBCreate(b.state, b, srcBackup.Project, srcBackup.Name, 
srcBackup.Config.Volume.Description, db.StoragePoolVolumeTypeNameCustom, false, 
vol.Config(), time.Time{}, string(vol.ContentType()))
        if err != nil {
                return err
        }
@@ -3652,7 +3652,7 @@ func (b *lxdBackend) 
CreateCustomVolumeFromBackup(srcBackup backup.Info, srcData
                        return err
                }
 
-               err = VolumeDBCreate(b.state, srcBackup.Project, b.name, 
fullSnapName, snapshot.Description, db.StoragePoolVolumeTypeNameCustom, true, 
snapVol.Config(), *snapshot.ExpiresAt, string(snapVol.ContentType()))
+               err = VolumeDBCreate(b.state, b, srcBackup.Project, 
fullSnapName, snapshot.Description, db.StoragePoolVolumeTypeNameCustom, true, 
snapVol.Config(), *snapshot.ExpiresAt, string(snapVol.ContentType()))
                if err != nil {
                        return err
                }

From 478f74f076e3d5537e6dce7161b6f39da339c4e8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:50:08 +0000
Subject: [PATCH 08/13] lxd/storage/utils: Removes VolumeFillDefault and
 VolumeValidateConfig

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/utils.go | 77 --------------------------------------------
 1 file changed, 77 deletions(-)

diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index 8cabd43f9c..c070c3375f 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -307,83 +307,6 @@ var StorageVolumeConfigKeys = map[string]func(value 
string) ([]string, error){
        },
 }
 
-// VolumeValidateConfig validations volume config. Deprecated.
-func VolumeValidateConfig(s *state.State, volName string, volType 
drivers.VolumeType, config map[string]string, parentPool *api.StoragePool) 
error {
-       logger := logging.AddContext(logger.Log, log.Ctx{"driver": 
parentPool.Driver, "pool": parentPool.Name})
-
-       // Validate volume config using the new driver interface if supported.
-       driver, err := drivers.Load(s, parentPool.Driver, parentPool.Name, 
parentPool.Config, logger, nil, commonRules())
-       if err != drivers.ErrUnknownDriver {
-               // Note: This legacy validation function doesn't have the 
concept of validating different content
-               // types, so it is hardcoded as ContentTypeFS.
-               return driver.ValidateVolume(drivers.NewVolume(driver, 
parentPool.Name, volType, drivers.ContentTypeFS, volName, config, 
parentPool.Config), false)
-       }
-
-       // Otherwise fallback to doing legacy validation.
-       for key, val := range config {
-               // User keys are not validated.
-               if strings.HasPrefix(key, "user.") {
-                       continue
-               }
-
-               // Validate storage volume config keys.
-               validator, ok := StorageVolumeConfigKeys[key]
-               if !ok {
-                       return fmt.Errorf("Invalid storage volume configuration 
key: %s", key)
-               }
-
-               _, err := validator(val)
-               if err != nil {
-                       return err
-               }
-
-               if parentPool.Driver != "zfs" || parentPool.Driver == "dir" {
-                       if config["zfs.use_refquota"] != "" {
-                               return fmt.Errorf("the key 
volume.zfs.use_refquota cannot be used with non zfs storage volumes")
-                       }
-
-                       if config["zfs.remove_snapshots"] != "" {
-                               return fmt.Errorf("the key 
volume.zfs.remove_snapshots cannot be used with non zfs storage volumes")
-                       }
-               }
-
-               if parentPool.Driver == "dir" {
-                       if config["block.mount_options"] != "" {
-                               return fmt.Errorf("the key block.mount_options 
cannot be used with dir storage volumes")
-                       }
-
-                       if config["block.filesystem"] != "" {
-                               return fmt.Errorf("the key block.filesystem 
cannot be used with dir storage volumes")
-                       }
-               }
-       }
-
-       return nil
-}
-
-// VolumeFillDefault fills default settings into a volume config.
-func VolumeFillDefault(config map[string]string, parentPool *api.StoragePool) 
error {
-       if parentPool.Driver == "lvm" || parentPool.Driver == "ceph" {
-               if config["block.filesystem"] == "" {
-                       config["block.filesystem"] = 
parentPool.Config["volume.block.filesystem"]
-               }
-               if config["block.filesystem"] == "" {
-                       // Unchangeable volume property: Set unconditionally.
-                       config["block.filesystem"] = drivers.DefaultFilesystem
-               }
-
-               if config["block.mount_options"] == "" {
-                       config["block.mount_options"] = 
parentPool.Config["volume.block.mount_options"]
-               }
-               if config["block.mount_options"] == "" {
-                       // Unchangeable volume property: Set unconditionally.
-                       config["block.mount_options"] = "discard"
-               }
-       }
-
-       return nil
-}
-
 // VolumeSnapshotsGet returns a list of snapshots of the form 
<volume>/<snapshot-name>.
 func VolumeSnapshotsGet(s *state.State, projectName string, pool string, 
volume string, volType int) ([]db.StorageVolumeArgs, error) {
        poolID, err := s.Cluster.GetStoragePoolID(pool)

From 89765ec19228101408d5116036b2cefda947c734 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:44:40 +0000
Subject: [PATCH 09/13] lxd/storage/pool/interface: Adds FillInstanceConfig

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/pool_interface.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lxd/storage/pool_interface.go b/lxd/storage/pool_interface.go
index 5423c89829..ec04657621 100644
--- a/lxd/storage/pool_interface.go
+++ b/lxd/storage/pool_interface.go
@@ -35,6 +35,7 @@ type Pool interface {
        ApplyPatch(name string) error
 
        // Instances.
+       FillInstanceConfig(inst instance.Instance, config map[string]string) 
error
        CreateInstance(inst instance.Instance, op *operations.Operation) error
        CreateInstanceFromBackup(srcBackup backup.Info, srcData io.ReadSeeker, 
op *operations.Operation) (func(instance.Instance) error, func(), error)
        CreateInstanceFromCopy(inst instance.Instance, src instance.Instance, 
snapshots bool, op *operations.Operation) error

From 97194874c4089ef337d9b23d184562f35e6ea31e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:48:23 +0000
Subject: [PATCH 10/13] lxd/storage/backend/lxd: Implements FillInstanceConfig

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/backend_lxd.go | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index a411e36df1..a2c86b94e9 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -430,6 +430,38 @@ func (b *lxdBackend) instanceRootVolumeConfig(inst 
instance.Instance) (map[strin
        return vol.Config, nil
 }
 
+// FillInstanceConfig populates the supplied instance volume config map with 
any defaults based on the storage
+// pool and instance type being used.
+func (b *lxdBackend) FillInstanceConfig(inst instance.Instance, config 
map[string]string) error {
+       logger := logging.AddContext(b.logger, log.Ctx{"project": 
inst.Project(), "instance": inst.Name()})
+       logger.Debug("FillInstanceConfig started")
+       defer logger.Debug("FillInstanceConfig finished")
+
+       volType, err := InstanceTypeToVolumeType(inst.Type())
+       if err != nil {
+               return err
+       }
+
+       contentType := InstanceContentType(inst)
+
+       // Get the volume name on storage.
+       volStorageName := project.Instance(inst.Project(), inst.Name())
+
+       // Fill default config in volume (creates internal copy of supplied 
config and modifies that).
+       vol := b.newVolume(volType, contentType, volStorageName, config)
+       err = b.driver.FillVolumeConfig(vol)
+       if err != nil {
+               return err
+       }
+
+       // Copy filled volume config back into supplied config map.
+       for k, v := range vol.Config() {
+               config[k] = v
+       }
+
+       return nil
+}
+
 // CreateInstance creates an empty instance.
 func (b *lxdBackend) CreateInstance(inst instance.Instance, op 
*operations.Operation) error {
        logger := logging.AddContext(b.logger, log.Ctx{"project": 
inst.Project(), "instance": inst.Name()})

From c21b90025e5a66949e0ab6de818354a19c9dec21 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:50:49 +0000
Subject: [PATCH 11/13] lxd/storage/backend/mock: Adds FillInstanceConfig

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/storage/backend_mock.go | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lxd/storage/backend_mock.go b/lxd/storage/backend_mock.go
index bfc443fa29..ec0f9c198f 100644
--- a/lxd/storage/backend_mock.go
+++ b/lxd/storage/backend_mock.go
@@ -67,6 +67,10 @@ func (b *mockBackend) ApplyPatch(name string) error {
        return nil
 }
 
+func (b *mockBackend) FillInstanceConfig(inst instance.Instance, config 
map[string]string) error {
+       return nil
+}
+
 func (b *mockBackend) CreateInstance(inst instance.Instance, op 
*operations.Operation) error {
        return nil
 }

From 0ba1df4f34d46a26f157ed453394cb0f11ccc53d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:51:26 +0000
Subject: [PATCH 12/13] lxd/instance/drivers/driver/lxc: Updates lxcCreate to
 use storagePool.FillInstanceConfig

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/driver_lxc.go | 20 +++++---------------
 1 file changed, 5 insertions(+), 15 deletions(-)

diff --git a/lxd/instance/drivers/driver_lxc.go 
b/lxd/instance/drivers/driver_lxc.go
index 054c698372..f21fcb315d 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -233,39 +233,29 @@ func lxcCreate(s *state.State, args db.InstanceArgs) 
(instance.Instance, error)
                return nil, fmt.Errorf("The container's root device is missing 
the pool property")
        }
 
-       storagePool := rootDiskDevice["pool"]
-
-       // Get the storage pool ID for the container.
-       poolID, dbPool, err := s.Cluster.GetStoragePool(storagePool)
-       if err != nil {
-               return nil, err
-       }
-
        // Initialize the storage pool.
-       pool, err := storagePools.GetPoolByName(c.state, storagePool)
+       c.storagePool, err = storagePools.GetPoolByName(c.state, 
rootDiskDevice["pool"])
        if err != nil {
                return nil, err
        }
 
-       // Fill in any default volume config.
+       // Fill default config.
        volumeConfig := map[string]string{}
-       err = storagePools.VolumeFillDefault(volumeConfig, dbPool)
+       err = c.storagePool.FillInstanceConfig(c, volumeConfig)
        if err != nil {
                return nil, err
        }
 
        // Create a new storage volume database entry for the container's 
storage volume.
        if c.IsSnapshot() {
-               _, err = s.Cluster.CreateStorageVolumeSnapshot(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeContainer, poolID, volumeConfig, 
time.Time{})
+               _, err = s.Cluster.CreateStorageVolumeSnapshot(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeContainer, c.storagePool.ID(), 
volumeConfig, time.Time{})
        } else {
-               _, err = s.Cluster.CreateStoragePoolVolume(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeContainer, poolID, volumeConfig, 
db.StoragePoolVolumeContentTypeFS)
+               _, err = s.Cluster.CreateStoragePoolVolume(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeContainer, c.storagePool.ID(), 
volumeConfig, db.StoragePoolVolumeContentTypeFS)
        }
        if err != nil {
                return nil, err
        }
 
-       c.storagePool = pool
-
        // Setup initial idmap config
        var idmap *idmap.IdmapSet
        base := int64(0)

From 28bf8ac84bcb40351ab832c90c8dc75bd49fb03e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Thu, 19 Nov 2020 12:51:52 +0000
Subject: [PATCH 13/13] lxd/instance/drivers/driver/qemu: Updates qemuCreate to
 use storagePool.FillInstanceConfig

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/driver_qemu.go | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/lxd/instance/drivers/driver_qemu.go 
b/lxd/instance/drivers/driver_qemu.go
index abd05b2e85..ce3d08adc8 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -250,27 +250,25 @@ func qemuCreate(s *state.State, args db.InstanceArgs) 
(instance.Instance, error)
                return nil, fmt.Errorf("The instances's root device is missing 
the pool property")
        }
 
-       storagePool := rootDiskDevice["pool"]
-
-       // Get the storage pool ID for the instance.
-       poolID, pool, err := s.Cluster.GetStoragePool(storagePool)
+       // Initialize the storage pool.
+       vm.storagePool, err = storagePools.GetPoolByName(vm.state, 
rootDiskDevice["pool"])
        if err != nil {
                return nil, err
        }
 
-       // Fill in any default volume config.
+       // Fill default config.
        volumeConfig := map[string]string{}
-       err = storagePools.VolumeFillDefault(volumeConfig, pool)
+       err = vm.storagePool.FillInstanceConfig(vm, volumeConfig)
        if err != nil {
                return nil, err
        }
 
        // Create a new database entry for the instance's storage volume.
        if vm.IsSnapshot() {
-               _, err = s.Cluster.CreateStorageVolumeSnapshot(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeVM, poolID, volumeConfig, time.Time{})
+               _, err = s.Cluster.CreateStorageVolumeSnapshot(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeVM, vm.storagePool.ID(), volumeConfig, 
time.Time{})
 
        } else {
-               _, err = s.Cluster.CreateStoragePoolVolume(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeVM, poolID, volumeConfig, 
db.StoragePoolVolumeContentTypeBlock)
+               _, err = s.Cluster.CreateStoragePoolVolume(args.Project, 
args.Name, "", db.StoragePoolVolumeTypeVM, vm.storagePool.ID(), volumeConfig, 
db.StoragePoolVolumeContentTypeBlock)
        }
        if err != nil {
                return nil, err
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to