Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage: Newtype for Database Volume/Content types #14885

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 75 additions & 8 deletions lxd/db/cluster/storage_volume_type.go
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,17 +31,50 @@
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) {

Check failure on line 34 in lxd/db/cluster/storage_volume_type.go

View workflow job for this annotation

GitHub Actions / Code

exported: exported function StoragePoolVolumeTypeFromInt should have comment or be unexported (revive)
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) {

Check failure on line 43 in lxd/db/cluster/storage_volume_type.go

View workflow job for this annotation

GitHub Actions / Code

exported: exported function StoragePoolVolumeTypeFromName should have comment or be unexported (revive)
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 {

Check failure on line 58 in lxd/db/cluster/storage_volume_type.go

View workflow job for this annotation

GitHub Actions / Code

exported: exported method StoragePoolVolumeType.Name should have comment or be unexported (revive)
switch t {
case StoragePoolVolumeTypeContainer:
return StoragePoolVolumeTypeNameContainer
case StoragePoolVolumeTypeVM:
return StoragePoolVolumeTypeNameVM
case StoragePoolVolumeTypeImage:
return StoragePoolVolumeTypeNameImage
case StoragePoolVolumeTypeCustom:
return StoragePoolVolumeTypeNameCustom
}

return StoragePoolVolumeTypeNameCustom
}

type StoragePoolVolumeContentType int

Check failure on line 73 in lxd/db/cluster/storage_volume_type.go

View workflow job for this annotation

GitHub Actions / Code

exported: exported type StoragePoolVolumeContentType should have comment or be unexported (revive)

// Content types.
const (
StoragePoolVolumeContentTypeFS = iota
StoragePoolVolumeContentTypeFS StoragePoolVolumeContentType = iota
StoragePoolVolumeContentTypeBlock
StoragePoolVolumeContentTypeISO
)
Expand All @@ -40,3 +85,25 @@
StoragePoolVolumeContentTypeNameBlock string = "block"
StoragePoolVolumeContentTypeNameISO string = "iso"
)

func StoragePoolVolumeContentTypeFromInt(contentType int) (StoragePoolVolumeContentType, error) {

Check failure on line 89 in lxd/db/cluster/storage_volume_type.go

View workflow job for this annotation

GitHub Actions / Code

exported: exported function StoragePoolVolumeContentTypeFromInt should have comment or be unexported (revive)
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 {

Check failure on line 98 in lxd/db/cluster/storage_volume_type.go

View workflow job for this annotation

GitHub Actions / Code

exported: exported method StoragePoolVolumeContentType.Name should have comment or be unexported (revive)
switch t {
case StoragePoolVolumeContentTypeFS:
return StoragePoolVolumeContentTypeNameFS
case StoragePoolVolumeContentTypeBlock:
return StoragePoolVolumeContentTypeNameBlock
case StoragePoolVolumeContentTypeISO:
return StoragePoolVolumeContentTypeNameISO
}

return StoragePoolVolumeContentTypeNameFS
}
2 changes: 1 addition & 1 deletion lxd/db/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion lxd/db/storage_pools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 10 additions & 4 deletions lxd/db/storage_volume_snapshots.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand All @@ -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
}
Expand Down
Loading
Loading