From 8b52bd1c6f6d504cd5cefee631f0bcd63b514054 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Fri, 20 Dec 2024 12:14:37 +0000 Subject: [PATCH 1/7] lxd/db: Add freshschema package. Signed-off-by: Mark Laing --- lxd/db/freshschema/main.go | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lxd/db/freshschema/main.go diff --git a/lxd/db/freshschema/main.go b/lxd/db/freshschema/main.go new file mode 100644 index 000000000000..a156a8ff784a --- /dev/null +++ b/lxd/db/freshschema/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "fmt" + "os" + + "github.com/canonical/lxd/lxd/db/cluster" + "github.com/canonical/lxd/lxd/db/node" +) + +func main() { + err := freshSchema(os.Args[1:]) + if err != nil { + _, _ = os.Stderr.Write([]byte(err.Error())) + os.Exit(1) + } +} + +// UpdateSchema updates the schema.go file of the cluster and node databases. +func freshSchema(args []string) error { + if len(args) < 1 { + return fmt.Errorf(`Schema kind must be provided (must be "node", or "cluster")`) + } + + kind := args[0] + var err error + switch kind { + case "node": + err = node.SchemaDotGo() + case "cluster": + err = cluster.SchemaDotGo() + default: + return fmt.Errorf(`No such schema kind %q (must be "node", or "cluster")`, kind) + } + + if err != nil { + return fmt.Errorf("Update node database schema: %w", err) + } + + return nil +} From db7a0733c5b5cfaaddace36ffc715f1d8f66a9fc Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Fri, 20 Dec 2024 12:15:00 +0000 Subject: [PATCH 2/7] lxd-generate: Remove schema subcommand. Signed-off-by: Mark Laing --- lxd/db/generate/db.go | 17 ----------------- lxd/db/generate/db/schema.go | 27 --------------------------- 2 files changed, 44 deletions(-) delete mode 100644 lxd/db/generate/db/schema.go diff --git a/lxd/db/generate/db.go b/lxd/db/generate/db.go index 7c3b210e2b8b..15998c899b73 100644 --- a/lxd/db/generate/db.go +++ b/lxd/db/generate/db.go @@ -22,7 +22,6 @@ func newDb() *cobra.Command { }, } - cmd.AddCommand(newDbSchema()) cmd.AddCommand(newDbMapper()) // Workaround for subcommand usage errors. See: https://github.com/spf13/cobra/issues/706 @@ -31,22 +30,6 @@ func newDb() *cobra.Command { return cmd } -func newDbSchema() *cobra.Command { - cmd := &cobra.Command{ - Use: "schema", - Short: "Generate database schema by applying updates.", - RunE: func(cmd *cobra.Command, args []string) error { - if len(args) < 1 { - return fmt.Errorf(`Schema kind must be provided (must be "node", or "cluster")`) - } - - return db.UpdateSchema(args[0]) - }, - } - - return cmd -} - func newDbMapper() *cobra.Command { cmd := &cobra.Command{ Use: "mapper [sub-command]", diff --git a/lxd/db/generate/db/schema.go b/lxd/db/generate/db/schema.go deleted file mode 100644 index 872056c6e16f..000000000000 --- a/lxd/db/generate/db/schema.go +++ /dev/null @@ -1,27 +0,0 @@ -package db - -import ( - "fmt" - - "github.com/canonical/lxd/lxd/db/cluster" - "github.com/canonical/lxd/lxd/db/node" -) - -// UpdateSchema updates the schema.go file of the cluster and node databases. -func UpdateSchema(kind string) error { - var err error - switch kind { - case "node": - err = node.SchemaDotGo() - case "cluster": - err = cluster.SchemaDotGo() - default: - return fmt.Errorf(`No such schema kind %q (must be "node", or "cluster")`, kind) - } - - if err != nil { - return fmt.Errorf("Update node database schema: %w", err) - } - - return nil -} From 0042f9711aa4ecea1ea8b43c02dfbdd3d2e72eab Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Fri, 20 Dec 2024 12:17:05 +0000 Subject: [PATCH 3/7] lxd/db/cluster: Immediately run goimports after generating file. Otherwise, when we get to generating the schema (now the generate directive is in the same package) it fails to compile the `cluster` package. Signed-off-by: Mark Laing --- lxd/db/cluster/auth_groups.go | 2 ++ lxd/db/cluster/cluster_groups.go | 3 +++ lxd/db/cluster/config.go | 2 ++ lxd/db/cluster/devices.go | 2 ++ lxd/db/cluster/identities.go | 2 ++ lxd/db/cluster/identity_projects.go | 2 ++ lxd/db/cluster/identity_provider_groups.go | 2 ++ lxd/db/cluster/images.go | 2 ++ lxd/db/cluster/instance_profiles.go | 2 ++ lxd/db/cluster/instances.go | 2 ++ lxd/db/cluster/nodes.go | 2 ++ lxd/db/cluster/nodes_cluster_groups.go | 2 ++ lxd/db/cluster/operations.go | 2 ++ lxd/db/cluster/profiles.go | 2 ++ lxd/db/cluster/projects.go | 2 ++ lxd/db/cluster/snapshots.go | 2 ++ lxd/db/cluster/warnings.go | 2 ++ 17 files changed, 35 insertions(+) diff --git a/lxd/db/cluster/auth_groups.go b/lxd/db/cluster/auth_groups.go index 3e8d59e1827b..ff19b9765330 100644 --- a/lxd/db/cluster/auth_groups.go +++ b/lxd/db/cluster/auth_groups.go @@ -33,6 +33,8 @@ import ( //go:generate mapper method -i -e auth_group DeleteOne-by-Name //go:generate mapper method -i -e auth_group Update //go:generate mapper method -i -e auth_group Rename +//go:generate goimports -w auth_groups.mapper.go +//go:generate goimports -w auth_groups.interface.mapper.go // AuthGroup is the database representation of an api.AuthGroup. type AuthGroup struct { diff --git a/lxd/db/cluster/cluster_groups.go b/lxd/db/cluster/cluster_groups.go index f12a28088143..9e8f522ccdf0 100644 --- a/lxd/db/cluster/cluster_groups.go +++ b/lxd/db/cluster/cluster_groups.go @@ -24,6 +24,9 @@ import ( //go:generate mapper method -i -e cluster_group Update //go:generate mapper method -i -e cluster_group DeleteOne-by-Name +//go:generate goimports -w cluster_groups.mapper.go +//go:generate goimports -w cluster_groups.interface.mapper.go + // ClusterGroup is a value object holding db-related details about a cluster group. type ClusterGroup struct { ID int diff --git a/lxd/db/cluster/config.go b/lxd/db/cluster/config.go index f09c38dc61a0..3b48b903697e 100644 --- a/lxd/db/cluster/config.go +++ b/lxd/db/cluster/config.go @@ -15,6 +15,8 @@ package cluster //go:generate mapper method -i -e config Create struct=Config //go:generate mapper method -i -e config Update struct=Config //go:generate mapper method -i -e config DeleteMany +//go:generate goimports -w config.mapper.go +//go:generate goimports -w config.interface.mapper.go // Config is a reference struct representing one configuration entry of another entity. type Config struct { diff --git a/lxd/db/cluster/devices.go b/lxd/db/cluster/devices.go index 7ba4b8f4b073..69a8074e2d36 100644 --- a/lxd/db/cluster/devices.go +++ b/lxd/db/cluster/devices.go @@ -19,6 +19,8 @@ import ( //go:generate mapper method -i -e device Create struct=Device //go:generate mapper method -i -e device Update struct=Device //go:generate mapper method -i -e device DeleteMany +//go:generate goimports -w devices.mapper.go +//go:generate goimports -w devices.interface.mapper.go // DeviceType represents the types of supported devices. type DeviceType int diff --git a/lxd/db/cluster/identities.go b/lxd/db/cluster/identities.go index 013171d642f4..3346a2e65930 100644 --- a/lxd/db/cluster/identities.go +++ b/lxd/db/cluster/identities.go @@ -51,6 +51,8 @@ import ( //go:generate mapper method -i -e identity DeleteOne-by-AuthMethod-and-Identifier //go:generate mapper method -i -e identity DeleteMany-by-Name-and-Type //go:generate mapper method -i -e identity Update struct=Identity +//go:generate goimports -w identities.mapper.go +//go:generate goimports -w identities.interface.mapper.go // AuthMethod is a database representation of an authentication method. // diff --git a/lxd/db/cluster/identity_projects.go b/lxd/db/cluster/identity_projects.go index 2823cc0d35ef..5c528bced2ad 100644 --- a/lxd/db/cluster/identity_projects.go +++ b/lxd/db/cluster/identity_projects.go @@ -16,6 +16,8 @@ package cluster //go:generate mapper method -i -e identity_project DeleteMany struct=Identity //go:generate mapper method -i -e identity_project Create struct=Identity //go:generate mapper method -i -e identity_project Update struct=Identity +//go:generate goimports -w identity_projects.mapper.go +//go:generate goimports -w identity_projects.interface.mapper.go // IdentityProject is an association table struct that associates // identities to projects. diff --git a/lxd/db/cluster/identity_provider_groups.go b/lxd/db/cluster/identity_provider_groups.go index 57c235793918..c4fa4d4f58f4 100644 --- a/lxd/db/cluster/identity_provider_groups.go +++ b/lxd/db/cluster/identity_provider_groups.go @@ -33,6 +33,8 @@ import ( //go:generate mapper method -i -e identity_provider_group DeleteOne-by-Name //go:generate mapper method -i -e identity_provider_group Update //go:generate mapper method -i -e identity_provider_group Rename +//go:generate goimports -w identity_provider_groups.mapper.go +//go:generate goimports -w identity_provider_groups.interface.mapper.go // IdentityProviderGroup is the database representation of an api.IdentityProviderGroup. type IdentityProviderGroup struct { diff --git a/lxd/db/cluster/images.go b/lxd/db/cluster/images.go index 1aff93593ec5..93c385341be6 100644 --- a/lxd/db/cluster/images.go +++ b/lxd/db/cluster/images.go @@ -23,6 +23,8 @@ import ( // //go:generate mapper method -i -e image GetMany //go:generate mapper method -i -e image GetOne +//go:generate goimports -w images.mapper.go +//go:generate goimports -w images.interface.mapper.go // Image is a value object holding db-related details about an image. type Image struct { diff --git a/lxd/db/cluster/instance_profiles.go b/lxd/db/cluster/instance_profiles.go index 17932cc0b84c..f5f128ac4401 100644 --- a/lxd/db/cluster/instance_profiles.go +++ b/lxd/db/cluster/instance_profiles.go @@ -23,6 +23,8 @@ import ( //go:generate mapper method -i -e instance_profile GetMany struct=Instance //go:generate mapper method -i -e instance_profile Create struct=Instance //go:generate mapper method -i -e instance_profile DeleteMany struct=Instance +//go:generate goimports -w instance_profiles.mapper.go +//go:generate goimports -w instance_profiles.interface.mapper.go // InstanceProfile is an association table struct that associates Instances // to Profiles. diff --git a/lxd/db/cluster/instances.go b/lxd/db/cluster/instances.go index 51dc1ac239e8..2ba877477743 100644 --- a/lxd/db/cluster/instances.go +++ b/lxd/db/cluster/instances.go @@ -49,6 +49,8 @@ import ( //go:generate mapper method -i -e instance Rename //go:generate mapper method -i -e instance DeleteOne-by-Project-and-Name //go:generate mapper method -i -e instance Update references=Config,Device +//go:generate goimports -w instances.mapper.go +//go:generate goimports -w instances.interface.mapper.go // Instance is a value object holding db-related details about an instance. type Instance struct { diff --git a/lxd/db/cluster/nodes.go b/lxd/db/cluster/nodes.go index fe51333fe654..64e7ff81f563 100644 --- a/lxd/db/cluster/nodes.go +++ b/lxd/db/cluster/nodes.go @@ -6,6 +6,8 @@ package cluster //go:generate mapper stmt -e node id // //go:generate mapper method -i -e node ID +//go:generate goimports -w nodes.mapper.go +//go:generate goimports -w nodes.interface.mapper.go // Node represents a LXD cluster node. type Node struct { diff --git a/lxd/db/cluster/nodes_cluster_groups.go b/lxd/db/cluster/nodes_cluster_groups.go index 2c1f6f90577c..1c1021849ef5 100644 --- a/lxd/db/cluster/nodes_cluster_groups.go +++ b/lxd/db/cluster/nodes_cluster_groups.go @@ -11,6 +11,8 @@ package cluster // //go:generate mapper method -e node_cluster_group GetMany //go:generate mapper method -e node_cluster_group DeleteOne-by-GroupID +//go:generate goimports -w nodes_cluster_groups.mapper.go +//go:generate goimports -w nodes_cluster_groups.interface.mapper.go // NodeClusterGroup associates a node to a cluster group. type NodeClusterGroup struct { diff --git a/lxd/db/cluster/operations.go b/lxd/db/cluster/operations.go index bf73958b0e30..c32d2d888ece 100644 --- a/lxd/db/cluster/operations.go +++ b/lxd/db/cluster/operations.go @@ -23,6 +23,8 @@ import ( //go:generate mapper method -i -e operation CreateOrReplace //go:generate mapper method -i -e operation DeleteOne-by-UUID //go:generate mapper method -i -e operation DeleteMany-by-NodeID +//go:generate goimports -w operations.mapper.go +//go:generate goimports -w operations.interface.mapper.go // Operation holds information about a single LXD operation running on a node // in the cluster. diff --git a/lxd/db/cluster/profiles.go b/lxd/db/cluster/profiles.go index 9f05eabac2f4..fe6dd1b9ef2d 100644 --- a/lxd/db/cluster/profiles.go +++ b/lxd/db/cluster/profiles.go @@ -33,6 +33,8 @@ import ( //go:generate mapper method -i -e profile Rename //go:generate mapper method -i -e profile Update references=Config,Device //go:generate mapper method -i -e profile DeleteOne-by-Project-and-Name +//go:generate goimports -w profiles.mapper.go +//go:generate goimports -w profiles.interface.mapper.go // Profile is a value object holding db-related details about a profile. type Profile struct { diff --git a/lxd/db/cluster/projects.go b/lxd/db/cluster/projects.go index b29d71283e54..e9e44813845c 100644 --- a/lxd/db/cluster/projects.go +++ b/lxd/db/cluster/projects.go @@ -33,6 +33,8 @@ import ( //go:generate mapper method -i -e project ID struct=Project //go:generate mapper method -i -e project Rename //go:generate mapper method -i -e project DeleteOne-by-Name +//go:generate goimports -w projects.mapper.go +//go:generate goimports -w projects.interface.mapper.go // ProjectFeature indicates the behaviour of a project feature. type ProjectFeature struct { diff --git a/lxd/db/cluster/snapshots.go b/lxd/db/cluster/snapshots.go index 8d90a91f7570..ab69ba17421a 100644 --- a/lxd/db/cluster/snapshots.go +++ b/lxd/db/cluster/snapshots.go @@ -31,6 +31,8 @@ import ( //go:generate mapper method -i -e instance_snapshot Create references=Config,Device //go:generate mapper method -i -e instance_snapshot Rename //go:generate mapper method -i -e instance_snapshot DeleteOne-by-Project-and-Instance-and-Name +//go:generate goimports -w snapshots.mapper.go +//go:generate goimports -w snapshots.interface.mapper.go // InstanceSnapshot is a value object holding db-related details about a snapshot. type InstanceSnapshot struct { diff --git a/lxd/db/cluster/warnings.go b/lxd/db/cluster/warnings.go index 47123ed3fbd5..9198f145e16d 100644 --- a/lxd/db/cluster/warnings.go +++ b/lxd/db/cluster/warnings.go @@ -32,6 +32,8 @@ import ( //go:generate mapper method -i -e warning DeleteMany-by-EntityType-and-EntityID //go:generate mapper method -i -e warning ID //go:generate mapper method -i -e warning Exists struct=Warning +//go:generate goimports -w warnings.mapper.go +//go:generate goimports -w warnings.interface.mapper.go // Warning is a value object holding db-related details about a warning. type Warning struct { From fabd0b3b273b25ae14315894343c7fba02c0cc86 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Fri, 20 Dec 2024 12:17:34 +0000 Subject: [PATCH 4/7] lxd/db/cluster: Update schema generation to use `freshschema` package. Signed-off-by: Mark Laing --- lxd/db/cluster/update.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go index 1885b71199ef..e5fc42dcf841 100644 --- a/lxd/db/cluster/update.go +++ b/lxd/db/cluster/update.go @@ -1,6 +1,8 @@ package cluster -//go:generate lxd-generate db schema cluster +// Have to run goimports first because the .mapper files are being generated at the same time. +// This causes "freshschema" to be unable to import the cluster package. +//go:generate go run ../freshschema/main.go cluster import ( "context" From 09790e4b15ec7624e383773db0be20d743c57ac0 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Fri, 20 Dec 2024 12:17:41 +0000 Subject: [PATCH 5/7] lxd/db/node: Update schema generation to use `freshschema` package. Signed-off-by: Mark Laing --- lxd/db/node/update.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/db/node/update.go b/lxd/db/node/update.go index 241fed093afb..a83be0af674b 100644 --- a/lxd/db/node/update.go +++ b/lxd/db/node/update.go @@ -1,6 +1,6 @@ package node -//go:generate lxd-generate db schema node +//go:generate go run ../freshschema/main.go node import ( "context" From 68be07b57ef0546cbe746ca3e9016bf5289cf82e Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Fri, 20 Dec 2024 12:18:29 +0000 Subject: [PATCH 6/7] Makefile: Remove goimports from `update-schema` target. This is no longer necessary as the files are updated as they are generated. Signed-off-by: Mark Laing --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 6e86a2657ac7..0611dd78708e 100644 --- a/Makefile +++ b/Makefile @@ -148,7 +148,6 @@ ifeq ($(shell command -v goimports),) endif cd lxd/db/generate && go build -v -trimpath -o $(GOPATH)/bin/lxd-generate -tags "$(TAG_SQLITE3)" $(DEBUG) && cd - go generate ./... - goimports -w ./lxd/db/ @echo "Code generation completed" .PHONY: update-api From 65893b9a6c01b1119abb5058f8d7545c82874426 Mon Sep 17 00:00:00 2001 From: Mark Laing Date: Fri, 20 Dec 2024 12:22:00 +0000 Subject: [PATCH 7/7] lxd/db/cluster: Fix linter error (prealloc). Signed-off-by: Mark Laing --- lxd/db/cluster/identity_provider_groups.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lxd/db/cluster/identity_provider_groups.go b/lxd/db/cluster/identity_provider_groups.go index c4fa4d4f58f4..949c3682f41d 100644 --- a/lxd/db/cluster/identity_provider_groups.go +++ b/lxd/db/cluster/identity_provider_groups.go @@ -148,7 +148,7 @@ func GetDistinctAuthGroupNamesFromIDPGroupNames(ctx context.Context, tx *sql.Tx, return nil, nil } - var args []any + args := make([]any, 0, len(idpGroupNames)) for _, idpGroupName := range idpGroupNames { args = append(args, idpGroupName) }