The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6622
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) === - Enforces that "size" volume property can only be updated on custom volume types. - Adds UpdateInstance and UpdateImage functions that can be used to add driver specific update rules. - Removes `dbPool` argument from storage pool `create` function, as same data is available via `b.db`
From 71e5e4424b0cc4d4308408303fff2739653f305c Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 15:35:37 +0000 Subject: [PATCH 01/12] lxd/storage: Removes unnecessary argument in backendLXD.create() Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 4 ++-- lxd/storage/load.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 4d042f7fe5..f419d785ab 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -59,8 +59,8 @@ func (b *lxdBackend) MigrationTypes(contentType drivers.ContentType, refresh boo // create creates the storage pool layout on the storage device. // localOnly is used for clustering where only a single node should do remote storage setup. -func (b *lxdBackend) create(dbPool *api.StoragePoolsPost, localOnly bool, op *operations.Operation) error { - logger := logging.AddContext(b.logger, log.Ctx{"args": dbPool}) +func (b *lxdBackend) create(localOnly bool, op *operations.Operation) error { + logger := logging.AddContext(b.logger, log.Ctx{"config": b.db.Config, "description": b.db.Description, "localOnly": localOnly}) logger.Debug("create started") defer logger.Debug("created finished") diff --git a/lxd/storage/load.go b/lxd/storage/load.go index f89304c649..6a0986c03d 100644 --- a/lxd/storage/load.go +++ b/lxd/storage/load.go @@ -104,7 +104,7 @@ func CreatePool(state *state.State, poolID int64, dbPool *api.StoragePoolsPost, pool.logger = logger // Create the pool itself on the storage device.. - err = pool.create(dbPool, localOnly, op) + err = pool.create(localOnly, op) if err != nil { return nil, err } From 7d6af06d85734d43eaa7376e4ab5b0ca41c28e7d Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:13:35 +0000 Subject: [PATCH 02/12] lxd/storage/backend/lxd: Comment on function description Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 1 + 1 file changed, 1 insertion(+) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index f419d785ab..7f2b5ddbf7 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -120,6 +120,7 @@ func (b *lxdBackend) newVolume(volType drivers.VolumeType, contentType drivers.C return drivers.NewVolume(b.driver, b.name, volType, contentType, volName, volConfig) } +// GetResources returns utilisation information about the pool. func (b *lxdBackend) GetResources() (*api.ResourcesStoragePool, error) { logger := logging.AddContext(b.logger, nil) logger.Debug("GetResources started") From 86ffcb4ff63a83737bf6f14f08e5a1414f709a0b Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:13:54 +0000 Subject: [PATCH 03/12] lxd/storage/backend/lxd: Implements UpdateInstance Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 64 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 7f2b5ddbf7..535329cc9b 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1147,6 +1147,70 @@ func (b *lxdBackend) DeleteInstance(inst instance.Instance, op *operations.Opera return nil } +// UpdateInstance updates an instance volume's config. +func (b *lxdBackend) UpdateInstance(inst instance.Instance, newDesc string, newConfig map[string]string, op *operations.Operation) error { + logger := logging.AddContext(b.logger, log.Ctx{"project": inst.Project(), "instance": inst.Name(), "newDesc": newDesc, "newConfig": newConfig}) + logger.Debug("UpdateInstance started") + defer logger.Debug("UpdateInstance finished") + + if inst.IsSnapshot() { + return fmt.Errorf("Instance cannot be a snapshot") + } + + // Check we can convert the instance to the volume types needed. + volType, err := InstanceTypeToVolumeType(inst.Type()) + if err != nil { + return err + } + + volDBType, err := VolumeTypeToDBType(volType) + if err != nil { + return err + } + + volStorageName := project.Prefix(inst.Project(), inst.Name()) + contentType := InstanceContentType(inst) + + // Validate config. + newVol := b.newVolume(volType, contentType, volStorageName, newConfig) + err = b.driver.ValidateVolume(newVol, false) + if err != nil { + return err + } + + // Get current config to compare what has changed. + _, curVol, err := b.state.Cluster.StoragePoolNodeVolumeGetTypeByProject(inst.Project(), volStorageName, volDBType, b.ID()) + if err != nil { + if err == db.ErrNoSuchObject { + return fmt.Errorf("Volume doesn't exist") + } + + return err + } + + // Apply config changes if there are any. + changedConfig, userOnly := b.detectChangedConfig(curVol.Config, newConfig) + if len(changedConfig) != 0 { + curVol := b.newVolume(volType, contentType, volStorageName, curVol.Config) + if !userOnly { + err = b.driver.UpdateVolume(curVol, changedConfig) + if err != nil { + return err + } + } + } + + // Update the database if something changed. + if len(changedConfig) != 0 || newDesc != curVol.Description { + err = b.state.Cluster.StoragePoolVolumeUpdateByProject(inst.Project(), volStorageName, volDBType, b.ID(), newDesc, newConfig) + if err != nil { + return err + } + } + + return nil +} + // MigrateInstance sends an instance volume for migration. // The args.Name field is ignored and the name of the instance is used instead. func (b *lxdBackend) MigrateInstance(inst instance.Instance, conn io.ReadWriteCloser, args migration.VolumeSourceArgs, op *operations.Operation) error { From e96db0a7f9643e4a7ae5a506e3bb18a56b53920e Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:14:09 +0000 Subject: [PATCH 04/12] lxd/storage/backend/lxd: Implements UpdateImage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 535329cc9b..76a123bc60 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -1798,6 +1798,15 @@ func (b *lxdBackend) DeleteImage(fingerprint string, op *operations.Operation) e return nil } +// UpdateImage updates image config. +func (b *lxdBackend) UpdateImage(fingerprint, newDesc string, newConfig map[string]string, op *operations.Operation) error { + logger := logging.AddContext(b.logger, log.Ctx{"fingerprint": fingerprint, "newDesc": newDesc, "newConfig": newConfig}) + logger.Debug("UpdateImage started") + defer logger.Debug("UpdateImage finished") + + return ErrNotImplemented +} + // CreateCustomVolume creates an empty custom volume. func (b *lxdBackend) CreateCustomVolume(volName, desc string, config map[string]string, op *operations.Operation) error { logger := logging.AddContext(b.logger, log.Ctx{"volName": volName, "desc": desc, "config": config}) From 6c8666c023b09ecfbf1d268d2a278f5af479e854 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:14:40 +0000 Subject: [PATCH 05/12] lxd/storage/backend/lxd: Adds detectChangedConfig and updates usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 54 ++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 76a123bc60..4f6a5d62b2 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -2161,6 +2161,36 @@ func (b *lxdBackend) RenameCustomVolume(volName string, newVolName string, op *o return nil } +// detectChangedConfig returns the config that has changed between current and new config maps. +// Also returns a boolean indicating whether all of the changed keys start with "user.". +// Deleted keys will be returned as having an empty string value. +func (b *lxdBackend) detectChangedConfig(curConfig, newConfig map[string]string) (map[string]string, bool) { + // Diff the configurations. + changedConfig := make(map[string]string) + userOnly := true + for key := range curConfig { + if curConfig[key] != newConfig[key] { + if !strings.HasPrefix(key, "user.") { + userOnly = false + } + + changedConfig[key] = newConfig[key] // Will be empty string on deleted keys. + } + } + + for key := range newConfig { + if curConfig[key] != newConfig[key] { + if !strings.HasPrefix(key, "user.") { + userOnly = false + } + + changedConfig[key] = newConfig[key] + } + } + + return changedConfig, userOnly +} + // UpdateCustomVolume applies the supplied config to the custom volume. func (b *lxdBackend) UpdateCustomVolume(volName, newDesc string, newConfig map[string]string, op *operations.Operation) error { logger := logging.AddContext(b.logger, log.Ctx{"volName": volName, "newDesc": newDesc, "newConfig": newConfig}) @@ -2188,30 +2218,8 @@ func (b *lxdBackend) UpdateCustomVolume(volName, newDesc string, newConfig map[s return err } - // Diff the configurations. - changedConfig := make(map[string]string) - userOnly := true - for key := range curVol.Config { - if curVol.Config[key] != newConfig[key] { - if !strings.HasPrefix(key, "user.") { - userOnly = false - } - - changedConfig[key] = newConfig[key] // Will be empty string on deleted keys. - } - } - - for key := range newConfig { - if curVol.Config[key] != newConfig[key] { - if !strings.HasPrefix(key, "user.") { - userOnly = false - } - - changedConfig[key] = newConfig[key] - } - } - // Apply config changes if there are any. + changedConfig, userOnly := b.detectChangedConfig(curVol.Config, newConfig) if len(changedConfig) != 0 { curVol := b.newVolume(drivers.VolumeTypeCustom, drivers.ContentTypeFS, volName, curVol.Config) if !userOnly { From b4371e775ebacdeafb780f35698d4f0b7c6764ad Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:15:02 +0000 Subject: [PATCH 06/12] lxd/storage/backend/lxd: Switches to StoragePoolVolumeUpdateByProject Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_lxd.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 4f6a5d62b2..68468540fe 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -2255,7 +2255,7 @@ func (b *lxdBackend) UpdateCustomVolume(volName, newDesc string, newConfig map[s // Update the database if something changed. if len(changedConfig) != 0 || newDesc != curVol.Description { - err = b.state.Cluster.StoragePoolVolumeUpdate(volName, db.StoragePoolVolumeTypeCustom, b.ID(), newDesc, newConfig) + err = b.state.Cluster.StoragePoolVolumeUpdateByProject("default", volName, db.StoragePoolVolumeTypeCustom, b.ID(), newDesc, newConfig) if err != nil { return err } From 2dc42e5b6d1db86d1a0dc6a9d552dca34662511f Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:15:29 +0000 Subject: [PATCH 07/12] lxd/db/storage/pools: Replaces StoragePoolVolumeUpdate with StoragePoolVolumeUpdateByProject Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/db/storage_pools.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lxd/db/storage_pools.go b/lxd/db/storage_pools.go index 02279a36a7..84d44d5075 100644 --- a/lxd/db/storage_pools.go +++ b/lxd/db/storage_pools.go @@ -871,16 +871,15 @@ func (c *Cluster) StoragePoolNodeVolumeGetTypeByProject(project, volumeName stri return c.StoragePoolVolumeGetType(project, volumeName, volumeType, poolID, c.nodeID) } -// StoragePoolVolumeUpdate updates the storage volume attached to a given storage -// pool. -func (c *Cluster) StoragePoolVolumeUpdate(volumeName string, volumeType int, poolID int64, volumeDescription string, volumeConfig map[string]string) error { - volumeID, _, err := c.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID) +// StoragePoolVolumeUpdateByProject updates the storage volume attached to a given storage pool. +func (c *Cluster) StoragePoolVolumeUpdateByProject(project, volumeName string, volumeType int, poolID int64, volumeDescription string, volumeConfig map[string]string) error { + volumeID, _, err := c.StoragePoolNodeVolumeGetTypeByProject(project, volumeName, volumeType, poolID) if err != nil { return err } err = c.Transaction(func(tx *ClusterTx) error { - err = storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, "default", volumeName, volumeType, poolID, func(volumeID int64) error { + err = storagePoolVolumeReplicateIfCeph(tx.tx, volumeID, project, volumeName, volumeType, poolID, func(volumeID int64) error { err = StorageVolumeConfigClear(tx.tx, volumeID) if err != nil { return err From 81f395ab05a50f9f11e3e12858f60a83c66cb2e9 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:16:59 +0000 Subject: [PATCH 08/12] lxd/storage/volumes: Updates storagePoolVolumeTypePut to be project aware Also handles update requests via the new storage layer. Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage_volumes.go | 48 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index ef17b367d9..340f91fcc1 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -12,6 +12,7 @@ import ( "github.com/gorilla/mux" "github.com/gorilla/websocket" "github.com/lxc/lxd/lxd/db" + "github.com/lxc/lxd/lxd/instance" "github.com/lxc/lxd/lxd/operations" "github.com/lxc/lxd/lxd/response" "github.com/lxc/lxd/lxd/state" @@ -908,6 +909,8 @@ func storagePoolVolumeTypeImageGet(d *Daemon, r *http.Request) response.Response // This function does allow limited functionality for non-custom volume types, specifically you // can modify the volume's description only. func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string) response.Response { + project := projectParam(r) + // Get the name of the storage volume. volumeName, err := storageGetVolumeNameFromURL(r) if err != nil { @@ -945,7 +948,7 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string) } // Get the existing storage volume. - _, vol, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID) + _, vol, err := d.cluster.StoragePoolNodeVolumeGetTypeByProject(project, volumeName, volumeType, poolID) if err != nil { return response.SmartError(err) } @@ -981,31 +984,44 @@ func storagePoolVolumeTypePut(d *Daemon, r *http.Request, volumeTypeName string) } } - // Handle update requests. + // Handle custom volume update requests. err = pool.UpdateCustomVolume(vol.Name, req.Description, req.Config, nil) if err != nil { return response.SmartError(err) } - } else { - // You are only allowed to modify the description for non-custom volumes. - // This is a special case because the rootfs devices do not provide a way - // to update a non-custom volume's description. - if len(req.Config) > 0 { - return response.BadRequest(fmt.Errorf("Only description can be modified for volume type %s", volumeTypeName)) + } else if volumeType == db.StoragePoolVolumeTypeContainer || volumeType == db.StoragePoolVolumeTypeVM { + inst, err := instance.LoadByProjectAndName(d.State(), project, vol.Name) + if err != nil { + return response.NotFound(err) } // There is a bug in the lxc client (lxc/storage_volume.go#L829-L865) which - // means that modifying a snapshot's description gets routed here rather - // than the dedicated snapshot editing route. So need to handle snapshot - // volumes here too. - - // Update the database if description changed. - if req.Description != vol.Description { - err = d.cluster.StoragePoolVolumeUpdate(vol.Name, volumeType, poolID, req.Description, vol.Config) + // means that modifying an instance snapshot's description gets routed here + // rather than the dedicated snapshot editing route. So need to handle + // snapshot volumes here too. + if inst.IsSnapshot() { + // Update the database if description changed. Use current config. + if req.Description != vol.Description { + err = d.cluster.StoragePoolVolumeUpdateByProject(inst.Project(), inst.Name(), volumeType, poolID, req.Description, vol.Config) + if err != nil { + response.SmartError(err) + } + } + } else { + // Handle instance volume update requests. + err = pool.UpdateInstance(inst, req.Description, req.Config, nil) if err != nil { - response.SmartError(err) + return response.SmartError(err) } } + } else if volumeType == db.StoragePoolVolumeTypeImage { + // Handle image update requests. + err = pool.UpdateImage(vol.Name, req.Description, req.Config, nil) + if err != nil { + return response.SmartError(err) + } + } else { + return response.SmartError(fmt.Errorf("Invalid volume type")) } } else { From 64aec93e582c1a1f6c4ec6a8802cdbc02e38c0c5 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:17:40 +0000 Subject: [PATCH 09/12] lxd/storage/pool/interface: Adds Update functions for Instances and Images Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/pool_interface.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lxd/storage/pool_interface.go b/lxd/storage/pool_interface.go index 279d0db79e..274c613a20 100644 --- a/lxd/storage/pool_interface.go +++ b/lxd/storage/pool_interface.go @@ -33,6 +33,7 @@ type Pool interface { CreateInstanceFromMigration(inst instance.Instance, conn io.ReadWriteCloser, args migration.VolumeTargetArgs, op *operations.Operation) error RenameInstance(inst instance.Instance, newName string, op *operations.Operation) error DeleteInstance(inst instance.Instance, op *operations.Operation) error + UpdateInstance(inst instance.Instance, newDesc string, newConfig map[string]string, op *operations.Operation) error MigrateInstance(inst instance.Instance, conn io.ReadWriteCloser, args migration.VolumeSourceArgs, op *operations.Operation) error RefreshInstance(inst instance.Instance, src instance.Instance, srcSnapshots []instance.Instance, op *operations.Operation) error @@ -56,6 +57,7 @@ type Pool interface { // Images. EnsureImage(fingerprint string, op *operations.Operation) error DeleteImage(fingerprint string, op *operations.Operation) error + UpdateImage(fingerprint, newDesc string, newConfig map[string]string, op *operations.Operation) error // Custom volumes. CreateCustomVolume(volName, desc string, config map[string]string, op *operations.Operation) error From c17566424710d79a0271570bb7301dcc044d6449 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:18:09 +0000 Subject: [PATCH 10/12] lxd/storage/drivers/driver/common: Only allow size property on custom volumes 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 a0cfb0173d..1b022472d2 100644 --- a/lxd/storage/drivers/driver_common.go +++ b/lxd/storage/drivers/driver_common.go @@ -76,6 +76,11 @@ func (d *common) validateVolume(vol Volume, driverRules map[string]func(value st } } + // If volume type is not custom, don't allow "size" property. + if vol.volType != VolumeTypeCustom && vol.config["size"] != "" { + return fmt.Errorf("Volume 'size' property is only valid for custom volume types") + } + return nil } From 3954904039b6ad6d70e8cf42709ff6a84cc58a2e Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:19:13 +0000 Subject: [PATCH 11/12] lxd/storage/backend/mock: Adds Update functions for Instances and Images Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/storage/backend_mock.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lxd/storage/backend_mock.go b/lxd/storage/backend_mock.go index 9cc026d611..62200e870f 100644 --- a/lxd/storage/backend_mock.go +++ b/lxd/storage/backend_mock.go @@ -88,6 +88,10 @@ func (b *mockBackend) DeleteInstance(inst instance.Instance, op *operations.Oper return nil } +func (b *mockBackend) UpdateInstance(inst instance.Instance, newDesc string, newConfig map[string]string, op *operations.Operation) error { + return nil +} + func (b *mockBackend) MigrateInstance(inst instance.Instance, conn io.ReadWriteCloser, args migration.VolumeSourceArgs, op *operations.Operation) error { return nil } @@ -152,6 +156,10 @@ func (b *mockBackend) DeleteImage(fingerprint string, op *operations.Operation) return nil } +func (b *mockBackend) UpdateImage(fingerprint, newDesc string, newConfig map[string]string, op *operations.Operation) error { + return nil +} + func (b *mockBackend) CreateCustomVolume(volName, desc string, config map[string]string, op *operations.Operation) error { return nil } From 02072ba07252251671c7d549b77df0cbabbf0312 Mon Sep 17 00:00:00 2001 From: Thomas Parrott <thomas.parr...@canonical.com> Date: Fri, 13 Dec 2019 17:19:38 +0000 Subject: [PATCH 12/12] lxd: Updates StoragePoolVolumeUpdateByProject usage Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com> --- lxd/db/storage_pools_test.go | 2 +- lxd/patches.go | 30 +++++++++++++++--------------- lxd/storage.go | 2 +- lxd/storage_ceph.go | 3 ++- lxd/storage_lvm.go | 3 ++- lxd/storage_volumes.go | 2 +- lxd/storage_volumes_snapshot.go | 2 +- lxd/storage_volumes_utils.go | 2 +- 8 files changed, 24 insertions(+), 22 deletions(-) diff --git a/lxd/db/storage_pools_test.go b/lxd/db/storage_pools_test.go index 5b78255ad9..7871cfa8be 100644 --- a/lxd/db/storage_pools_test.go +++ b/lxd/db/storage_pools_test.go @@ -184,7 +184,7 @@ func TestStoragePoolVolume_Ceph(t *testing.T) { // Update the volume config["k"] = "v2" - err = cluster.StoragePoolVolumeUpdate("v1", 1, poolID, "volume 1", config) + err = cluster.StoragePoolVolumeUpdateByProject("default", "v1", 1, poolID, "volume 1", config) require.NoError(t, err) for _, nodeID := range []int64{1, 2} { _, volume, err := cluster.StoragePoolVolumeGetType("default", "v1", 1, poolID, nodeID) diff --git a/lxd/patches.go b/lxd/patches.go index 99923e43cf..3049b08896 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -480,7 +480,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the container") - err := d.cluster.StoragePoolVolumeUpdate(ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) if err != nil { return err } @@ -568,7 +568,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the snapshot") - err := d.cluster.StoragePoolVolumeUpdate(cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) if err != nil { return err } @@ -649,7 +649,7 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string, _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the image") - err := d.cluster.StoragePoolVolumeUpdate(img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) if err != nil { return err } @@ -767,7 +767,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the container") - err := d.cluster.StoragePoolVolumeUpdate(ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) if err != nil { return err } @@ -884,7 +884,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the snapshot") - err := d.cluster.StoragePoolVolumeUpdate(cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) if err != nil { return err } @@ -914,7 +914,7 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the image") - err := d.cluster.StoragePoolVolumeUpdate(img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) if err != nil { return err } @@ -1076,7 +1076,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the container") - err := d.cluster.StoragePoolVolumeUpdate(ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) if err != nil { return err } @@ -1231,7 +1231,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the snapshot") - err := d.cluster.StoragePoolVolumeUpdate(cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) if err != nil { return err } @@ -1402,7 +1402,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the image") - err := d.cluster.StoragePoolVolumeUpdate(img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) if err != nil { return err } @@ -1594,7 +1594,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the container") - err := d.cluster.StoragePoolVolumeUpdate(ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig) if err != nil { return err } @@ -1680,7 +1680,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the snapshot") - err := d.cluster.StoragePoolVolumeUpdate(cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig) if err != nil { return err } @@ -1736,7 +1736,7 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID) if err == nil { logger.Warnf("Storage volumes database already contains an entry for the image") - err := d.cluster.StoragePoolVolumeUpdate(img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) + err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig) if err != nil { return err } @@ -2290,7 +2290,7 @@ func patchStorageApiUpdateStorageConfigs(name string, d *Daemon) error { // exist in the db, so it's safe to ignore the error. volumeType, _ := driver.VolumeTypeNameToType(volume.Type) // Update the volume config. - err = d.cluster.StoragePoolVolumeUpdate(volume.Name, volumeType, poolID, volume.Description, volume.Config) + err = d.cluster.StoragePoolVolumeUpdateByProject("default", volume.Name, volumeType, poolID, volume.Description, volume.Config) if err != nil { return err } @@ -2438,7 +2438,7 @@ func patchStorageApiDetectLVSize(name string, d *Daemon) error { // exist in the db, so it's safe to ignore the error. volumeType, _ := driver.VolumeTypeNameToType(volume.Type) // Update the volume config. - err = d.cluster.StoragePoolVolumeUpdate(volume.Name, volumeType, poolID, volume.Description, volume.Config) + err = d.cluster.StoragePoolVolumeUpdateByProject("default", volume.Name, volumeType, poolID, volume.Description, volume.Config) if err != nil { return err } @@ -2568,7 +2568,7 @@ func patchStorageZFSVolumeSize(name string, d *Daemon) error { // exist in the db, so it's safe to ignore the error. volumeType, _ := driver.VolumeTypeNameToType(volume.Type) // Update the volume config. - err = d.cluster.StoragePoolVolumeUpdate(volume.Name, + err = d.cluster.StoragePoolVolumeUpdateByProject("default", volume.Name, volumeType, poolID, volume.Description, volume.Config) if err != nil { diff --git a/lxd/storage.go b/lxd/storage.go index ff3f67ca55..af02e505c5 100644 --- a/lxd/storage.go +++ b/lxd/storage.go @@ -566,7 +566,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName // Update last idmap poolVolumePut.Config["volatile.idmap.last"] = jsonIdmap - err = s.Cluster.StoragePoolVolumeUpdate(volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config) + err = s.Cluster.StoragePoolVolumeUpdateByProject("default", volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config) if err != nil { return err } diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go index 750112b03c..1b5729e8e7 100644 --- a/lxd/storage_ceph.go +++ b/lxd/storage_ceph.go @@ -2443,7 +2443,8 @@ func (s *storageCeph) StorageEntitySetQuota(volumeType int, size int64, data int // Update the database s.volume.Config["size"] = units.GetByteSizeString(size, 0) - err = s.s.Cluster.StoragePoolVolumeUpdate( + err = s.s.Cluster.StoragePoolVolumeUpdateByProject( + "default", s.volume.Name, volumeType, s.poolID, diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go index 2a8d924972..e4cab25c5e 100644 --- a/lxd/storage_lvm.go +++ b/lxd/storage_lvm.go @@ -2122,7 +2122,8 @@ func (s *storageLvm) StorageEntitySetQuota(volumeType int, size int64, data inte // Update the database s.volume.Config["size"] = units.GetByteSizeString(size, 0) - err = s.s.Cluster.StoragePoolVolumeUpdate( + err = s.s.Cluster.StoragePoolVolumeUpdateByProject( + "default", s.volume.Name, volumeType, s.poolID, diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index 340f91fcc1..0efd6460d3 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -873,7 +873,7 @@ func storagePoolVolumeTypeGet(d *Daemon, r *http.Request, volumeTypeName string) } // Get the storage volume. - _, volume, err := d.cluster.StoragePoolNodeVolumeGetType(volumeName, volumeType, poolID) + _, volume, err := d.cluster.StoragePoolNodeVolumeGetTypeByProject(project, volumeName, volumeType, poolID) if err != nil { return response.SmartError(err) } diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go index d81698513e..cb939f6527 100644 --- a/lxd/storage_volumes_snapshot.go +++ b/lxd/storage_volumes_snapshot.go @@ -461,7 +461,7 @@ func storagePoolVolumeSnapshotTypePut(d *Daemon, r *http.Request) response.Respo do := func(op *operations.Operation) error { // Update the database if description changed. if req.Description != vol.Description { - err = d.cluster.StoragePoolVolumeUpdate(vol.Name, volumeType, poolID, req.Description, vol.Config) + err = d.cluster.StoragePoolVolumeUpdateByProject("default", vol.Name, volumeType, poolID, req.Description, vol.Config) if err != nil { return err } diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go index 40d8ca789a..51fa6ef38e 100644 --- a/lxd/storage_volumes_utils.go +++ b/lxd/storage_volumes_utils.go @@ -202,7 +202,7 @@ func storagePoolVolumeUpdate(state *state.State, poolName string, volumeName str // Update the database if something changed if len(changedConfig) != 0 || newDescription != oldDescription { - err = state.Cluster.StoragePoolVolumeUpdate(volumeName, volumeType, poolID, newDescription, newConfig) + err = state.Cluster.StoragePoolVolumeUpdateByProject("default", volumeName, volumeType, poolID, newDescription, newConfig) if err != nil { return err }
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel