From 7c3742d3a68cff108b15360f0917eb7db58899c1 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 16:51:45 -0600 Subject: [PATCH 01/15] lxd/db/cluster: Add StoragePoolVolumeType newtype Signed-off-by: Wesley Hershberger --- lxd/db/cluster/storage_volume_type.go | 57 +++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/lxd/db/cluster/storage_volume_type.go b/lxd/db/cluster/storage_volume_type.go index 566c9f3e55eb..6e5d68ab8a12 100644 --- a/lxd/db/cluster/storage_volume_type.go +++ b/lxd/db/cluster/storage_volume_type.go @@ -1,9 +1,21 @@ package cluster +import ( + "errors" +) + +// StoragePoolVolumeType records a volume's type in the database. +// +// # Type Safety +// Funtions using this type should assume that a StoragePoolVolumeType is always +// a valid value; i.e. that it is type safe. Use the parsing methods below when +// converting to StoragePoolVolumeType. +type StoragePoolVolumeType int + // XXX: this was extracted from lxd/storage_volume_utils.go, we find a way to // factor it independently from both the db and main packages. const ( - StoragePoolVolumeTypeContainer = iota + StoragePoolVolumeTypeContainer StoragePoolVolumeType = iota StoragePoolVolumeTypeImage StoragePoolVolumeTypeCustom StoragePoolVolumeTypeVM @@ -19,12 +31,43 @@ const ( StoragePoolVolumeTypeNameCustom string = "custom" ) -// StoragePoolVolumeTypeNames represents a map of storage volume types and their names. -var StoragePoolVolumeTypeNames = map[int]string{ - StoragePoolVolumeTypeContainer: "container", - StoragePoolVolumeTypeImage: "image", - StoragePoolVolumeTypeCustom: "custom", - StoragePoolVolumeTypeVM: "virtual-machine", +func StoragePoolVolumeTypeFromInt(volType int) (StoragePoolVolumeType, error) { + switch StoragePoolVolumeType(volType) { + case StoragePoolVolumeTypeContainer, StoragePoolVolumeTypeVM, StoragePoolVolumeTypeCustom, StoragePoolVolumeTypeImage: + return StoragePoolVolumeType(volType), nil + default: + return StoragePoolVolumeType(volType), errors.New("Invalid storage volume type") + } +} + +func StoragePoolVolumeTypeFromName(volTypeName string) (StoragePoolVolumeType, error) { + switch volTypeName { + case StoragePoolVolumeTypeNameContainer: + return StoragePoolVolumeTypeContainer, nil + case StoragePoolVolumeTypeNameVM: + return StoragePoolVolumeTypeVM, nil + case StoragePoolVolumeTypeNameImage: + return StoragePoolVolumeTypeImage, nil + case StoragePoolVolumeTypeNameCustom: + return StoragePoolVolumeTypeCustom, nil + } + + return StoragePoolVolumeTypeCustom, errors.New("Invalid storage volume type") +} + +func (t StoragePoolVolumeType) Name() string { + switch t { + case StoragePoolVolumeTypeContainer: + return StoragePoolVolumeTypeNameContainer + case StoragePoolVolumeTypeVM: + return StoragePoolVolumeTypeNameVM + case StoragePoolVolumeTypeImage: + return StoragePoolVolumeTypeNameImage + case StoragePoolVolumeTypeCustom: + return StoragePoolVolumeTypeNameCustom + } + + return StoragePoolVolumeTypeNameCustom } // Content types. From 9e27cfd6a69c81d9e61ebf75b36e7f9592d9b9af Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:06:23 -0600 Subject: [PATCH 02/15] lxd/db/cluster: Add StoragePoolVolumeContentType newtype Signed-off-by: Wesley Hershberger --- lxd/db/cluster/storage_volume_type.go | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lxd/db/cluster/storage_volume_type.go b/lxd/db/cluster/storage_volume_type.go index 6e5d68ab8a12..9bccf733440e 100644 --- a/lxd/db/cluster/storage_volume_type.go +++ b/lxd/db/cluster/storage_volume_type.go @@ -70,9 +70,11 @@ func (t StoragePoolVolumeType) Name() string { return StoragePoolVolumeTypeNameCustom } +type StoragePoolVolumeContentType int + // Content types. const ( - StoragePoolVolumeContentTypeFS = iota + StoragePoolVolumeContentTypeFS StoragePoolVolumeContentType = iota StoragePoolVolumeContentTypeBlock StoragePoolVolumeContentTypeISO ) @@ -83,3 +85,25 @@ const ( StoragePoolVolumeContentTypeNameBlock string = "block" StoragePoolVolumeContentTypeNameISO string = "iso" ) + +func StoragePoolVolumeContentTypeFromInt(contentType int) (StoragePoolVolumeContentType, error) { + switch StoragePoolVolumeContentType(contentType) { + case StoragePoolVolumeContentTypeFS, StoragePoolVolumeContentTypeBlock, StoragePoolVolumeContentTypeISO: + return StoragePoolVolumeContentType(contentType), nil + default: + return StoragePoolVolumeContentType(contentType), errors.New("Invalid storage volume content type ID") + } +} + +func (t StoragePoolVolumeContentType) Name() string { + switch t { + case StoragePoolVolumeContentTypeFS: + return StoragePoolVolumeContentTypeNameFS + case StoragePoolVolumeContentTypeBlock: + return StoragePoolVolumeContentTypeNameBlock + case StoragePoolVolumeContentTypeISO: + return StoragePoolVolumeContentTypeNameISO + } + + return StoragePoolVolumeContentTypeNameFS +} From 0bced8d6b3a9d422dba6f6faaa17347d9bc35f54 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:01:18 -0600 Subject: [PATCH 03/15] lxd/db: Validate newtypes from DB Enforce the type safety invariants for pool volume/content types as the values are queried from the DB so that downstream code can assume that their values are valid. Signed-off-by: Wesley Hershberger --- lxd/db/storage_volume_snapshots.go | 10 ++++- lxd/db/storage_volumes.go | 63 +++++++++++------------------- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/lxd/db/storage_volume_snapshots.go b/lxd/db/storage_volume_snapshots.go index 39e573ebe530..e67c3b6bc5c9 100644 --- a/lxd/db/storage_volume_snapshots.go +++ b/lxd/db/storage_volume_snapshots.go @@ -92,6 +92,7 @@ func (c *ClusterTx) UpdateStorageVolumeSnapshot(ctx context.Context, projectName // GetStorageVolumeSnapshotWithID returns the volume snapshot with the given ID. func (c *ClusterTx) GetStorageVolumeSnapshotWithID(ctx context.Context, snapshotID int) (StorageVolumeArgs, error) { args := StorageVolumeArgs{} + rawVolumeType := int(-1) q := ` SELECT volumes.id, @@ -106,7 +107,7 @@ JOIN storage_pools ON storage_pools.id=volumes.storage_pool_id WHERE volumes.id=? ` arg1 := []any{snapshotID} - outfmt := []any{&args.ID, &args.Name, &args.CreationDate, &args.PoolName, &args.Type, &args.ProjectName} + outfmt := []any{&args.ID, &args.Name, &args.CreationDate, &args.PoolName, &rawVolumeType, &args.ProjectName} err := dbQueryRowScan(ctx, c, q, arg1, outfmt) if err != nil { @@ -121,7 +122,12 @@ WHERE volumes.id=? return args, fmt.Errorf("Volume is not a snapshot") } - args.TypeName = cluster.StoragePoolVolumeTypeNames[args.Type] + args.Type, err = cluster.StoragePoolVolumeTypeFromInt(rawVolumeType) + if err != nil { + return StorageVolumeArgs{}, err + } + + args.TypeName = args.Type.Name() return args, nil } diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index 6d977ccc21aa..8183dd58fc97 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -74,6 +74,7 @@ WHERE storage_volumes.type = ? // GetStoragePoolVolumeWithID returns the volume with the given ID. func (c *ClusterTx) GetStoragePoolVolumeWithID(ctx context.Context, volumeID int) (StorageVolumeArgs, error) { var response StorageVolumeArgs + var rawVolumeType = int(-1) stmt := ` SELECT @@ -92,7 +93,7 @@ LEFT JOIN nodes ON nodes.id = storage_volumes.node_id WHERE storage_volumes.id = ? ` - err := c.tx.QueryRowContext(ctx, stmt, volumeID).Scan(&response.ID, &response.Name, &response.Description, &response.CreationDate, &response.Type, &response.NodeID, &response.PoolName, &response.ProjectName) + err := c.tx.QueryRowContext(ctx, stmt, volumeID).Scan(&response.ID, &response.Name, &response.Description, &response.CreationDate, &rawVolumeType, &response.NodeID, &response.PoolName, &response.ProjectName) if err != nil { if err == sql.ErrNoRows { return StorageVolumeArgs{}, api.StatusErrorf(http.StatusNotFound, "Storage pool volume not found") @@ -106,7 +107,12 @@ WHERE storage_volumes.id = ? return StorageVolumeArgs{}, err } - response.TypeName = cluster.StoragePoolVolumeTypeNames[response.Type] + response.Type, err = cluster.StoragePoolVolumeTypeFromInt(rawVolumeType) + if err != nil { + return StorageVolumeArgs{}, err + } + + response.TypeName = response.Type.Name() return response, nil } @@ -214,25 +220,28 @@ func (c *ClusterTx) GetStorageVolumes(ctx context.Context, memberSpecific bool, var volumes []*StorageVolume err = query.Scan(ctx, c.Tx(), q.String(), func(scan func(dest ...any) error) error { - var volumeType = int(-1) - var contentType = int(-1) + var rawVolumeType = int(-1) + var rawContentType = int(-1) var vol StorageVolume - err := scan(&vol.Project, &vol.ID, &vol.Name, &vol.Location, &volumeType, &contentType, &vol.Description, &vol.CreatedAt, &vol.Pool) + err := scan(&vol.Project, &vol.ID, &vol.Name, &vol.Location, &rawVolumeType, &rawContentType, &vol.Description, &vol.CreatedAt, &vol.Pool) if err != nil { return err } - vol.Type, err = storagePoolVolumeTypeToName(volumeType) + volumeType, err := cluster.StoragePoolVolumeTypeFromInt(rawVolumeType) if err != nil { return err } - vol.ContentType, err = storagePoolVolumeContentTypeToName(contentType) + contentType, err := cluster.StoragePoolVolumeContentTypeFromInt(rawContentType) if err != nil { return err } + vol.Type = volumeType.Name() + vol.ContentType = contentType.Name() + volumes = append(volumes, &vol) return nil @@ -311,9 +320,9 @@ func (c *ClusterTx) GetLocalStoragePoolVolumeSnapshotsWithType(ctx context.Conte var s StorageVolumeArgs var snapName string var expiryDate sql.NullTime - var contentType int + var rawContentType = int(-1) - err := scan(&s.ID, &snapName, &s.Description, &s.CreationDate, &expiryDate, &contentType) + err := scan(&s.ID, &snapName, &s.Description, &s.CreationDate, &expiryDate, &rawContentType) if err != nil { return err } @@ -324,11 +333,13 @@ func (c *ClusterTx) GetLocalStoragePoolVolumeSnapshotsWithType(ctx context.Conte s.Snapshot = true s.ExpiryDate = expiryDate.Time // Convert null to zero. - s.ContentType, err = storagePoolVolumeContentTypeToName(contentType) + contentType, err := cluster.StoragePoolVolumeContentTypeFromInt(rawContentType) if err != nil { return err } + s.ContentType = contentType.Name() + snapshots = append(snapshots, s) return nil @@ -542,7 +553,7 @@ type StorageVolumeArgs struct { Name string // At least one of Type or TypeName must be set. - Type int + Type cluster.StoragePoolVolumeType TypeName string // At least one of PoolID or PoolName must be set. @@ -777,36 +788,6 @@ func storageVolumeConfigClear(tx *sql.Tx, volumeID int64, isSnapshot bool) error return nil } -// Convert a volume integer type code to its human-readable name. -func storagePoolVolumeTypeToName(volumeType int) (string, error) { - switch volumeType { - case cluster.StoragePoolVolumeTypeContainer: - return cluster.StoragePoolVolumeTypeNameContainer, nil - case cluster.StoragePoolVolumeTypeVM: - return cluster.StoragePoolVolumeTypeNameVM, nil - case cluster.StoragePoolVolumeTypeImage: - return cluster.StoragePoolVolumeTypeNameImage, nil - case cluster.StoragePoolVolumeTypeCustom: - return cluster.StoragePoolVolumeTypeNameCustom, nil - } - - return "", fmt.Errorf("Invalid storage volume type") -} - -// Convert a volume integer content type code to its human-readable name. -func storagePoolVolumeContentTypeToName(contentType int) (string, error) { - switch contentType { - case cluster.StoragePoolVolumeContentTypeFS: - return cluster.StoragePoolVolumeContentTypeNameFS, nil - case cluster.StoragePoolVolumeContentTypeBlock: - return cluster.StoragePoolVolumeContentTypeNameBlock, nil - case cluster.StoragePoolVolumeContentTypeISO: - return cluster.StoragePoolVolumeContentTypeNameISO, nil - } - - return "", fmt.Errorf("Invalid storage volume content type") -} - // GetCustomVolumesInProject returns all custom volumes in the given project. func (c *ClusterTx) GetCustomVolumesInProject(ctx context.Context, project string) ([]StorageVolumeArgs, error) { sql := ` From e0dd470c9930d36d506785605ccab2440ebe5264 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:21:03 -0600 Subject: [PATCH 04/15] lxd/storage: Use StoragePoolVolumeType Signed-off-by: Wesley Hershberger --- lxd/storage/utils.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go index 2db127ebd46e..7d94dde5f34e 100644 --- a/lxd/storage/utils.go +++ b/lxd/storage/utils.go @@ -73,7 +73,7 @@ func ConfigDiff(oldConfig map[string]string, newConfig map[string]string) ([]str } // VolumeTypeNameToDBType converts a volume type string to internal volume type DB code. -func VolumeTypeNameToDBType(volumeTypeName string) (int, error) { +func VolumeTypeNameToDBType(volumeTypeName string) (cluster.StoragePoolVolumeType, error) { switch volumeTypeName { case cluster.StoragePoolVolumeTypeNameContainer: return cluster.StoragePoolVolumeTypeContainer, nil @@ -89,7 +89,7 @@ func VolumeTypeNameToDBType(volumeTypeName string) (int, error) { } // VolumeTypeToDBType converts volume type to internal volume type DB code. -func VolumeTypeToDBType(volType drivers.VolumeType) (int, error) { +func VolumeTypeToDBType(volType drivers.VolumeType) (cluster.StoragePoolVolumeType, error) { switch volType { case drivers.VolumeTypeContainer: return cluster.StoragePoolVolumeTypeContainer, nil @@ -105,7 +105,7 @@ func VolumeTypeToDBType(volType drivers.VolumeType) (int, error) { } // VolumeDBTypeToType converts internal volume type DB code to storage driver volume type. -func VolumeDBTypeToType(volDBType int) (drivers.VolumeType, error) { +func VolumeDBTypeToType(volDBType cluster.StoragePoolVolumeType) (drivers.VolumeType, error) { switch volDBType { case cluster.StoragePoolVolumeTypeContainer: return drivers.VolumeTypeContainer, nil @@ -188,7 +188,7 @@ func VolumeContentTypeNameToContentType(contentTypeName string) (int, error) { // DiskVolumeSourceParse parses a disk device's `source` property when it refers to a // storage volume. -func DiskVolumeSourceParse(source string) (volType drivers.VolumeType, dbVolType int, volTypeName string, volName string, err error) { +func DiskVolumeSourceParse(source string) (volType drivers.VolumeType, dbVolType cluster.StoragePoolVolumeType, volTypeName string, volName string, err error) { source = filepath.Clean(source) slash := strings.Index(source, "/") @@ -996,7 +996,7 @@ func volumeIsUsedByDevice(vol api.StorageVolume, inst *db.InstanceArgs, dev map[ return false, err } - if inst.Name == vol.Name && cluster.StoragePoolVolumeTypeNames[rootVolumeDBType] == vol.Type { + if inst.Name == vol.Name && rootVolumeDBType.Name() == vol.Type { return true, nil } } From 197974d8cf7c0d95de41f1bf738972d358ad1f30 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:23:12 -0600 Subject: [PATCH 05/15] lxd/db: Use StoragePoolVolumeType for query params Signed-off-by: Wesley Hershberger --- lxd/db/instances.go | 2 +- lxd/db/storage_volume_snapshots.go | 4 ++-- lxd/db/storage_volumes.go | 26 +++++++++++++------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lxd/db/instances.go b/lxd/db/instances.go index 846a9d81a8c0..7d1dd2955cf9 100644 --- a/lxd/db/instances.go +++ b/lxd/db/instances.go @@ -666,7 +666,7 @@ func (c *ClusterTx) InstancesToInstanceArgs(ctx context.Context, fillProfiles bo // UpdateInstanceNode changes the name of an instance and the cluster member hosting it. // It's meant to be used when moving a non-running instance backed by ceph from one cluster node to another. -func (c *ClusterTx) UpdateInstanceNode(ctx context.Context, project string, oldName string, newName string, newMemberName string, poolID int64, volumeType int) error { +func (c *ClusterTx) UpdateInstanceNode(ctx context.Context, project string, oldName string, newName string, newMemberName string, poolID int64, volumeType cluster.StoragePoolVolumeType) error { // Update the name of the instance and its snapshots, and the member ID they are associated with. instanceID, err := cluster.GetInstanceID(ctx, c.tx, project, oldName) if err != nil { diff --git a/lxd/db/storage_volume_snapshots.go b/lxd/db/storage_volume_snapshots.go index e67c3b6bc5c9..c174c0978fe7 100644 --- a/lxd/db/storage_volume_snapshots.go +++ b/lxd/db/storage_volume_snapshots.go @@ -18,7 +18,7 @@ import ( // CreateStorageVolumeSnapshot creates a new storage volume snapshot attached to a given // storage pool. -func (c *ClusterTx) CreateStorageVolumeSnapshot(ctx context.Context, projectName string, volumeName string, volumeDescription string, volumeType int, poolID int64, volumeConfig map[string]string, creationDate time.Time, expiryDate time.Time) (int64, error) { +func (c *ClusterTx) CreateStorageVolumeSnapshot(ctx context.Context, projectName string, volumeName string, volumeDescription string, volumeType cluster.StoragePoolVolumeType, poolID int64, volumeConfig map[string]string, creationDate time.Time, expiryDate time.Time) (int64, error) { var volumeID int64 volumeName, snapshotName, _ := strings.Cut(volumeName, shared.SnapshotDelimiter) @@ -54,7 +54,7 @@ func (c *ClusterTx) CreateStorageVolumeSnapshot(ctx context.Context, projectName } // UpdateStorageVolumeSnapshot updates the storage volume snapshot attached to a given storage pool. -func (c *ClusterTx) UpdateStorageVolumeSnapshot(ctx context.Context, projectName string, volumeName string, volumeType int, poolID int64, volumeDescription string, volumeConfig map[string]string, expiryDate time.Time) error { +func (c *ClusterTx) UpdateStorageVolumeSnapshot(ctx context.Context, projectName string, volumeName string, volumeType cluster.StoragePoolVolumeType, poolID int64, volumeDescription string, volumeConfig map[string]string, expiryDate time.Time) error { var err error if !strings.Contains(volumeName, shared.SnapshotDelimiter) { diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index 8183dd58fc97..b9d94ce66289 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -21,7 +21,7 @@ import ( // GetStoragePoolVolumesWithType return a list of all volumes of the given type. // If memberSpecific is true, then the search is restricted to volumes that belong to this member or belong to // all members. -func (c *ClusterTx) GetStoragePoolVolumesWithType(ctx context.Context, volumeType int, memberSpecific bool) ([]StorageVolumeArgs, error) { +func (c *ClusterTx) GetStoragePoolVolumesWithType(ctx context.Context, volumeType cluster.StoragePoolVolumeType, memberSpecific bool) ([]StorageVolumeArgs, error) { var q strings.Builder q.WriteString(` SELECT @@ -119,7 +119,7 @@ WHERE storage_volumes.id = ? // StorageVolumeFilter used for filtering storage volumes with GetStorageVolumes(). type StorageVolumeFilter struct { - Type *int + Type *cluster.StoragePoolVolumeType Project *string Name *string PoolID *int64 @@ -262,7 +262,7 @@ func (c *ClusterTx) GetStorageVolumes(ctx context.Context, memberSpecific bool, } // GetStoragePoolVolume returns the storage volume attached to a given storage pool. -func (c *ClusterTx) GetStoragePoolVolume(ctx context.Context, poolID int64, projectName string, volumeType int, volumeName string, memberSpecific bool) (*StorageVolume, error) { +func (c *ClusterTx) GetStoragePoolVolume(ctx context.Context, poolID int64, projectName string, volumeType cluster.StoragePoolVolumeType, volumeName string, memberSpecific bool) (*StorageVolume, error) { filters := []StorageVolumeFilter{{ Project: &projectName, Type: &volumeType, @@ -286,7 +286,7 @@ func (c *ClusterTx) GetStoragePoolVolume(ctx context.Context, poolID int64, proj // GetLocalStoragePoolVolumeSnapshotsWithType get all snapshots of a storage volume // attached to a given storage pool of a given volume type, on the local member. // Returns snapshots slice ordered by when they were created, oldest first. -func (c *ClusterTx) GetLocalStoragePoolVolumeSnapshotsWithType(ctx context.Context, projectName string, volumeName string, volumeType int, poolID int64) ([]StorageVolumeArgs, error) { +func (c *ClusterTx) GetLocalStoragePoolVolumeSnapshotsWithType(ctx context.Context, projectName string, volumeName string, volumeType cluster.StoragePoolVolumeType, poolID int64) ([]StorageVolumeArgs, error) { remoteDrivers := StorageRemoteDriverNames() // ORDER BY creation_date and then id is important here as the users of this function can expect that the @@ -384,7 +384,7 @@ func storageVolumeSnapshotConfig(ctx context.Context, tx *ClusterTx, volumeSnaps } // UpdateStoragePoolVolume updates the storage volume attached to a given storage pool. -func (c *ClusterTx) UpdateStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeType int, poolID int64, volumeDescription string, volumeConfig map[string]string) error { +func (c *ClusterTx) UpdateStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeType cluster.StoragePoolVolumeType, poolID int64, volumeDescription string, volumeConfig map[string]string) error { isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter) volume, err := c.GetStoragePoolVolume(ctx, poolID, projectName, volumeType, volumeName, true) @@ -412,7 +412,7 @@ func (c *ClusterTx) UpdateStoragePoolVolume(ctx context.Context, projectName str // RemoveStoragePoolVolume deletes the storage volume attached to a given storage // pool. -func (c *ClusterTx) RemoveStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeType int, poolID int64) error { +func (c *ClusterTx) RemoveStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeType cluster.StoragePoolVolumeType, poolID int64) error { isSnapshot := strings.Contains(volumeName, shared.SnapshotDelimiter) var stmt string if isSnapshot { @@ -435,7 +435,7 @@ func (c *ClusterTx) RemoveStoragePoolVolume(ctx context.Context, projectName str } // RenameStoragePoolVolume renames the storage volume attached to a given storage pool. -func (c *ClusterTx) RenameStoragePoolVolume(ctx context.Context, projectName string, oldVolumeName string, newVolumeName string, volumeType int, poolID int64) error { +func (c *ClusterTx) RenameStoragePoolVolume(ctx context.Context, projectName string, oldVolumeName string, newVolumeName string, volumeType cluster.StoragePoolVolumeType, poolID int64) error { isSnapshot := strings.Contains(oldVolumeName, shared.SnapshotDelimiter) var stmt string if isSnapshot { @@ -459,7 +459,7 @@ func (c *ClusterTx) RenameStoragePoolVolume(ctx context.Context, projectName str } // CreateStoragePoolVolume creates a new storage volume attached to a given storage pool. -func (c *ClusterTx) CreateStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeDescription string, volumeType int, poolID int64, volumeConfig map[string]string, contentType int, creationDate time.Time) (int64, error) { +func (c *ClusterTx) CreateStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeDescription string, volumeType cluster.StoragePoolVolumeType, poolID int64, volumeConfig map[string]string, contentType int, creationDate time.Time) (int64, error) { var volumeID int64 if shared.IsSnapshot(volumeName) { @@ -508,7 +508,7 @@ INSERT INTO storage_volumes (storage_pool_id, node_id, type, name, description, // Return the ID of a storage volume on a given storage pool of a given storage // volume type, on the given node. -func (c *ClusterTx) storagePoolVolumeGetTypeID(ctx context.Context, project string, volumeName string, volumeType int, poolID, nodeID int64) (int64, error) { +func (c *ClusterTx) storagePoolVolumeGetTypeID(ctx context.Context, project string, volumeName string, volumeType cluster.StoragePoolVolumeType, poolID, nodeID int64) (int64, error) { remoteDrivers := StorageRemoteDriverNames() s := fmt.Sprintf(` @@ -542,7 +542,7 @@ SELECT storage_volumes_all.id // GetStoragePoolNodeVolumeID gets the ID of a storage volume on a given storage pool // of a given storage volume type and project, on the current node. -func (c *ClusterTx) GetStoragePoolNodeVolumeID(ctx context.Context, projectName string, volumeName string, volumeType int, poolID int64) (int64, error) { +func (c *ClusterTx) GetStoragePoolNodeVolumeID(ctx context.Context, projectName string, volumeName string, volumeType cluster.StoragePoolVolumeType, poolID int64) (int64, error) { return c.storagePoolVolumeGetTypeID(ctx, projectName, volumeName, volumeType, poolID, c.nodeID) } @@ -580,7 +580,7 @@ type StorageVolumeArgs struct { // The volume name can be either a regular name or a volume snapshot name. // If the volume is defined, but without a specific node, then the ErrNoClusterMember error is returned. // If the volume is not found then an api.StatusError with code set to http.StatusNotFound is returned. -func (c *ClusterTx) GetStorageVolumeNodes(ctx context.Context, poolID int64, projectName string, volumeName string, volumeType int) ([]NodeInfo, error) { +func (c *ClusterTx) GetStorageVolumeNodes(ctx context.Context, poolID int64, projectName string, volumeName string, volumeType cluster.StoragePoolVolumeType) ([]NodeInfo, error) { nodes := []NodeInfo{} sql := ` @@ -678,7 +678,7 @@ func (c *ClusterTx) storageVolumeConfigGet(ctx context.Context, volumeID int64, // // Note, the code below doesn't deal with snapshots of snapshots. // To do that, we'll need to weed out based on # slashes in names. -func (c *ClusterTx) GetNextStorageVolumeSnapshotIndex(ctx context.Context, pool, name string, typ int, pattern string) (nextIndex int) { +func (c *ClusterTx) GetNextStorageVolumeSnapshotIndex(ctx context.Context, pool, name string, typ cluster.StoragePoolVolumeType, pattern string) (nextIndex int) { remoteDrivers := StorageRemoteDriverNames() q := fmt.Sprintf(` @@ -866,7 +866,7 @@ func (c *ClusterTx) GetStorageVolumeURIs(ctx context.Context, project string) ([ // UpdateStorageVolumeNode changes the name of a storage volume and the cluster member hosting it. // It's meant to be used when moving a storage volume backed by ceph from one cluster node to another. -func (c *ClusterTx) UpdateStorageVolumeNode(ctx context.Context, projectName string, oldName string, newName string, newMemberName string, poolID int64, volumeType int) error { +func (c *ClusterTx) UpdateStorageVolumeNode(ctx context.Context, projectName string, oldName string, newName string, newMemberName string, poolID int64, volumeType cluster.StoragePoolVolumeType) error { volume, err := c.GetStoragePoolVolume(ctx, poolID, projectName, volumeType, oldName, false) if err != nil { return err From c3a3d4f92eb15cf7c19fe306ed9b460610b140a7 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:23:49 -0600 Subject: [PATCH 06/15] lxd/project: Use StoragePoolVolumeType Signed-off-by: Wesley Hershberger --- lxd/project/project.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lxd/project/project.go b/lxd/project/project.go index 5c93a630d6eb..4a2d02f30609 100644 --- a/lxd/project/project.go +++ b/lxd/project/project.go @@ -73,7 +73,7 @@ func StorageVolumeParts(projectStorageVolumeName string) (projectName string, st // For custom volume type, if the project specified has the "features.storage.volumes" flag enabled then the // project name is returned, otherwise the default project name is returned. // For all other volume types the supplied project name is returned. -func StorageVolumeProject(c *db.Cluster, projectName string, volumeType int) (string, error) { +func StorageVolumeProject(c *db.Cluster, projectName string, volumeType cluster.StoragePoolVolumeType) (string, error) { // Image volumes are effectively a cache and so are always linked to default project. // Optimisation to avoid loading project record. if volumeType == cluster.StoragePoolVolumeTypeImage { @@ -103,7 +103,7 @@ func StorageVolumeProject(c *db.Cluster, projectName string, volumeType int) (st // For custom volume type, if the project supplied has the "features.storage.volumes" flag enabled then the // project name is returned, otherwise the default project name is returned. // For all other volume types the supplied project's name is returned. -func StorageVolumeProjectFromRecord(p *api.Project, volumeType int) string { +func StorageVolumeProjectFromRecord(p *api.Project, volumeType cluster.StoragePoolVolumeType) string { // Image volumes are effectively a cache and so are always linked to default project. if volumeType == cluster.StoragePoolVolumeTypeImage { return api.ProjectDefaultName From e431d169503b1b86e9d3a2a572857593b187a087 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:41:30 -0600 Subject: [PATCH 07/15] lxd/device: Use StoragePoolVolumeType Signed-off-by: Wesley Hershberger --- lxd/device/disk.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/device/disk.go b/lxd/device/disk.go index fa26c2acb492..68be0447ee4d 100644 --- a/lxd/device/disk.go +++ b/lxd/device/disk.go @@ -1853,7 +1853,7 @@ func (d *disk) localSourceOpen(srcPath string) (*os.File, error) { return f, nil } -func (d *disk) storagePoolVolumeAttachShift(projectName, poolName, volumeName string, volumeType int, remapPath string) error { +func (d *disk) storagePoolVolumeAttachShift(projectName, poolName, volumeName string, volumeType cluster.StoragePoolVolumeType, remapPath string) error { var err error var dbVolume *db.StorageVolume err = d.state.DB.Cluster.Transaction(context.TODO(), func(ctx context.Context, tx *db.ClusterTx) error { From f0b26ef798118d2280ff3987f5954cc9fe5be897 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Wed, 29 Jan 2025 16:35:29 -0600 Subject: [PATCH 08/15] lxd/instance/drivers: Use StoragePoolVolumeType.Name Signed-off-by: Wesley Hershberger --- lxd/instance/drivers/driver_qemu.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go index c704469d343f..0acae4cf6b03 100644 --- a/lxd/instance/drivers/driver_qemu.go +++ b/lxd/instance/drivers/driver_qemu.go @@ -5368,7 +5368,7 @@ func allowRemoveSecurityProtectionStart(state *state.State, poolName string, vol return err }) if err != nil { - volumeTypeName := dbCluster.StoragePoolVolumeTypeNames[volumeType] + volumeTypeName := volumeType.Name() return fmt.Errorf(`Failed loading "%s/%s" from project %q: %w`, volumeTypeName, volumeName, volumeProject, err) } From da88c0422ddeb3f61ae9929fdac438b69a7dd4f1 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:44:56 -0600 Subject: [PATCH 09/15] lxd: Use StoragePoolVolumeType Signed-off-by: Wesley Hershberger --- lxd/patches.go | 2 +- lxd/storage_volumes.go | 6 +++--- lxd/storage_volumes_snapshot.go | 2 +- lxd/storage_volumes_state.go | 2 +- lxd/storage_volumes_utils.go | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lxd/patches.go b/lxd/patches.go index 398444f4060e..a8dd96e0a675 100644 --- a/lxd/patches.go +++ b/lxd/patches.go @@ -1005,7 +1005,7 @@ func patchStorageZfsUnsetInvalidBlockSettingsV2(_ string, d *Daemon) error { return err } - var volType int + var volType dbCluster.StoragePoolVolumeType for pool, volumes := range poolVolumes { for _, vol := range volumes { diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index 95af61f6c395..0a7af334d2ca 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -639,7 +639,7 @@ func storagePoolVolumesGet(d *Daemon, r *http.Request) response.Response { } // Convert volume type name to internal integer representation if requested. - var volumeType int + var volumeType cluster.StoragePoolVolumeType if volumeTypeName != "" { volumeType, err = storagePools.VolumeTypeNameToDBType(volumeTypeName) if err != nil { @@ -2703,7 +2703,7 @@ const ctxStorageVolumeDetails request.CtxKey = "storage-volume-details" type storageVolumeDetails struct { volumeName string volumeTypeName string - volumeType int + volumeType cluster.StoragePoolVolumeType location string pool storagePools.Pool forwardingNodeInfo *db.NodeInfo @@ -2822,7 +2822,7 @@ func addStoragePoolVolumeDetailsToRequestContext(s *state.State, r *http.Request // the local cluster member it returns nil and no error. If it is another cluster member it returns a db.NodeInfo containing // the name and address of the remote member. If there is more than one cluster member with a matching volume name, an // error is returned. -func getRemoteVolumeNodeInfo(ctx context.Context, s *state.State, poolName string, projectName string, volumeName string, volumeType int) (*db.NodeInfo, error) { +func getRemoteVolumeNodeInfo(ctx context.Context, s *state.State, poolName string, projectName string, volumeName string, volumeType cluster.StoragePoolVolumeType) (*db.NodeInfo, error) { localNodeID := s.DB.Cluster.GetNodeID() var err error var nodes []db.NodeInfo diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go index afc53f9320bd..4e62e4cce83c 100644 --- a/lxd/storage_volumes_snapshot.go +++ b/lxd/storage_volumes_snapshot.go @@ -883,7 +883,7 @@ func storagePoolVolumeSnapshotTypePatch(d *Daemon, r *http.Request) response.Res return doStoragePoolVolumeSnapshotUpdate(s, r, effectiveProjectName, dbVolume.Name, details.volumeType, req) } -func doStoragePoolVolumeSnapshotUpdate(s *state.State, r *http.Request, projectName string, volName string, volumeType int, req api.StorageVolumeSnapshotPut) response.Response { +func doStoragePoolVolumeSnapshotUpdate(s *state.State, r *http.Request, projectName string, volName string, volumeType dbCluster.StoragePoolVolumeType, req api.StorageVolumeSnapshotPut) response.Response { expiry := time.Time{} if req.ExpiresAt != nil { expiry = *req.ExpiresAt diff --git a/lxd/storage_volumes_state.go b/lxd/storage_volumes_state.go index 2027f4e254ea..b312cfcd49fc 100644 --- a/lxd/storage_volumes_state.go +++ b/lxd/storage_volumes_state.go @@ -101,7 +101,7 @@ func storagePoolVolumeTypeStateGet(d *Daemon, r *http.Request) response.Response } // Check that the storage volume type is valid. - if !shared.ValueInSlice(volumeType, []int{cluster.StoragePoolVolumeTypeCustom, cluster.StoragePoolVolumeTypeContainer, cluster.StoragePoolVolumeTypeVM}) { + if !shared.ValueInSlice(volumeType, []cluster.StoragePoolVolumeType{cluster.StoragePoolVolumeTypeCustom, cluster.StoragePoolVolumeTypeContainer, cluster.StoragePoolVolumeTypeVM}) { return response.BadRequest(fmt.Errorf("Invalid storage volume type %q", volumeTypeName)) } diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go index 7bbd4d26a763..0885d23d2046 100644 --- a/lxd/storage_volumes_utils.go +++ b/lxd/storage_volumes_utils.go @@ -18,7 +18,7 @@ import ( "github.com/canonical/lxd/shared/version" ) -var supportedVolumeTypes = []int{cluster.StoragePoolVolumeTypeContainer, cluster.StoragePoolVolumeTypeVM, cluster.StoragePoolVolumeTypeCustom, cluster.StoragePoolVolumeTypeImage} +var supportedVolumeTypes = []cluster.StoragePoolVolumeType{cluster.StoragePoolVolumeTypeContainer, cluster.StoragePoolVolumeTypeVM, cluster.StoragePoolVolumeTypeCustom, cluster.StoragePoolVolumeTypeImage} func storagePoolVolumeUpdateUsers(s *state.State, projectName string, oldPoolName string, oldVol *api.StorageVolume, newPoolName string, newVol *api.StorageVolume) (revert.Hook, error) { revert := revert.New() From a7e64f19cc5e0aa9d448a585bdc1c1e05c6b4fcf Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:25:17 -0600 Subject: [PATCH 10/15] lxd/db: Use StoragePoolVolumeContentType Signed-off-by: Wesley Hershberger --- lxd/db/storage_volumes.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/db/storage_volumes.go b/lxd/db/storage_volumes.go index b9d94ce66289..48b9883af497 100644 --- a/lxd/db/storage_volumes.go +++ b/lxd/db/storage_volumes.go @@ -459,7 +459,7 @@ func (c *ClusterTx) RenameStoragePoolVolume(ctx context.Context, projectName str } // CreateStoragePoolVolume creates a new storage volume attached to a given storage pool. -func (c *ClusterTx) CreateStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeDescription string, volumeType cluster.StoragePoolVolumeType, poolID int64, volumeConfig map[string]string, contentType int, creationDate time.Time) (int64, error) { +func (c *ClusterTx) CreateStoragePoolVolume(ctx context.Context, projectName string, volumeName string, volumeDescription string, volumeType cluster.StoragePoolVolumeType, poolID int64, volumeConfig map[string]string, contentType cluster.StoragePoolVolumeContentType, creationDate time.Time) (int64, error) { var volumeID int64 if shared.IsSnapshot(volumeName) { From 1fb3e0b1afb6ab6f95030433541d24b832a4202a Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:25:40 -0600 Subject: [PATCH 11/15] lxd/storage: Use StoragePoolVolumeContentType Signed-off-by: Wesley Hershberger --- lxd/storage/utils.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go index 7d94dde5f34e..462fdfff18e8 100644 --- a/lxd/storage/utils.go +++ b/lxd/storage/utils.go @@ -145,7 +145,7 @@ func VolumeTypeToAPIInstanceType(volType drivers.VolumeType) (api.InstanceType, } // VolumeContentTypeToDBContentType converts volume type to internal code. -func VolumeContentTypeToDBContentType(contentType drivers.ContentType) (int, error) { +func VolumeContentTypeToDBContentType(contentType drivers.ContentType) (cluster.StoragePoolVolumeContentType, error) { switch contentType { case drivers.ContentTypeBlock: return cluster.StoragePoolVolumeContentTypeBlock, nil @@ -159,7 +159,7 @@ func VolumeContentTypeToDBContentType(contentType drivers.ContentType) (int, err } // VolumeDBContentTypeToContentType converts internal content type DB code to driver representation. -func VolumeDBContentTypeToContentType(volDBType int) (drivers.ContentType, error) { +func VolumeDBContentTypeToContentType(volDBType cluster.StoragePoolVolumeContentType) (drivers.ContentType, error) { switch volDBType { case cluster.StoragePoolVolumeContentTypeBlock: return drivers.ContentTypeBlock, nil @@ -173,7 +173,7 @@ func VolumeDBContentTypeToContentType(volDBType int) (drivers.ContentType, error } // VolumeContentTypeNameToContentType converts volume content type string internal code. -func VolumeContentTypeNameToContentType(contentTypeName string) (int, error) { +func VolumeContentTypeNameToContentType(contentTypeName string) (cluster.StoragePoolVolumeContentType, error) { switch contentTypeName { case cluster.StoragePoolVolumeContentTypeNameFS: return cluster.StoragePoolVolumeContentTypeFS, nil From 7a17e7f48205b1dfaa5713423fbf9d497a382274 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Wed, 29 Jan 2025 16:26:19 -0600 Subject: [PATCH 12/15] lxd/storage: Replace VolumeTypeNameToDBType with StoragePoolVolumeTypeFromName Signed-off-by: Wesley Hershberger --- lxd/storage/backend_lxd.go | 2 +- lxd/storage/utils.go | 22 +++------------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go index 639be8bcf18b..0fff3cd98429 100644 --- a/lxd/storage/backend_lxd.go +++ b/lxd/storage/backend_lxd.go @@ -7152,7 +7152,7 @@ func (b *lxdBackend) detectUnknownInstanceVolume(vol *drivers.Volume, projectVol return fmt.Errorf("Instance %q in project %q has a different volume name in its backup file (%q)", instName, projectName, backupConf.Volume.Name) } - instVolDBType, err := VolumeTypeNameToDBType(backupConf.Volume.Type) + instVolDBType, err := cluster.StoragePoolVolumeTypeFromName(backupConf.Volume.Type) if err != nil { return fmt.Errorf("Failed checking instance volume type for instance %q in project %q: %w", instName, projectName, err) } diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go index 462fdfff18e8..685a49528410 100644 --- a/lxd/storage/utils.go +++ b/lxd/storage/utils.go @@ -72,22 +72,6 @@ func ConfigDiff(oldConfig map[string]string, newConfig map[string]string) ([]str return changedConfig, userOnly } -// VolumeTypeNameToDBType converts a volume type string to internal volume type DB code. -func VolumeTypeNameToDBType(volumeTypeName string) (cluster.StoragePoolVolumeType, error) { - switch volumeTypeName { - case cluster.StoragePoolVolumeTypeNameContainer: - return cluster.StoragePoolVolumeTypeContainer, nil - case cluster.StoragePoolVolumeTypeNameVM: - return cluster.StoragePoolVolumeTypeVM, nil - case cluster.StoragePoolVolumeTypeNameImage: - return cluster.StoragePoolVolumeTypeImage, nil - case cluster.StoragePoolVolumeTypeNameCustom: - return cluster.StoragePoolVolumeTypeCustom, nil - } - - return -1, fmt.Errorf("Invalid storage volume type name") -} - // VolumeTypeToDBType converts volume type to internal volume type DB code. func VolumeTypeToDBType(volType drivers.VolumeType) (cluster.StoragePoolVolumeType, error) { switch volType { @@ -219,7 +203,7 @@ func DiskVolumeSourceParse(source string) (volType drivers.VolumeType, dbVolType return volType, dbVolType, "", "", err } - dbVolType, err = VolumeTypeNameToDBType(volTypeName) + dbVolType, err = cluster.StoragePoolVolumeTypeFromName(volTypeName) if err != nil { return volType, dbVolType, "", "", err } @@ -1018,7 +1002,7 @@ func volumeIsUsedByDevice(vol api.StorageVolume, inst *db.InstanceArgs, dev map[ // the volume. func VolumeUsedByProfileDevices(s *state.State, poolName string, projectName string, vol *api.StorageVolume, profileFunc func(profileID int64, profile api.Profile, project api.Project, usedByDevices []string) error) error { // Convert the volume type name to our internal integer representation. - volumeType, err := VolumeTypeNameToDBType(vol.Type) + volumeType, err := cluster.StoragePoolVolumeTypeFromName(vol.Type) if err != nil { return err } @@ -1125,7 +1109,7 @@ func VolumeUsedByProfileDevices(s *state.State, poolName string, projectName str // names that are using the volume. func VolumeUsedByInstanceDevices(s *state.State, poolName string, projectName string, vol *api.StorageVolume, expandDevices bool, instanceFunc func(inst db.InstanceArgs, project api.Project, usedByDevices []string) error) error { // Convert the volume type name to our internal integer representation. - volumeType, err := VolumeTypeNameToDBType(vol.Type) + volumeType, err := cluster.StoragePoolVolumeTypeFromName(vol.Type) if err != nil { return err } From a1dad6cbdfcce45ac458113565b54074359be6a1 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Wed, 29 Jan 2025 16:29:10 -0600 Subject: [PATCH 13/15] lxd: Replace VolumeTypeNameToDBType with StoragePoolVolumeTypeFromName Signed-off-by: Wesley Hershberger --- lxd/storage_volumes.go | 4 ++-- lxd/storage_volumes_state.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go index 0a7af334d2ca..54f4503b9984 100644 --- a/lxd/storage_volumes.go +++ b/lxd/storage_volumes.go @@ -641,7 +641,7 @@ func storagePoolVolumesGet(d *Daemon, r *http.Request) response.Response { // Convert volume type name to internal integer representation if requested. var volumeType cluster.StoragePoolVolumeType if volumeTypeName != "" { - volumeType, err = storagePools.VolumeTypeNameToDBType(volumeTypeName) + volumeType, err = cluster.StoragePoolVolumeTypeFromName(volumeTypeName) if err != nil { return response.BadRequest(err) } @@ -2756,7 +2756,7 @@ func addStoragePoolVolumeDetailsToRequestContext(s *state.State, r *http.Request details.volumeTypeName = volumeTypeName // Convert the volume type name to our internal integer representation. - volumeType, err := storagePools.VolumeTypeNameToDBType(volumeTypeName) + volumeType, err := cluster.StoragePoolVolumeTypeFromName(volumeTypeName) if err != nil { return api.StatusErrorf(http.StatusBadRequest, "Failed to get storage volume type: %w", err) } diff --git a/lxd/storage_volumes_state.go b/lxd/storage_volumes_state.go index b312cfcd49fc..a4e61bb484fb 100644 --- a/lxd/storage_volumes_state.go +++ b/lxd/storage_volumes_state.go @@ -95,7 +95,7 @@ func storagePoolVolumeTypeStateGet(d *Daemon, r *http.Request) response.Response } // Convert the volume type name to our internal integer representation. - volumeType, err := storagePools.VolumeTypeNameToDBType(volumeTypeName) + volumeType, err := cluster.StoragePoolVolumeTypeFromName(volumeTypeName) if err != nil { return response.BadRequest(err) } From 8e199e9bc212e569fde7a5c01122eabaa69bac53 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Thu, 9 Jan 2025 17:44:06 -0600 Subject: [PATCH 14/15] lxd/db/test: Use StoragePoolVolumeType Signed-off-by: Wesley Hershberger --- lxd/db/storage_pools_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/db/storage_pools_test.go b/lxd/db/storage_pools_test.go index 6296d9f84ca2..c9b7bf931093 100644 --- a/lxd/db/storage_pools_test.go +++ b/lxd/db/storage_pools_test.go @@ -198,7 +198,7 @@ func TestStoragePoolVolume_Ceph(t *testing.T) { }) require.NoError(t, err) - getStoragePoolVolume := func(volumeProjectName string, volumeName string, volumeType int, poolID int64) (*db.StorageVolume, error) { + getStoragePoolVolume := func(volumeProjectName string, volumeName string, volumeType cluster.StoragePoolVolumeType, poolID int64) (*db.StorageVolume, error) { var dbVolume *db.StorageVolume err = clusterDB.Transaction(context.TODO(), func(ctx context.Context, tx *db.ClusterTx) error { dbVolume, err = tx.GetStoragePoolVolume(context.Background(), poolID, volumeProjectName, volumeType, volumeName, true) From c41c1c609251778d87cda1a94a834cfe7ae2ecf4 Mon Sep 17 00:00:00 2001 From: Wesley Hershberger Date: Wed, 29 Jan 2025 17:02:12 -0600 Subject: [PATCH 15/15] lxd/test: Fix misused ContentType constant Signed-off-by: Wesley Hershberger --- lxd/instance_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/instance_test.go b/lxd/instance_test.go index ada5e1713c8a..61bef17dcb43 100644 --- a/lxd/instance_test.go +++ b/lxd/instance_test.go @@ -182,7 +182,7 @@ func (suite *containerTestSuite) TestContainer_LoadFromDB() { suite.Req.Nil(err) err = state.DB.Cluster.Transaction(context.TODO(), func(ctx context.Context, tx *db.ClusterTx) error { - _, err = tx.CreateStoragePoolVolume(ctx, c.Project().Name, c.Name(), "", cluster.StoragePoolVolumeContentTypeFS, pool.ID(), nil, cluster.StoragePoolVolumeContentTypeFS, time.Now()) + _, err = tx.CreateStoragePoolVolume(ctx, c.Project().Name, c.Name(), "", cluster.StoragePoolVolumeTypeContainer, pool.ID(), nil, cluster.StoragePoolVolumeContentTypeFS, time.Now()) return err })