[lxc-devel] [lxd/master] Implement storage patch mechanism
stgraber on Github
lxc-bot at linuxcontainers.org
Wed Jan 15 05:52:34 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200114/c9110de1/attachment-0001.bin>
-------------- next part --------------
From 424caa0553e474ee48ca23b465a93686bd660611 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 15 Jan 2020 00:42:06 -0500
Subject: [PATCH 1/4] lxd/storage/drivers: Rename drivers_ to driver_
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/storage/drivers/{drivers_lvm.go => driver_lvm.go} | 0
lxd/storage/drivers/{drivers_lvm_utils.go => driver_lvm_utils.go} | 0
.../drivers/{drivers_lvm_volumes.go => driver_lvm_volumes.go} | 0
3 files changed, 0 insertions(+), 0 deletions(-)
rename lxd/storage/drivers/{drivers_lvm.go => driver_lvm.go} (100%)
rename lxd/storage/drivers/{drivers_lvm_utils.go => driver_lvm_utils.go} (100%)
rename lxd/storage/drivers/{drivers_lvm_volumes.go => driver_lvm_volumes.go} (100%)
diff --git a/lxd/storage/drivers/drivers_lvm.go b/lxd/storage/drivers/driver_lvm.go
similarity index 100%
rename from lxd/storage/drivers/drivers_lvm.go
rename to lxd/storage/drivers/driver_lvm.go
diff --git a/lxd/storage/drivers/drivers_lvm_utils.go b/lxd/storage/drivers/driver_lvm_utils.go
similarity index 100%
rename from lxd/storage/drivers/drivers_lvm_utils.go
rename to lxd/storage/drivers/driver_lvm_utils.go
diff --git a/lxd/storage/drivers/drivers_lvm_volumes.go b/lxd/storage/drivers/driver_lvm_volumes.go
similarity index 100%
rename from lxd/storage/drivers/drivers_lvm_volumes.go
rename to lxd/storage/drivers/driver_lvm_volumes.go
From dd55ce01c1799c2f01b6c7ecf785c80d1d5ad35d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 15 Jan 2020 00:17:47 -0500
Subject: [PATCH 2/4] lxd/storage/drivers: Implement patch mechanism
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/storage/drivers/driver_common.go | 21 +++++++++++++++++++++
lxd/storage/drivers/interface.go | 1 +
2 files changed, 22 insertions(+)
diff --git a/lxd/storage/drivers/driver_common.go b/lxd/storage/drivers/driver_common.go
index 785ea72f6b..9bac72e386 100644
--- a/lxd/storage/drivers/driver_common.go
+++ b/lxd/storage/drivers/driver_common.go
@@ -27,6 +27,7 @@ type common struct {
getCommonVolumeRules func(vol Volume) map[string]func(string) error
state *state.State
logger logger.Logger
+ patches map[string]func() error
}
func (d *common) init(state *state.State, name string, config map[string]string, logger logger.Logger, volIDFunc func(volType VolumeType, volName string) (int64, error), commonVolRulesFunc func(vol Volume) map[string]func(string) error) {
@@ -124,6 +125,26 @@ func (d *common) Config() map[string]string {
return confCopy
}
+// ApplyPatch looks for a suitable patch and runs it.
+func (d *common) ApplyPatch(name string) error {
+ if d.patches == nil {
+ return fmt.Errorf("The patch mechanism isn't implemented on pool '%s'", d.name)
+ }
+
+ // Locate the patch.
+ patch, ok := d.patches[name]
+ if !ok {
+ return fmt.Errorf("Patch '%s' isn't implemented on pool '%s'", name, d.name)
+ }
+
+ // Handle cases where a patch isn't needed.
+ if patch == nil {
+ return nil
+ }
+
+ return patch()
+}
+
// vfsGetResources is a generic GetResources implementation for VFS-only drivers.
func (d *common) vfsGetResources() (*api.ResourcesStoragePool, error) {
// Get the VFS information
diff --git a/lxd/storage/drivers/interface.go b/lxd/storage/drivers/interface.go
index 092c97a5dd..0e4a58a558 100644
--- a/lxd/storage/drivers/interface.go
+++ b/lxd/storage/drivers/interface.go
@@ -40,6 +40,7 @@ type Driver interface {
GetResources() (*api.ResourcesStoragePool, error)
Validate(config map[string]string) error
Update(changedConfig map[string]string) error
+ ApplyPatch(name string) error
// Volumes.
ValidateVolume(vol Volume, removeUnknownKeys bool) error
From 8e2bf1015770519f4f43eb39b87f76e7b3e4857b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 15 Jan 2020 00:26:13 -0500
Subject: [PATCH 3/4] lxd/storage: Add patch mechanism to backend
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/storage/backend_lxd.go | 29 +++++++++++++++++++++++++++++
lxd/storage/backend_lxd_patches.go | 5 +++++
lxd/storage/backend_mock.go | 4 ++++
lxd/storage/pool_interface.go | 2 ++
4 files changed, 40 insertions(+)
create mode 100644 lxd/storage/backend_lxd_patches.go
diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index 582e225005..0f89357600 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -233,6 +233,35 @@ func (b *lxdBackend) Unmount() (bool, error) {
return b.driver.Unmount()
}
+// ApplyPatch runs the requested patch at both backend and driver level.
+func (b *lxdBackend) ApplyPatch(name string) error {
+ // Run early backend patches.
+ patch, ok := lxdEarlyPatches[name]
+ if ok {
+ err := patch(b)
+ if err != nil {
+ return err
+ }
+ }
+
+ // Run the driver patch itself.
+ err := b.driver.ApplyPatch(name)
+ if err != nil {
+ return err
+ }
+
+ // Run late backend patches.
+ patch, ok = lxdLatePatches[name]
+ if ok {
+ err := patch(b)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
// ensureInstanceSymlink creates a symlink in the instance directory to the instance's mount path
// if doesn't exist already.
func (b *lxdBackend) ensureInstanceSymlink(instanceType instancetype.Type, projectName, instanceName, mountPath string) error {
diff --git a/lxd/storage/backend_lxd_patches.go b/lxd/storage/backend_lxd_patches.go
new file mode 100644
index 0000000000..4fb9cf302e
--- /dev/null
+++ b/lxd/storage/backend_lxd_patches.go
@@ -0,0 +1,5 @@
+package storage
+
+var lxdEarlyPatches = map[string]func(b *lxdBackend) error{}
+
+var lxdLatePatches = map[string]func(b *lxdBackend) error{}
diff --git a/lxd/storage/backend_mock.go b/lxd/storage/backend_mock.go
index c2eef25bb8..90f15951ff 100644
--- a/lxd/storage/backend_mock.go
+++ b/lxd/storage/backend_mock.go
@@ -60,6 +60,10 @@ func (b *mockBackend) Unmount() (bool, error) {
return true, nil
}
+func (b *mockBackend) ApplyPatch(name string) error {
+ return nil
+}
+
func (b *mockBackend) CreateInstance(inst instance.Instance, op *operations.Operation) error {
return nil
}
diff --git a/lxd/storage/pool_interface.go b/lxd/storage/pool_interface.go
index 2e1e139ecd..40a995ed2b 100644
--- a/lxd/storage/pool_interface.go
+++ b/lxd/storage/pool_interface.go
@@ -25,6 +25,8 @@ type Pool interface {
Mount() (bool, error)
Unmount() (bool, error)
+ ApplyPatch(name string) error
+
// Instances.
CreateInstance(inst instance.Instance, op *operations.Operation) error
CreateInstanceFromBackup(srcBackup backup.Info, srcData io.ReadSeeker, op *operations.Operation) (func(instance.Instance) error, func(), error)
From ae3bc4fce8ddc5f5ee1b9faffeec76bfc73b3d02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 15 Jan 2020 00:40:46 -0500
Subject: [PATCH 4/4] lxd/patches: Add storage_create_vm
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/patches.go | 23 +++++++++++++++++++++++
lxd/storage/backend_lxd_patches.go | 13 ++++++++++++-
lxd/storage/drivers/driver_btrfs.go | 6 ++++++
lxd/storage/drivers/driver_cephfs.go | 6 ++++++
lxd/storage/drivers/driver_dir.go | 10 ++++++++++
lxd/storage/drivers/driver_lvm.go | 6 ++++++
lxd/storage/drivers/driver_zfs.go | 6 ++++++
lxd/storage/drivers/driver_zfs_patches.go | 21 +++++++++++++++++++++
8 files changed, 90 insertions(+), 1 deletion(-)
create mode 100644 lxd/storage/drivers/driver_zfs_patches.go
diff --git a/lxd/patches.go b/lxd/patches.go
index c5f7a1b5e7..5be31ce745 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -20,6 +20,7 @@ import (
"github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/rsync"
driver "github.com/lxc/lxd/lxd/storage"
+ storagePools "github.com/lxc/lxd/lxd/storage"
storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
"github.com/lxc/lxd/shared"
log "github.com/lxc/lxd/shared/log15"
@@ -77,6 +78,7 @@ var patches = []patch{
{name: "storage_api_rename_container_snapshots_dir_again_again", run: patchStorageApiRenameContainerSnapshotsDir},
{name: "clustering_add_roles", run: patchClusteringAddRoles},
{name: "clustering_add_roles_again", run: patchClusteringAddRoles},
+ {name: "storage_create_vm", run: patchStorageCreateVM},
}
type patch struct {
@@ -130,6 +132,27 @@ func patchesApplyAll(d *Daemon) error {
}
// Patches begin here
+func patchStorageCreateVM(name string, d *Daemon) error {
+ // Load all the pools.
+ pools, _ := d.cluster.StoragePools()
+
+ for _, poolName := range pools {
+ pool, err := storagePools.GetPoolByName(d.State(), poolName)
+ if err != storageDrivers.ErrUnknownDriver {
+ if err != nil {
+ return err
+ }
+
+ err = pool.ApplyPatch("storage_create_vm")
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
func patchRenameCustomVolumeLVs(name string, d *Daemon) error {
// Ignore the error since it will also fail if there are no pools.
pools, _ := d.cluster.StoragePools()
diff --git a/lxd/storage/backend_lxd_patches.go b/lxd/storage/backend_lxd_patches.go
index 4fb9cf302e..4fca84102a 100644
--- a/lxd/storage/backend_lxd_patches.go
+++ b/lxd/storage/backend_lxd_patches.go
@@ -1,5 +1,16 @@
package storage
+import (
+ "github.com/lxc/lxd/lxd/storage/drivers"
+)
+
var lxdEarlyPatches = map[string]func(b *lxdBackend) error{}
-var lxdLatePatches = map[string]func(b *lxdBackend) error{}
+var lxdLatePatches = map[string]func(b *lxdBackend) error{
+ "storage_create_vm": lxdPatchStorageCreateVM,
+}
+
+// Patches start here.
+func lxdPatchStorageCreateVM(b *lxdBackend) error {
+ return b.createStorageStructure(drivers.GetPoolMountPath(b.name))
+}
diff --git a/lxd/storage/drivers/driver_btrfs.go b/lxd/storage/drivers/driver_btrfs.go
index f45ffe75b2..d508709fc8 100644
--- a/lxd/storage/drivers/driver_btrfs.go
+++ b/lxd/storage/drivers/driver_btrfs.go
@@ -27,6 +27,12 @@ type btrfs struct {
// load is used to run one-time action per-driver rather than per-pool.
func (d *btrfs) load() error {
+ // Register the patches.
+ d.patches = map[string]func() error{
+ "storage_create_vm": nil,
+ }
+
+ // Done if previously loaded.
if btrfsLoaded {
return nil
}
diff --git a/lxd/storage/drivers/driver_cephfs.go b/lxd/storage/drivers/driver_cephfs.go
index bbeacc4478..53fafa9530 100644
--- a/lxd/storage/drivers/driver_cephfs.go
+++ b/lxd/storage/drivers/driver_cephfs.go
@@ -25,6 +25,12 @@ type cephfs struct {
// load is used to run one-time action per-driver rather than per-pool.
func (d *cephfs) load() error {
+ // Register the patches.
+ d.patches = map[string]func() error{
+ "storage_create_vm": nil,
+ }
+
+ // Done if previously loaded.
if cephfsLoaded {
return nil
}
diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index 3e0d6f56a1..27707a379d 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -16,6 +16,16 @@ type dir struct {
common
}
+// load is used to run one-time action per-driver rather than per-pool.
+func (d *dir) load() error {
+ // Register the patches.
+ d.patches = map[string]func() error{
+ "storage_create_vm": nil,
+ }
+
+ return nil
+}
+
// Info returns info about the driver and its environment.
func (d *dir) Info() Info {
return Info{
diff --git a/lxd/storage/drivers/driver_lvm.go b/lxd/storage/drivers/driver_lvm.go
index 1ebf58d703..9eb629d503 100644
--- a/lxd/storage/drivers/driver_lvm.go
+++ b/lxd/storage/drivers/driver_lvm.go
@@ -28,6 +28,12 @@ type lvm struct {
}
func (d *lvm) load() error {
+ // Register the patches.
+ d.patches = map[string]func() error{
+ "storage_create_vm": nil,
+ }
+
+ // Done if previously loaded.
if lvmLoaded {
return nil
}
diff --git a/lxd/storage/drivers/driver_zfs.go b/lxd/storage/drivers/driver_zfs.go
index 72b79253fe..e77df847f8 100644
--- a/lxd/storage/drivers/driver_zfs.go
+++ b/lxd/storage/drivers/driver_zfs.go
@@ -36,6 +36,12 @@ type zfs struct {
// load is used to run one-time action per-driver rather than per-pool.
func (d *zfs) load() error {
+ // Register the patches.
+ d.patches = map[string]func() error{
+ "storage_create_vm": d.patchStorageCreateVM,
+ }
+
+ // Done if previously loaded.
if zfsLoaded {
return nil
}
diff --git a/lxd/storage/drivers/driver_zfs_patches.go b/lxd/storage/drivers/driver_zfs_patches.go
new file mode 100644
index 0000000000..fc6eccd146
--- /dev/null
+++ b/lxd/storage/drivers/driver_zfs_patches.go
@@ -0,0 +1,21 @@
+package drivers
+
+import (
+ "path/filepath"
+)
+
+func (d *zfs) patchStorageCreateVM() error {
+ // Create any missing initial dataset.
+ for _, dataset := range d.initialDatasets() {
+ if d.checkDataset(filepath.Join(d.config["zfs.pool_name"], dataset)) {
+ continue
+ }
+
+ err := d.createDataset(filepath.Join(d.config["zfs.pool_name"], dataset), "mountpoint=none")
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
More information about the lxc-devel
mailing list