[lxc-devel] [lxd/master] Rename containers db tables

freeekanayaka on Github lxc-bot at linuxcontainers.org
Tue Aug 13 11:27:51 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 827 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190813/8bec21c5/attachment-0001.bin>
-------------- next part --------------
From cb02036759d42113fc898d3833874830f9fa04d7 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 10:58:21 +0200
Subject: [PATCH 01/11] Fix failing unit test

---
 lxd/db/cluster/open_test.go | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/lxd/db/cluster/open_test.go b/lxd/db/cluster/open_test.go
index 2b74fa3094..bdf5505bc4 100644
--- a/lxd/db/cluster/open_test.go
+++ b/lxd/db/cluster/open_test.go
@@ -3,6 +3,9 @@ package cluster_test
 import (
 	"database/sql"
 	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
 	"testing"
 
 	"github.com/lxc/lxd/lxd/db/cluster"
@@ -15,9 +18,12 @@ import (
 
 // If the node is not clustered, the schema updates works normally.
 func TestEnsureSchema_NoClustered(t *testing.T) {
+	dir, cleanup := newDir(t)
+	defer cleanup()
+	assert.NoError(t, os.Mkdir(filepath.Join(dir, "global"), 0711))
 	db := newDB(t)
 	addNode(t, db, "0.0.0.0", 1, 1)
-	ready, err := cluster.EnsureSchema(db, "1.2.3.4:666", "/unused/db/dir")
+	ready, err := cluster.EnsureSchema(db, "1.2.3.4:666", dir)
 	assert.True(t, ready)
 	assert.NoError(t, err)
 }
@@ -179,3 +185,22 @@ func assertNode(t *testing.T, db *sql.DB, address string, schema int, apiExtensi
 	})
 	require.NoError(t, err)
 }
+
+// Return a new temporary directory.
+func newDir(t *testing.T) (string, func()) {
+	t.Helper()
+
+	dir, err := ioutil.TempDir("", "dqlite-replication-test-")
+	assert.NoError(t, err)
+
+	cleanup := func() {
+		_, err := os.Stat(dir)
+		if err != nil {
+			assert.True(t, os.IsNotExist(err))
+		} else {
+			assert.NoError(t, os.RemoveAll(dir))
+		}
+	}
+
+	return dir, cleanup
+}

From 7a1560d728fcaa85efb3d1458ab3a6c5fab5f5b7 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 10:58:48 +0200
Subject: [PATCH 02/11] Add schema update function to rename containers-related
 tables

---
 lxd/db/cluster/update.go      | 99 +++++++++++++++++++++++++++++++++++
 lxd/db/cluster/update_test.go | 29 ++++++++++
 2 files changed, 128 insertions(+)

diff --git a/lxd/db/cluster/update.go b/lxd/db/cluster/update.go
index 5b730e7c56..cb1b9e90d2 100644
--- a/lxd/db/cluster/update.go
+++ b/lxd/db/cluster/update.go
@@ -47,6 +47,105 @@ var updates = map[int]schema.Update{
 	12: updateFromV11,
 	13: updateFromV12,
 	14: updateFromV13,
+	15: updateFromV14,
+}
+
+// Rename all containers* tables to instances*/
+func updateFromV14(tx *sql.Tx) error {
+	stmts := `
+ALTER TABLE containers RENAME TO instances;
+ALTER TABLE containers_backups RENAME COLUMN container_id TO instance_id;
+ALTER TABLE containers_backups RENAME TO instances_backups;
+ALTER TABLE containers_config RENAME COLUMN container_id TO instance_id;
+ALTER TABLE containers_config RENAME TO instances_config;
+DROP VIEW containers_config_ref;
+CREATE VIEW instances_config_ref (project,
+    node,
+    name,
+    key,
+    value) AS
+   SELECT projects.name,
+    nodes.name,
+    instances.name,
+    instances_config.key,
+    instances_config.value
+     FROM instances_config
+       JOIN instances ON instances.id=instances_config.instance_id
+       JOIN projects ON projects.id=instances.project_id
+       JOIN nodes ON nodes.id=instances.node_id;
+ALTER TABLE containers_devices RENAME COLUMN container_id TO instance_id;
+ALTER TABLE containers_devices RENAME TO instances_devices;
+ALTER TABLE containers_devices_config RENAME COLUMN container_device_id TO instance_device_id;
+ALTER TABLE containers_devices_config RENAME TO instances_devices_config;
+DROP VIEW containers_devices_ref;
+CREATE VIEW instances_devices_ref (project,
+    node,
+    name,
+    device,
+    type,
+    key,
+    value) AS
+   SELECT projects.name,
+    nodes.name,
+    instances.name,
+          instances_devices.name,
+    instances_devices.type,
+          coalesce(instances_devices_config.key,
+    ''),
+    coalesce(instances_devices_config.value,
+    '')
+   FROM instances_devices
+     LEFT OUTER JOIN instances_devices_config ON instances_devices_config.instance_device_id=instances_devices.id
+     JOIN instances ON instances.id=instances_devices.instance_id
+     JOIN projects ON projects.id=instances.project_id
+     JOIN nodes ON nodes.id=instances.node_id;
+DROP INDEX containers_node_id_idx;
+CREATE INDEX instances_node_id_idx ON instances (node_id);
+ALTER TABLE containers_profiles RENAME COLUMN container_id TO instance_id;
+ALTER TABLE containers_profiles RENAME TO instances_profiles;
+DROP VIEW containers_profiles_ref;
+CREATE VIEW instances_profiles_ref (project,
+    node,
+    name,
+    value) AS
+   SELECT projects.name,
+    nodes.name,
+    instances.name,
+    profiles.name
+     FROM instances_profiles
+       JOIN instances ON instances.id=instances_profiles.instance_id
+       JOIN profiles ON profiles.id=instances_profiles.profile_id
+       JOIN projects ON projects.id=instances.project_id
+       JOIN nodes ON nodes.id=instances.node_id
+     ORDER BY instances_profiles.apply_order;
+DROP INDEX containers_project_id_and_name_idx;
+DROP INDEX containers_project_id_and_node_id_and_name_idx;
+DROP INDEX containers_project_id_and_node_id_idx;
+DROP INDEX containers_project_id_idx;
+CREATE INDEX instances_project_id_and_name_idx ON instances (project_id, name);
+CREATE INDEX instances_project_id_and_node_id_and_name_idx ON instances (project_id, node_id, name);
+CREATE INDEX instances_project_id_and_node_id_idx ON instances (project_id, node_id);
+CREATE INDEX instances_project_id_idx ON instances (project_id);
+DROP VIEW profiles_used_by_ref;
+CREATE VIEW profiles_used_by_ref (project,
+    name,
+    value) AS
+  SELECT projects.name,
+    profiles.name,
+    printf('/1.0/containers/%s?project=%s',
+    "instances".name,
+    instances_projects.name)
+    FROM profiles
+    JOIN projects ON projects.id=profiles.project_id
+    JOIN "instances_profiles"
+      ON "instances_profiles".profile_id=profiles.id
+    JOIN "instances"
+      ON "instances".id="instances_profiles".instance_id
+    JOIN projects AS instances_projects
+      ON instances_projects.id="instances".project_id;
+`
+	_, err := tx.Exec(stmts)
+	return err
 }
 
 func updateFromV13(tx *sql.Tx) error {
diff --git a/lxd/db/cluster/update_test.go b/lxd/db/cluster/update_test.go
index 8ce8f28b4b..cb44981e23 100644
--- a/lxd/db/cluster/update_test.go
+++ b/lxd/db/cluster/update_test.go
@@ -461,3 +461,32 @@ INSERT INTO containers VALUES (4, 1, 'xenial', 1, 1, 0, ?, 0, ?, 'Xenial Xerus',
 `, time.Now(), time.Now())
 	assert.EqualError(t, err, "UNIQUE constraint failed: containers.project_id, containers.name")
 }
+
+func TestUpdateFromV14(t *testing.T) {
+	schema := cluster.Schema()
+	db, err := schema.ExerciseUpdate(15, func(db *sql.DB) {
+		// Insert a node.
+		_, err := db.Exec(
+			"INSERT INTO nodes VALUES (1, 'n1', '', '1.2.3.4:666', 1, 32, ?, 0)",
+			time.Now())
+		require.NoError(t, err)
+
+		// Insert a container.
+		_, err = db.Exec(`
+INSERT INTO containers VALUES (1, 1, 'eoan', 1, 1, 0, ?, 0, ?, 'Eoan Ermine', 1, NULL)
+`, time.Now(), time.Now())
+		require.NoError(t, err)
+	})
+
+	require.NoError(t, err)
+
+	tx, err := db.Begin()
+	require.NoError(t, err)
+
+	defer tx.Rollback()
+
+	// Check that the new instances table can be queried.
+	count, err := query.Count(tx, "instances", "")
+	require.NoError(t, err)
+	assert.Equal(t, 1, count)
+}

From 59ee8a962941dfe9e77da26f92b29750499ccf22 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 10:59:14 +0200
Subject: [PATCH 03/11] Regenerate global db schema

---
 lxd/db/cluster/schema.go | 236 +++++++++++++++++++--------------------
 1 file changed, 118 insertions(+), 118 deletions(-)

diff --git a/lxd/db/cluster/schema.go b/lxd/db/cluster/schema.go
index 5f48acbd2b..63fef9a8fa 100644
--- a/lxd/db/cluster/schema.go
+++ b/lxd/db/cluster/schema.go
@@ -20,7 +20,61 @@ CREATE TABLE config (
     value TEXT,
     UNIQUE (key)
 );
-CREATE TABLE "containers" (
+CREATE TABLE "images" (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    fingerprint TEXT NOT NULL,
+    filename TEXT NOT NULL,
+    size INTEGER NOT NULL,
+    public INTEGER NOT NULL DEFAULT 0,
+    architecture INTEGER NOT NULL,
+    creation_date DATETIME,
+    expiry_date DATETIME,
+    upload_date DATETIME NOT NULL,
+    cached INTEGER NOT NULL DEFAULT 0,
+    last_use_date DATETIME,
+    auto_update INTEGER NOT NULL DEFAULT 0,
+    project_id INTEGER NOT NULL,
+    UNIQUE (project_id, fingerprint),
+    FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
+);
+CREATE TABLE "images_aliases" (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    name TEXT NOT NULL,
+    image_id INTEGER NOT NULL,
+    description TEXT,
+    project_id INTEGER NOT NULL,
+    UNIQUE (project_id, name),
+    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE,
+    FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
+);
+CREATE INDEX images_aliases_project_id_idx ON images_aliases (project_id);
+CREATE TABLE images_nodes (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    image_id INTEGER NOT NULL,
+    node_id INTEGER NOT NULL,
+    UNIQUE (image_id, node_id),
+    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE,
+    FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE
+);
+CREATE INDEX images_project_id_idx ON images (project_id);
+CREATE TABLE images_properties (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    image_id INTEGER NOT NULL,
+    type INTEGER NOT NULL,
+    key TEXT NOT NULL,
+    value TEXT,
+    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE
+);
+CREATE TABLE images_source (
+    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+    image_id INTEGER NOT NULL,
+    server TEXT NOT NULL,
+    protocol INTEGER NOT NULL,
+    certificate TEXT NOT NULL,
+    alias TEXT NOT NULL,
+    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE
+);
+CREATE TABLE "instances" (
     id INTEGER primary key AUTOINCREMENT NOT NULL,
     node_id INTEGER NOT NULL,
     name TEXT NOT NULL,
@@ -37,56 +91,56 @@ CREATE TABLE "containers" (
     FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE,
     FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
 );
-CREATE TABLE containers_backups (
+CREATE TABLE "instances_backups" (
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    container_id INTEGER NOT NULL,
+    instance_id INTEGER NOT NULL,
     name VARCHAR(255) NOT NULL,
     creation_date DATETIME,
     expiry_date DATETIME,
     container_only INTEGER NOT NULL default 0,
     optimized_storage INTEGER NOT NULL default 0,
-    FOREIGN KEY (container_id) REFERENCES containers (id) ON DELETE CASCADE,
-    UNIQUE (container_id, name)
+    FOREIGN KEY (instance_id) REFERENCES "instances" (id) ON DELETE CASCADE,
+    UNIQUE (instance_id, name)
 );
-CREATE TABLE containers_config (
+CREATE TABLE "instances_config" (
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    container_id INTEGER NOT NULL,
+    instance_id INTEGER NOT NULL,
     key TEXT NOT NULL,
     value TEXT,
-    FOREIGN KEY (container_id) REFERENCES containers (id) ON DELETE CASCADE,
-    UNIQUE (container_id, key)
+    FOREIGN KEY (instance_id) REFERENCES "instances" (id) ON DELETE CASCADE,
+    UNIQUE (instance_id, key)
 );
-CREATE VIEW containers_config_ref (project,
+CREATE VIEW instances_config_ref (project,
     node,
     name,
     key,
     value) AS
    SELECT projects.name,
     nodes.name,
-    containers.name,
-    containers_config.key,
-    containers_config.value
-     FROM containers_config
-       JOIN containers ON containers.id=containers_config.container_id
-       JOIN projects ON projects.id=containers.project_id
-       JOIN nodes ON nodes.id=containers.node_id;
-CREATE TABLE containers_devices (
+    instances.name,
+    instances_config.key,
+    instances_config.value
+     FROM instances_config
+       JOIN instances ON instances.id=instances_config.instance_id
+       JOIN projects ON projects.id=instances.project_id
+       JOIN nodes ON nodes.id=instances.node_id;
+CREATE TABLE "instances_devices" (
     id INTEGER primary key AUTOINCREMENT NOT NULL,
-    container_id INTEGER NOT NULL,
+    instance_id INTEGER NOT NULL,
     name TEXT NOT NULL,
     type INTEGER NOT NULL default 0,
-    FOREIGN KEY (container_id) REFERENCES containers (id) ON DELETE CASCADE,
-    UNIQUE (container_id, name)
+    FOREIGN KEY (instance_id) REFERENCES "instances" (id) ON DELETE CASCADE,
+    UNIQUE (instance_id, name)
 );
-CREATE TABLE containers_devices_config (
+CREATE TABLE "instances_devices_config" (
     id INTEGER primary key AUTOINCREMENT NOT NULL,
-    container_device_id INTEGER NOT NULL,
+    instance_device_id INTEGER NOT NULL,
     key TEXT NOT NULL,
     value TEXT,
-    FOREIGN KEY (container_device_id) REFERENCES containers_devices (id) ON DELETE CASCADE,
-    UNIQUE (container_device_id, key)
+    FOREIGN KEY (instance_device_id) REFERENCES "instances_devices" (id) ON DELETE CASCADE,
+    UNIQUE (instance_device_id, key)
 );
-CREATE VIEW containers_devices_ref (project,
+CREATE VIEW instances_devices_ref (project,
     node,
     name,
     device,
@@ -95,104 +149,50 @@ CREATE VIEW containers_devices_ref (project,
     value) AS
    SELECT projects.name,
     nodes.name,
-    containers.name,
-          containers_devices.name,
-    containers_devices.type,
-          coalesce(containers_devices_config.key,
+    instances.name,
+          instances_devices.name,
+    instances_devices.type,
+          coalesce(instances_devices_config.key,
     ''),
-    coalesce(containers_devices_config.value,
+    coalesce(instances_devices_config.value,
     '')
-   FROM containers_devices
-     LEFT OUTER JOIN containers_devices_config ON containers_devices_config.container_device_id=containers_devices.id
-     JOIN containers ON containers.id=containers_devices.container_id
-     JOIN projects ON projects.id=containers.project_id
-     JOIN nodes ON nodes.id=containers.node_id;
-CREATE INDEX containers_node_id_idx ON containers (node_id);
-CREATE TABLE containers_profiles (
+   FROM instances_devices
+     LEFT OUTER JOIN instances_devices_config ON instances_devices_config.instance_device_id=instances_devices.id
+     JOIN instances ON instances.id=instances_devices.instance_id
+     JOIN projects ON projects.id=instances.project_id
+     JOIN nodes ON nodes.id=instances.node_id;
+CREATE INDEX instances_node_id_idx ON instances (node_id);
+CREATE TABLE "instances_profiles" (
     id INTEGER primary key AUTOINCREMENT NOT NULL,
-    container_id INTEGER NOT NULL,
+    instance_id INTEGER NOT NULL,
     profile_id INTEGER NOT NULL,
     apply_order INTEGER NOT NULL default 0,
-    UNIQUE (container_id, profile_id),
-    FOREIGN KEY (container_id) REFERENCES containers(id) ON DELETE CASCADE,
+    UNIQUE (instance_id, profile_id),
+    FOREIGN KEY (instance_id) REFERENCES "instances"(id) ON DELETE CASCADE,
     FOREIGN KEY (profile_id) REFERENCES profiles(id) ON DELETE CASCADE
 );
-CREATE VIEW containers_profiles_ref (project,
+CREATE VIEW instances_profiles_ref (project,
     node,
     name,
     value) AS
    SELECT projects.name,
     nodes.name,
-    containers.name,
+    instances.name,
     profiles.name
-     FROM containers_profiles
-       JOIN containers ON containers.id=containers_profiles.container_id
-       JOIN profiles ON profiles.id=containers_profiles.profile_id
-       JOIN projects ON projects.id=containers.project_id
-       JOIN nodes ON nodes.id=containers.node_id
-     ORDER BY containers_profiles.apply_order;
-CREATE INDEX containers_project_id_and_name_idx ON containers (project_id,
+     FROM instances_profiles
+       JOIN instances ON instances.id=instances_profiles.instance_id
+       JOIN profiles ON profiles.id=instances_profiles.profile_id
+       JOIN projects ON projects.id=instances.project_id
+       JOIN nodes ON nodes.id=instances.node_id
+     ORDER BY instances_profiles.apply_order;
+CREATE INDEX instances_project_id_and_name_idx ON instances (project_id,
     name);
-CREATE INDEX containers_project_id_and_node_id_and_name_idx ON containers (project_id,
+CREATE INDEX instances_project_id_and_node_id_and_name_idx ON instances (project_id,
     node_id,
     name);
-CREATE INDEX containers_project_id_and_node_id_idx ON containers (project_id,
+CREATE INDEX instances_project_id_and_node_id_idx ON instances (project_id,
     node_id);
-CREATE INDEX containers_project_id_idx ON containers (project_id);
-CREATE TABLE "images" (
-    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    fingerprint TEXT NOT NULL,
-    filename TEXT NOT NULL,
-    size INTEGER NOT NULL,
-    public INTEGER NOT NULL DEFAULT 0,
-    architecture INTEGER NOT NULL,
-    creation_date DATETIME,
-    expiry_date DATETIME,
-    upload_date DATETIME NOT NULL,
-    cached INTEGER NOT NULL DEFAULT 0,
-    last_use_date DATETIME,
-    auto_update INTEGER NOT NULL DEFAULT 0,
-    project_id INTEGER NOT NULL,
-    UNIQUE (project_id, fingerprint),
-    FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
-);
-CREATE TABLE "images_aliases" (
-    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    name TEXT NOT NULL,
-    image_id INTEGER NOT NULL,
-    description TEXT,
-    project_id INTEGER NOT NULL,
-    UNIQUE (project_id, name),
-    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE,
-    FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE
-);
-CREATE INDEX images_aliases_project_id_idx ON images_aliases (project_id);
-CREATE TABLE images_nodes (
-    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    image_id INTEGER NOT NULL,
-    node_id INTEGER NOT NULL,
-    UNIQUE (image_id, node_id),
-    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE,
-    FOREIGN KEY (node_id) REFERENCES nodes (id) ON DELETE CASCADE
-);
-CREATE INDEX images_project_id_idx ON images (project_id);
-CREATE TABLE images_properties (
-    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    image_id INTEGER NOT NULL,
-    type INTEGER NOT NULL,
-    key TEXT NOT NULL,
-    value TEXT,
-    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE
-);
-CREATE TABLE images_source (
-    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
-    image_id INTEGER NOT NULL,
-    server TEXT NOT NULL,
-    protocol INTEGER NOT NULL,
-    certificate TEXT NOT NULL,
-    alias TEXT NOT NULL,
-    FOREIGN KEY (image_id) REFERENCES images (id) ON DELETE CASCADE
-);
+CREATE INDEX instances_project_id_idx ON instances (project_id);
 CREATE TABLE networks (
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
     name TEXT NOT NULL,
@@ -308,16 +308,16 @@ CREATE VIEW profiles_used_by_ref (project,
   SELECT projects.name,
     profiles.name,
     printf('/1.0/containers/%s?project=%s',
-    containers.name,
-    containers_projects.name)
+    "instances".name,
+    instances_projects.name)
     FROM profiles
     JOIN projects ON projects.id=profiles.project_id
-    JOIN containers_profiles
-      ON containers_profiles.profile_id=profiles.id
-    JOIN containers
-      ON containers.id=containers_profiles.container_id
-    JOIN projects AS containers_projects
-      ON containers_projects.id=containers.project_id;
+    JOIN "instances_profiles"
+      ON "instances_profiles".profile_id=profiles.id
+    JOIN "instances"
+      ON "instances".id="instances_profiles".instance_id
+    JOIN projects AS instances_projects
+      ON instances_projects.id="instances".project_id;
 CREATE TABLE projects (
     id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
     name TEXT NOT NULL,
@@ -344,9 +344,9 @@ CREATE VIEW projects_used_by_ref (name,
     value) AS
   SELECT projects.name,
     printf('/1.0/containers/%s?project=%s',
-    containers.name,
+    "instances".name,
     projects.name)
-    FROM containers JOIN projects ON project_id=projects.id UNION
+    FROM "instances" JOIN projects ON project_id=projects.id UNION
   SELECT projects.name,
     printf('/1.0/images/%s',
     images.fingerprint)
@@ -405,5 +405,5 @@ CREATE TABLE storage_volumes_config (
     FOREIGN KEY (storage_volume_id) REFERENCES storage_volumes (id) ON DELETE CASCADE
 );
 
-INSERT INTO schema (version, updated_at) VALUES (14, strftime("%s"))
+INSERT INTO schema (version, updated_at) VALUES (15, strftime("%s"))
 `

From 94b7261100381e117717524124b17dcc3c471930 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 11:29:48 +0200
Subject: [PATCH 04/11] Replace references to the "containers" table with
 "instances"

---
 lxd/db/containers.go       | 310 ++++++++++++++++++++-----------------
 lxd/db/db_internal_test.go |  24 +--
 lxd/db/devices.go          |  12 +-
 lxd/db/profiles.go         |  10 +-
 4 files changed, 192 insertions(+), 164 deletions(-)

diff --git a/lxd/db/containers.go b/lxd/db/containers.go
index 3d11bd4537..8b55bb8620 100644
--- a/lxd/db/containers.go
+++ b/lxd/db/containers.go
@@ -19,49 +19,49 @@ import (
 
 // Code generation directives.
 //
-//go:generate -command mapper lxd-generate db mapper -t containers.mapper.go
+//go:generate -command mapper lxd-generate db mapper -t instances.mapper.go
 //go:generate mapper reset
 //
-//go:generate mapper stmt -p db -e container objects
-//go:generate mapper stmt -p db -e container objects-by-Type
-//go:generate mapper stmt -p db -e container objects-by-Project-and-Type
-//go:generate mapper stmt -p db -e container objects-by-Project-and-Type-and-Parent
-//go:generate mapper stmt -p db -e container objects-by-Node-and-Type
-//go:generate mapper stmt -p db -e container objects-by-Project-and-Node-and-Type
-//go:generate mapper stmt -p db -e container objects-by-Project-and-Name
-//go:generate mapper stmt -p db -e container objects-by-Project-and-Name-and-Type
-//go:generate mapper stmt -p db -e container profiles-ref
-//go:generate mapper stmt -p db -e container profiles-ref-by-Project
-//go:generate mapper stmt -p db -e container profiles-ref-by-Node
-//go:generate mapper stmt -p db -e container profiles-ref-by-Project-and-Node
-//go:generate mapper stmt -p db -e container profiles-ref-by-Project-and-Name
-//go:generate mapper stmt -p db -e container config-ref
-//go:generate mapper stmt -p db -e container config-ref-by-Project
-//go:generate mapper stmt -p db -e container config-ref-by-Node
-//go:generate mapper stmt -p db -e container config-ref-by-Project-and-Node
-//go:generate mapper stmt -p db -e container config-ref-by-Project-and-Name
-//go:generate mapper stmt -p db -e container devices-ref
-//go:generate mapper stmt -p db -e container devices-ref-by-Project
-//go:generate mapper stmt -p db -e container devices-ref-by-Node
-//go:generate mapper stmt -p db -e container devices-ref-by-Project-and-Node
-//go:generate mapper stmt -p db -e container devices-ref-by-Project-and-Name
-//go:generate mapper stmt -p db -e container id
-//go:generate mapper stmt -p db -e container create struct=Container
-//go:generate mapper stmt -p db -e container create-config-ref
-//go:generate mapper stmt -p db -e container create-devices-ref
-//go:generate mapper stmt -p db -e container rename
-//go:generate mapper stmt -p db -e container delete
+//go:generate mapper stmt -p db -e instance objects
+//go:generate mapper stmt -p db -e instance objects-by-Type
+//go:generate mapper stmt -p db -e instance objects-by-Project-and-Type
+//go:generate mapper stmt -p db -e instance objects-by-Project-and-Type-and-Parent
+//go:generate mapper stmt -p db -e instance objects-by-Node-and-Type
+//go:generate mapper stmt -p db -e instance objects-by-Project-and-Node-and-Type
+//go:generate mapper stmt -p db -e instance objects-by-Project-and-Name
+//go:generate mapper stmt -p db -e instance objects-by-Project-and-Name-and-Type
+//go:generate mapper stmt -p db -e instance profiles-ref
+//go:generate mapper stmt -p db -e instance profiles-ref-by-Project
+//go:generate mapper stmt -p db -e instance profiles-ref-by-Node
+//go:generate mapper stmt -p db -e instance profiles-ref-by-Project-and-Node
+//go:generate mapper stmt -p db -e instance profiles-ref-by-Project-and-Name
+//go:generate mapper stmt -p db -e instance config-ref
+//go:generate mapper stmt -p db -e instance config-ref-by-Project
+//go:generate mapper stmt -p db -e instance config-ref-by-Node
+//go:generate mapper stmt -p db -e instance config-ref-by-Project-and-Node
+//go:generate mapper stmt -p db -e instance config-ref-by-Project-and-Name
+//go:generate mapper stmt -p db -e instance devices-ref
+//go:generate mapper stmt -p db -e instance devices-ref-by-Project
+//go:generate mapper stmt -p db -e instance devices-ref-by-Node
+//go:generate mapper stmt -p db -e instance devices-ref-by-Project-and-Node
+//go:generate mapper stmt -p db -e instance devices-ref-by-Project-and-Name
+//go:generate mapper stmt -p db -e instance id
+//go:generate mapper stmt -p db -e instance create struct=Instance
+//go:generate mapper stmt -p db -e instance create-config-ref
+//go:generate mapper stmt -p db -e instance create-devices-ref
+//go:generate mapper stmt -p db -e instance rename
+//go:generate mapper stmt -p db -e instance delete
 //
-//go:generate mapper method -p db -e container List
-//go:generate mapper method -p db -e container Get
-//go:generate mapper method -p db -e container ID struct=Container
-//go:generate mapper method -p db -e container Exists struct=Container
-//go:generate mapper method -p db -e container Create struct=Container
-//go:generate mapper method -p db -e container ProfilesRef
-//go:generate mapper method -p db -e container ConfigRef
-//go:generate mapper method -p db -e container DevicesRef
-//go:generate mapper method -p db -e container Rename
-//go:generate mapper method -p db -e container Delete
+//go:generate mapper method -p db -e instance List
+//go:generate mapper method -p db -e instance Get
+//go:generate mapper method -p db -e instance ID struct=Instance
+//go:generate mapper method -p db -e instance Exists struct=Instance
+//go:generate mapper method -p db -e instance Create struct=Instance
+//go:generate mapper method -p db -e instance ProfilesRef
+//go:generate mapper method -p db -e instance ConfigRef
+//go:generate mapper method -p db -e instance DevicesRef
+//go:generate mapper method -p db -e instance Rename
+//go:generate mapper method -p db -e instance Delete
 
 // Container is a value object holding db-related details about a container.
 type Container struct {
@@ -91,6 +91,34 @@ type ContainerFilter struct {
 	Type    int
 }
 
+// Instance is a value object holding db-related details about a container.
+type Instance struct {
+	ID           int
+	Project      string `db:"primary=yes&join=projects.name"`
+	Name         string `db:"primary=yes"`
+	Node         string `db:"join=nodes.name"`
+	Type         int
+	Architecture int
+	Ephemeral    bool
+	CreationDate time.Time
+	Stateful     bool
+	LastUseDate  time.Time
+	Description  string `db:"coalesce=''"`
+	Config       map[string]string
+	Devices      map[string]map[string]string
+	Profiles     []string
+	ExpiryDate   time.Time
+}
+
+// InstanceFilter can be used to filter results yielded by ContainerList.
+type InstanceFilter struct {
+	Project string
+	Name    string
+	Node    string
+	Parent  string
+	Type    int
+}
+
 // ContainerToArgs is a convenience to convert the new Container db struct into
 // the legacy ContainerArgs.
 func ContainerToArgs(container *Container) ContainerArgs {
@@ -170,9 +198,9 @@ const (
 // ContainerNames returns the names of all containers the given project.
 func (c *ClusterTx) ContainerNames(project string) ([]string, error) {
 	stmt := `
-SELECT containers.name FROM containers
-  JOIN projects ON projects.id = containers.project_id
-  WHERE projects.name = ? AND containers.type = ?
+SELECT instances.name FROM instances
+  JOIN projects ON projects.id = instances.project_id
+  WHERE projects.name = ? AND instances.type = ?
 `
 	return query.SelectStrings(c.tx, stmt, project, CTypeRegular)
 }
@@ -185,9 +213,9 @@ func (c *ClusterTx) ContainerNodeAddress(project string, name string) (string, e
 	stmt := `
 SELECT nodes.id, nodes.address
   FROM nodes
-  JOIN containers ON containers.node_id = nodes.id
-  JOIN projects ON projects.id = containers.project_id
- WHERE projects.name = ? AND containers.name = ?
+  JOIN instances ON instances.node_id = nodes.id
+  JOIN projects ON projects.id = instances.project_id
+ WHERE projects.name = ? AND instances.name = ?
 `
 	var address string
 	var id int64
@@ -236,13 +264,13 @@ func (c *ClusterTx) ContainersListByNodeAddress(project string) (map[string][]st
 	}
 
 	stmt := `
-SELECT containers.name, nodes.id, nodes.address, nodes.heartbeat
-  FROM containers
-  JOIN nodes ON nodes.id = containers.node_id
-  JOIN projects ON projects.id = containers.project_id
-  WHERE containers.type=?
+SELECT instances.name, nodes.id, nodes.address, nodes.heartbeat
+  FROM instances
+  JOIN nodes ON nodes.id = instances.node_id
+  JOIN projects ON projects.id = instances.project_id
+  WHERE instances.type=?
     AND projects.name = ?
-  ORDER BY containers.id
+  ORDER BY instances.id
 `
 	rows, err := c.tx.Query(stmt, CTypeRegular, project)
 	if err != nil {
@@ -278,8 +306,8 @@ SELECT containers.name, nodes.id, nodes.address, nodes.heartbeat
 
 // ContainerListExpanded loads all containers across all projects and expands
 // their config and devices using the profiles they are associated to.
-func (c *ClusterTx) ContainerListExpanded() ([]Container, error) {
-	containers, err := c.ContainerList(ContainerFilter{})
+func (c *ClusterTx) ContainerListExpanded() ([]Instance, error) {
+	instances, err := c.InstanceList(InstanceFilter{})
 	if err != nil {
 		return nil, errors.Wrap(err, "Load containers")
 	}
@@ -300,29 +328,29 @@ func (c *ClusterTx) ContainerListExpanded() ([]Container, error) {
 		profilesByName[profile.Name] = profile
 	}
 
-	for i, container := range containers {
-		profiles := make([]api.Profile, len(container.Profiles))
-		for j, name := range container.Profiles {
-			profile := profilesByProjectAndName[container.Project][name]
+	for i, instance := range instances {
+		profiles := make([]api.Profile, len(instance.Profiles))
+		for j, name := range instance.Profiles {
+			profile := profilesByProjectAndName[instance.Project][name]
 			profiles[j] = *ProfileToAPI(&profile)
 		}
 
-		containers[i].Config = ProfilesExpandConfig(container.Config, profiles)
-		containers[i].Devices = ProfilesExpandDevices(container.Devices, profiles)
+		instances[i].Config = ProfilesExpandConfig(instance.Config, profiles)
+		instances[i].Devices = ProfilesExpandDevices(instance.Devices, profiles)
 	}
 
-	return containers, nil
+	return instances, nil
 }
 
 // ContainersByNodeName returns a map associating each container to the name of
 // its node.
 func (c *ClusterTx) ContainersByNodeName(project string) (map[string]string, error) {
 	stmt := `
-SELECT containers.name, nodes.name
-  FROM containers
-  JOIN nodes ON nodes.id = containers.node_id
-  JOIN projects ON projects.id = containers.project_id
-  WHERE containers.type=?
+SELECT instances.name, nodes.name
+  FROM instances
+  JOIN nodes ON nodes.id = instances.node_id
+  JOIN projects ON projects.id = instances.project_id
+  WHERE instances.type=?
     AND projects.name = ?
 `
 	rows, err := c.tx.Query(stmt, CTypeRegular, project)
@@ -366,7 +394,7 @@ func (c *ClusterTx) SnapshotIDsAndNames(name string) (map[int]string, error) {
 		}{})
 		return []interface{}{&objects[i].ID, &objects[i].Name}
 	}
-	stmt, err := c.tx.Prepare("SELECT id, name FROM containers WHERE SUBSTR(name,1,?)=? AND type=?")
+	stmt, err := c.tx.Prepare("SELECT id, name FROM instances WHERE SUBSTR(name,1,?)=? AND type=?")
 	if err != nil {
 		return nil, err
 	}
@@ -407,7 +435,7 @@ func (c *ClusterTx) ContainerNodeMove(oldName, newName, newNode string) error {
 
 	// Update the name of the container and of its snapshots, and the node
 	// ID they are associated with.
-	containerID, err := c.ContainerID("default", oldName)
+	containerID, err := c.InstanceID("default", oldName)
 	if err != nil {
 		return errors.Wrap(err, "failed to get container's ID")
 	}
@@ -419,7 +447,7 @@ func (c *ClusterTx) ContainerNodeMove(oldName, newName, newNode string) error {
 	if err != nil {
 		return errors.Wrap(err, "failed to get new node's info")
 	}
-	stmt := "UPDATE containers SET node_id=?, name=? WHERE id=?"
+	stmt := "UPDATE instances SET node_id=?, name=? WHERE id=?"
 	result, err := c.tx.Exec(stmt, node.ID, newName, containerID)
 	if err != nil {
 		return errors.Wrap(err, "failed to update container's name and node ID")
@@ -429,11 +457,11 @@ func (c *ClusterTx) ContainerNodeMove(oldName, newName, newNode string) error {
 		return errors.Wrap(err, "failed to get rows affected by container update")
 	}
 	if n != 1 {
-		return fmt.Errorf("unexpected number of updated rows in containers table: %d", n)
+		return fmt.Errorf("unexpected number of updated rows in instances table: %d", n)
 	}
 	for snapshotID, snapshotName := range snapshots {
 		newSnapshotName := newName + shared.SnapshotDelimiter + snapshotName
-		stmt := "UPDATE containers SET node_id=?, name=? WHERE id=?"
+		stmt := "UPDATE instances SET node_id=?, name=? WHERE id=?"
 		result, err := c.tx.Exec(stmt, node.ID, newSnapshotName, snapshotID)
 		if err != nil {
 			return errors.Wrap(err, "failed to update snapshot's name and node ID")
@@ -492,32 +520,32 @@ func (c *ClusterTx) ContainerNodeMove(oldName, newName, newNode string) error {
 }
 
 // ContainerNodeList returns all container objects on the local node.
-func (c *ClusterTx) ContainerNodeList() ([]Container, error) {
+func (c *ClusterTx) ContainerNodeList() ([]Instance, error) {
 	node, err := c.NodeName()
 	if err != nil {
 		return nil, errors.Wrap(err, "Local node name")
 	}
-	filter := ContainerFilter{
+	filter := InstanceFilter{
 		Node: node,
 		Type: int(CTypeRegular),
 	}
 
-	return c.ContainerList(filter)
+	return c.InstanceList(filter)
 }
 
 // ContainerNodeProjectList returns all container objects on the local node within the given project.
-func (c *ClusterTx) ContainerNodeProjectList(project string) ([]Container, error) {
+func (c *ClusterTx) ContainerNodeProjectList(project string) ([]Instance, error) {
 	node, err := c.NodeName()
 	if err != nil {
 		return nil, errors.Wrap(err, "Local node name")
 	}
-	filter := ContainerFilter{
+	filter := InstanceFilter{
 		Project: project,
 		Node:    node,
 		Type:    int(CTypeRegular),
 	}
 
-	return c.ContainerList(filter)
+	return c.InstanceList(filter)
 }
 
 // ContainerConfigInsert inserts a new config for the container with the given ID.
@@ -541,7 +569,7 @@ func (c *ClusterTx) ContainerConfigUpdate(id int, values map[string]string) erro
 
 	// Insert/update keys
 	if len(changes) > 0 {
-		query := fmt.Sprintf("INSERT OR REPLACE INTO containers_config (container_id, key, value) VALUES")
+		query := fmt.Sprintf("INSERT OR REPLACE INTO instances_config (instance_id, key, value) VALUES")
 		exprs := []string{}
 		params := []interface{}{}
 		for key, value := range changes {
@@ -558,7 +586,7 @@ func (c *ClusterTx) ContainerConfigUpdate(id int, values map[string]string) erro
 
 	// Delete keys
 	if len(deletes) > 0 {
-		query := fmt.Sprintf("DELETE FROM containers_config WHERE key IN %s AND container_id=?", query.Params(len(deletes)))
+		query := fmt.Sprintf("DELETE FROM instances_config WHERE key IN %s AND instance_id=?", query.Params(len(deletes)))
 		params := []interface{}{}
 		for _, key := range deletes {
 			params = append(params, key)
@@ -577,7 +605,7 @@ func (c *ClusterTx) ContainerConfigUpdate(id int, values map[string]string) erro
 // ContainerRemove removes the container with the given name from the database.
 func (c *Cluster) ContainerRemove(project, name string) error {
 	return c.Transaction(func(tx *ClusterTx) error {
-		return tx.ContainerDelete(project, name)
+		return tx.InstanceDelete(project, name)
 	})
 }
 
@@ -585,10 +613,10 @@ func (c *Cluster) ContainerRemove(project, name string) error {
 // with the given ID.
 func (c *Cluster) ContainerProjectAndName(id int) (string, string, error) {
 	q := `
-SELECT projects.name, containers.name
-  FROM containers
-  JOIN projects ON projects.id = containers.project_id
-WHERE containers.id=?
+SELECT projects.name, instances.name
+  FROM instances
+  JOIN projects ON projects.id = instances.project_id
+WHERE instances.id=?
 `
 	project := ""
 	name := ""
@@ -604,7 +632,7 @@ WHERE containers.id=?
 
 // ContainerID returns the ID of the container with the given name.
 func (c *Cluster) ContainerID(name string) (int, error) {
-	q := "SELECT id FROM containers WHERE name=?"
+	q := "SELECT id FROM instances WHERE name=?"
 	id := -1
 	arg1 := []interface{}{name}
 	arg2 := []interface{}{&id}
@@ -619,29 +647,29 @@ func (c *Cluster) ContainerID(name string) (int, error) {
 // ContainerConfigClear removes any config associated with the container with
 // the given ID.
 func ContainerConfigClear(tx *sql.Tx, id int) error {
-	_, err := tx.Exec("DELETE FROM containers_config WHERE container_id=?", id)
+	_, err := tx.Exec("DELETE FROM instances_config WHERE instance_id=?", id)
 	if err != nil {
 		return err
 	}
-	_, err = tx.Exec("DELETE FROM containers_profiles WHERE container_id=?", id)
+	_, err = tx.Exec("DELETE FROM instances_profiles WHERE instance_id=?", id)
 	if err != nil {
 		return err
 	}
-	_, err = tx.Exec(`DELETE FROM containers_devices_config WHERE id IN
-		(SELECT containers_devices_config.id
-		 FROM containers_devices_config JOIN containers_devices
-		 ON containers_devices_config.container_device_id=containers_devices.id
-		 WHERE containers_devices.container_id=?)`, id)
+	_, err = tx.Exec(`DELETE FROM instances_devices_config WHERE id IN
+		(SELECT instances_devices_config.id
+		 FROM instances_devices_config JOIN instances_devices
+		 ON instances_devices_config.instance_device_id=instances_devices.id
+		 WHERE instances_devices.instance_id=?)`, id)
 	if err != nil {
 		return err
 	}
-	_, err = tx.Exec("DELETE FROM containers_devices WHERE container_id=?", id)
+	_, err = tx.Exec("DELETE FROM instances_devices WHERE instance_id=?", id)
 	return err
 }
 
 // ContainerConfigInsert inserts a new config for the container with the given ID.
 func ContainerConfigInsert(tx *sql.Tx, id int, config map[string]string) error {
-	str := "INSERT INTO containers_config (container_id, key, value) values (?, ?, ?)"
+	str := "INSERT INTO instances_config (instance_id, key, value) values (?, ?, ?)"
 	stmt, err := tx.Prepare(str)
 	if err != nil {
 		return err
@@ -667,7 +695,7 @@ func ContainerConfigInsert(tx *sql.Tx, id int, config map[string]string) error {
 // ContainerConfigGet returns the value of the given key in the configuration
 // of the container with the given ID.
 func (c *Cluster) ContainerConfigGet(id int, key string) (string, error) {
-	q := "SELECT value FROM containers_config WHERE container_id=? AND key=?"
+	q := "SELECT value FROM instances_config WHERE instance_id=? AND key=?"
 	value := ""
 	arg1 := []interface{}{id, key}
 	arg2 := []interface{}{&value}
@@ -682,7 +710,7 @@ func (c *Cluster) ContainerConfigGet(id int, key string) (string, error) {
 // ContainerConfigRemove removes the given key from the config of the container
 // with the given ID.
 func (c *Cluster) ContainerConfigRemove(id int, key string) error {
-	err := exec(c.db, "DELETE FROM containers_config WHERE key=? AND container_id=?", key, id)
+	err := exec(c.db, "DELETE FROM instances_config WHERE key=? AND instance_id=?", key, id)
 	return err
 }
 
@@ -694,7 +722,7 @@ func (c *Cluster) ContainerSetStateful(id int, stateful bool) error {
 		statefulInt = 1
 	}
 
-	err := exec(c.db, "UPDATE containers SET stateful=? WHERE id=?", statefulInt, id)
+	err := exec(c.db, "UPDATE instances SET stateful=? WHERE id=?", statefulInt, id)
 	return err
 }
 
@@ -711,7 +739,7 @@ func ContainerProfilesInsert(tx *sql.Tx, id int, project string, profiles []stri
 
 	applyOrder := 1
 	str := `
-INSERT INTO containers_profiles (container_id, profile_id, apply_order)
+INSERT INTO instances_profiles (instance_id, profile_id, apply_order)
   VALUES (
     ?,
     (SELECT profiles.id
@@ -745,10 +773,10 @@ func (c *Cluster) ContainerProfiles(id int) ([]string, error) {
 	var profiles []string
 
 	query := `
-        SELECT name FROM containers_profiles
-        JOIN profiles ON containers_profiles.profile_id=profiles.id
-		WHERE container_id=?
-        ORDER BY containers_profiles.apply_order`
+        SELECT name FROM instances_profiles
+        JOIN profiles ON instances_profiles.profile_id=profiles.id
+		WHERE instance_id=?
+        ORDER BY instances_profiles.apply_order`
 	inargs := []interface{}{id}
 	outfmt := []interface{}{name}
 
@@ -769,7 +797,7 @@ func (c *Cluster) ContainerProfiles(id int) ([]string, error) {
 // ContainerConfig gets the container configuration map from the DB
 func (c *Cluster) ContainerConfig(id int) (map[string]string, error) {
 	var key, value string
-	q := `SELECT key, value FROM containers_config WHERE container_id=?`
+	q := `SELECT key, value FROM instances_config WHERE instance_id=?`
 
 	inargs := []interface{}{id}
 	outfmt := []interface{}{key, value}
@@ -797,7 +825,7 @@ func (c *Cluster) ContainerConfig(id int) (map[string]string, error) {
 // NOTE: this is a pre-projects legacy API that is used only by patches. Don't
 // use it for new code.
 func (c *Cluster) LegacyContainersList(cType ContainerType) ([]string, error) {
-	q := fmt.Sprintf("SELECT name FROM containers WHERE type=? ORDER BY name")
+	q := fmt.Sprintf("SELECT name FROM instances WHERE type=? ORDER BY name")
 	inargs := []interface{}{cType}
 	var container string
 	outfmt := []interface{}{container}
@@ -817,7 +845,7 @@ func (c *Cluster) LegacyContainersList(cType ContainerType) ([]string, error) {
 // ContainersNodeList returns the names of all the containers of the given type
 // running on the local node.
 func (c *Cluster) ContainersNodeList(cType ContainerType) ([]string, error) {
-	q := fmt.Sprintf("SELECT name FROM containers WHERE type=? AND node_id=? ORDER BY name")
+	q := fmt.Sprintf("SELECT name FROM instances WHERE type=? AND node_id=? ORDER BY name")
 	inargs := []interface{}{cType, c.nodeID}
 	var container string
 	outfmt := []interface{}{container}
@@ -837,7 +865,7 @@ func (c *Cluster) ContainersNodeList(cType ContainerType) ([]string, error) {
 // ContainersResetState resets the power state of all containers.
 func (c *Cluster) ContainersResetState() error {
 	// Reset all container states
-	err := exec(c.db, "DELETE FROM containers_config WHERE key='volatile.last_state.power'")
+	err := exec(c.db, "DELETE FROM instances_config WHERE key='volatile.last_state.power'")
 	return err
 }
 
@@ -852,7 +880,7 @@ func (c *Cluster) ContainerSetState(id int, state string) error {
 // ContainerSetState sets the the power state of the container with the given ID.
 func (c *ClusterTx) ContainerSetState(id int, state string) error {
 	// Set the new value
-	str := fmt.Sprintf("INSERT OR REPLACE INTO containers_config (container_id, key, value) VALUES (?, 'volatile.last_state.power', ?)")
+	str := fmt.Sprintf("INSERT OR REPLACE INTO instances_config (instance_id, key, value) VALUES (?, 'volatile.last_state.power', ?)")
 	stmt, err := c.tx.Prepare(str)
 	if err != nil {
 		return err
@@ -871,7 +899,7 @@ func (c *ClusterTx) ContainerSetState(id int, state string) error {
 // the container with the given ID.
 func ContainerUpdate(tx *sql.Tx, id int, description string, architecture int, ephemeral bool,
 	expiryDate time.Time) error {
-	str := fmt.Sprintf("UPDATE containers SET description=?, architecture=?, ephemeral=?, expiry_date=? WHERE id=?")
+	str := fmt.Sprintf("UPDATE instances SET description=?, architecture=?, ephemeral=?, expiry_date=? WHERE id=?")
 	stmt, err := tx.Prepare(str)
 	if err != nil {
 		return err
@@ -898,7 +926,7 @@ func ContainerUpdate(tx *sql.Tx, id int, description string, architecture int, e
 // ContainerCreationUpdate updates the cration_date field of the container
 // with the given ID.
 func (c *Cluster) ContainerCreationUpdate(id int, date time.Time) error {
-	stmt := `UPDATE containers SET creation_date=? WHERE id=?`
+	stmt := `UPDATE instances SET creation_date=? WHERE id=?`
 	err := exec(c.db, stmt, date, id)
 	return err
 }
@@ -906,7 +934,7 @@ func (c *Cluster) ContainerCreationUpdate(id int, date time.Time) error {
 // ContainerLastUsedUpdate updates the last_use_date field of the container
 // with the given ID.
 func (c *ClusterTx) ContainerLastUsedUpdate(id int, date time.Time) error {
-	str := `UPDATE containers SET last_use_date=? WHERE id=?`
+	str := `UPDATE instances SET last_use_date=? WHERE id=?`
 	stmt, err := c.tx.Prepare(str)
 	if err != nil {
 		return err
@@ -929,11 +957,11 @@ func (c *Cluster) ContainerGetSnapshots(project, name string) ([]string, error)
 	regexp := name + shared.SnapshotDelimiter
 	length := len(regexp)
 	q := `
-SELECT containers.name
-  FROM containers
-  JOIN projects ON projects.id = containers.project_id
-WHERE projects.name=? AND containers.type=? AND SUBSTR(containers.name,1,?)=?
-ORDER BY date(containers.creation_date)
+SELECT instances.name
+  FROM instances
+  JOIN projects ON projects.id = instances.project_id
+WHERE projects.name=? AND instances.type=? AND SUBSTR(instances.name,1,?)=?
+ORDER BY date(instances.creation_date)
 `
 	inargs := []interface{}{project, CTypeSnapshot, length, regexp}
 	outfmt := []interface{}{name}
@@ -950,14 +978,14 @@ ORDER BY date(containers.creation_date)
 }
 
 // ContainerGetSnapshotsFull returns all container objects for snapshots of a given container
-func (c *ClusterTx) ContainerGetSnapshotsFull(project string, name string) ([]Container, error) {
-	filter := ContainerFilter{
+func (c *ClusterTx) ContainerGetSnapshotsFull(project string, name string) ([]Instance, error) {
+	filter := InstanceFilter{
 		Parent:  name,
 		Project: project,
 		Type:    int(CTypeSnapshot),
 	}
 
-	snapshots, err := c.ContainerList(filter)
+	snapshots, err := c.InstanceList(filter)
 	if err != nil {
 		return nil, err
 	}
@@ -973,10 +1001,10 @@ func (c *Cluster) ContainerNextSnapshot(project string, name string, pattern str
 	base := name + shared.SnapshotDelimiter
 	length := len(base)
 	q := `
-SELECT containers.name
-  FROM containers
-  JOIN projects ON projects.id = containers.project_id
- WHERE projects.name=? AND containers.type=? AND SUBSTR(containers.name,1,?)=?`
+SELECT instances.name
+  FROM instances
+  JOIN projects ON projects.id = instances.project_id
+ WHERE projects.name=? AND instances.type=? AND SUBSTR(instances.name,1,?)=?`
 	var numstr string
 	inargs := []interface{}{project, CTypeSnapshot, length, base}
 	outfmt := []interface{}{numstr}
@@ -1025,8 +1053,8 @@ func (c *ClusterTx) ContainerPool(project, containerName string) (string, error)
 	query := `
 SELECT storage_pools.name FROM storage_pools
   JOIN storage_volumes ON storage_pools.id=storage_volumes.storage_pool_id
-  JOIN containers ON containers.name=storage_volumes.name
-  JOIN projects ON projects.id=containers.project_id
+  JOIN instances ON instances.name=storage_volumes.name
+  JOIN projects ON projects.id=instances.project_id
  WHERE projects.name=? AND storage_volumes.node_id=? AND storage_volumes.name=? AND storage_volumes.type=?
 `
 	inargs := []interface{}{project, c.nodeID, containerName, StoragePoolVolumeTypeContainer}
@@ -1046,7 +1074,7 @@ SELECT storage_pools.name FROM storage_pools
 
 // ContainerBackupID returns the ID of the container backup with the given name.
 func (c *Cluster) ContainerBackupID(name string) (int, error) {
-	q := "SELECT id FROM containers_backups WHERE name=?"
+	q := "SELECT id FROM instances_backups WHERE name=?"
 	id := -1
 	arg1 := []interface{}{name}
 	arg2 := []interface{}{&id}
@@ -1066,13 +1094,13 @@ func (c *Cluster) ContainerGetBackup(project, name string) (ContainerBackupArgs,
 	containerOnlyInt := -1
 	optimizedStorageInt := -1
 	q := `
-SELECT containers_backups.id, containers_backups.container_id,
-       containers_backups.creation_date, containers_backups.expiry_date,
-       containers_backups.container_only, containers_backups.optimized_storage
-    FROM containers_backups
-    JOIN containers ON containers.id=containers_backups.container_id
-    JOIN projects ON projects.id=containers.project_id
-    WHERE projects.name=? AND containers_backups.name=?
+SELECT instances_backups.id, instances_backups.instance_id,
+       instances_backups.creation_date, instances_backups.expiry_date,
+       instances_backups.instance_only, instances_backups.optimized_storage
+    FROM instances_backups
+    JOIN instances ON instances.id=instances_backups.instance_id
+    JOIN projects ON projects.id=instances.project_id
+    WHERE projects.name=? AND instances_backups.name=?
 `
 	arg1 := []interface{}{project, name}
 	arg2 := []interface{}{&args.ID, &args.ContainerID, &args.CreationDate,
@@ -1102,10 +1130,10 @@ SELECT containers_backups.id, containers_backups.container_id,
 func (c *Cluster) ContainerGetBackups(project, name string) ([]string, error) {
 	var result []string
 
-	q := `SELECT containers_backups.name FROM containers_backups
-JOIN containers ON containers_backups.container_id=containers.id
-JOIN projects ON projects.id=containers.project_id
-WHERE projects.name=? AND containers.name=?`
+	q := `SELECT instances_backups.name FROM instances_backups
+JOIN instances ON instances_backups.instance_id=instances.id
+JOIN projects ON projects.id=instances.project_id
+WHERE projects.name=? AND instances.name=?`
 	inargs := []interface{}{project, name}
 	outfmt := []interface{}{name}
 	dbResults, err := queryScan(c.db, q, inargs, outfmt)
@@ -1138,7 +1166,7 @@ func (c *Cluster) ContainerBackupCreate(args ContainerBackupArgs) error {
 			optimizedStorageInt = 1
 		}
 
-		str := fmt.Sprintf("INSERT INTO containers_backups (container_id, name, creation_date, expiry_date, container_only, optimized_storage) VALUES (?, ?, ?, ?, ?, ?)")
+		str := fmt.Sprintf("INSERT INTO instances_backups (instance_id, name, creation_date, expiry_date, instance_only, optimized_storage) VALUES (?, ?, ?, ?, ?, ?)")
 		stmt, err := tx.tx.Prepare(str)
 		if err != nil {
 			return err
@@ -1170,7 +1198,7 @@ func (c *Cluster) ContainerBackupRemove(name string) error {
 		return err
 	}
 
-	err = exec(c.db, "DELETE FROM containers_backups WHERE id=?", id)
+	err = exec(c.db, "DELETE FROM instances_backups WHERE id=?", id)
 	if err != nil {
 		return err
 	}
@@ -1182,7 +1210,7 @@ func (c *Cluster) ContainerBackupRemove(name string) error {
 // to the new one.
 func (c *Cluster) ContainerBackupRename(oldName, newName string) error {
 	err := c.Transaction(func(tx *ClusterTx) error {
-		str := fmt.Sprintf("UPDATE containers_backups SET name = ? WHERE name = ?")
+		str := fmt.Sprintf("UPDATE instances_backups SET name = ? WHERE name = ?")
 		stmt, err := tx.tx.Prepare(str)
 		if err != nil {
 			return err
@@ -1192,7 +1220,7 @@ func (c *Cluster) ContainerBackupRename(oldName, newName string) error {
 		logger.Debug(
 			"Calling SQL Query",
 			log.Ctx{
-				"query":   "UPDATE containers_backups SET name = ? WHERE name = ?",
+				"query":   "UPDATE instances_backups SET name = ? WHERE name = ?",
 				"oldName": oldName,
 				"newName": newName})
 		if _, err := stmt.Exec(newName, oldName); err != nil {
@@ -1210,7 +1238,7 @@ func (c *Cluster) ContainerBackupsGetExpired() ([]string, error) {
 	var name string
 	var expiryDate string
 
-	q := `SELECT containers_backups.name, containers_backups.expiry_date FROM containers_backups`
+	q := `SELECT instances_backups.name, instances_backups.expiry_date FROM instances_backups`
 	outfmt := []interface{}{name, expiryDate}
 	dbResults, err := queryScan(c.db, q, nil, outfmt)
 	if err != nil {
diff --git a/lxd/db/db_internal_test.go b/lxd/db/db_internal_test.go
index 3a672851d7..7a628d6d07 100644
--- a/lxd/db/db_internal_test.go
+++ b/lxd/db/db_internal_test.go
@@ -15,12 +15,12 @@ import (
 )
 
 const fixtures string = `
-    INSERT INTO containers (node_id, name, architecture, type, project_id) VALUES (1, 'thename', 1, 1, 1);
+    INSERT INTO instances (node_id, name, architecture, type, project_id) VALUES (1, 'thename', 1, 1, 1);
     INSERT INTO profiles (name, project_id) VALUES ('theprofile', 1);
-    INSERT INTO containers_profiles (container_id, profile_id) VALUES (1, 2);
-    INSERT INTO containers_config (container_id, key, value) VALUES (1, 'thekey', 'thevalue');
-    INSERT INTO containers_devices (container_id, name, type) VALUES (1, 'somename', 1);
-    INSERT INTO containers_devices_config (key, value, container_device_id) VALUES ('configkey', 'configvalue', 1);
+    INSERT INTO instances_profiles (instance_id, profile_id) VALUES (1, 2);
+    INSERT INTO instances_config (instance_id, key, value) VALUES (1, 'thekey', 'thevalue');
+    INSERT INTO instances_devices (instance_id, name, type) VALUES (1, 'somename', 1);
+    INSERT INTO instances_devices_config (key, value, instance_device_id) VALUES ('configkey', 'configvalue', 1);
     INSERT INTO images (fingerprint, filename, size, architecture, creation_date, expiry_date, upload_date, auto_update, project_id) VALUES ('fingerprint', 'filename', 1024, 0,  1431547174,  1431547175,  1431547176, 1, 1);
     INSERT INTO images_aliases (name, image_id, description, project_id) VALUES ('somealias', 1, 'some description', 1);
     INSERT INTO images_properties (image_id, type, key, value) VALUES (1, 0, 'thekey', 'some value');
@@ -85,7 +85,7 @@ func (s *dbTestSuite) Test_deleting_a_container_cascades_on_related_tables() {
 	var statements string
 
 	// Drop the container we just created.
-	statements = `DELETE FROM containers WHERE name = 'thename';`
+	statements = `DELETE FROM instances WHERE name = 'thename';`
 
 	tx, commit := s.CreateTestTx()
 	defer commit()
@@ -94,25 +94,25 @@ func (s *dbTestSuite) Test_deleting_a_container_cascades_on_related_tables() {
 	s.Nil(err, "Error deleting container!")
 
 	// Make sure there are 0 container_profiles entries left.
-	statements = `SELECT count(*) FROM containers_profiles;`
+	statements = `SELECT count(*) FROM instances_profiles;`
 	err = tx.QueryRow(statements).Scan(&count)
 	s.Nil(err)
 	s.Equal(count, 0, "Deleting a container didn't delete the profile association!")
 
 	// Make sure there are 0 containers_config entries left.
-	statements = `SELECT count(*) FROM containers_config;`
+	statements = `SELECT count(*) FROM instances_config;`
 	err = tx.QueryRow(statements).Scan(&count)
 	s.Nil(err)
 	s.Equal(count, 0, "Deleting a container didn't delete the associated container_config!")
 
 	// Make sure there are 0 containers_devices entries left.
-	statements = `SELECT count(*) FROM containers_devices;`
+	statements = `SELECT count(*) FROM instances_devices;`
 	err = tx.QueryRow(statements).Scan(&count)
 	s.Nil(err)
 	s.Equal(count, 0, "Deleting a container didn't delete the associated container_devices!")
 
 	// Make sure there are 0 containers_devices_config entries left.
-	statements = `SELECT count(*) FROM containers_devices_config;`
+	statements = `SELECT count(*) FROM instances_devices_config;`
 	err = tx.QueryRow(statements).Scan(&count)
 	s.Nil(err)
 	s.Equal(count, 0, "Deleting a container didn't delete the associated container_devices_config!")
@@ -133,7 +133,7 @@ func (s *dbTestSuite) Test_deleting_a_profile_cascades_on_related_tables() {
 	s.Nil(err)
 
 	// Make sure there are 0 container_profiles entries left.
-	statements = `SELECT count(*) FROM containers_profiles WHERE profile_id = 2;`
+	statements = `SELECT count(*) FROM instances_profiles WHERE profile_id = 2;`
 	err = tx.QueryRow(statements).Scan(&count)
 	s.Nil(err)
 	s.Equal(count, 0, "Deleting a profile didn't delete the container association!")
@@ -275,7 +275,7 @@ func (s *dbTestSuite) Test_ContainerConfig() {
 
 	tx, commit := s.CreateTestTx()
 
-	_, err = tx.Exec("INSERT INTO containers_config (container_id, key, value) VALUES (1, 'something', 'something else');")
+	_, err = tx.Exec("INSERT INTO instances_config (instance_id, key, value) VALUES (1, 'something', 'something else');")
 	s.Nil(err)
 
 	commit()
diff --git a/lxd/db/devices.go b/lxd/db/devices.go
index ac51b3f73d..e78d7ec9d4 100644
--- a/lxd/db/devices.go
+++ b/lxd/db/devices.go
@@ -119,7 +119,7 @@ func dbDeviceConfig(db *sql.DB, id int, isprofile bool) (config.Device, error) {
 	if isprofile {
 		query = `SELECT key, value FROM profiles_devices_config WHERE profile_device_id=?`
 	} else {
-		query = `SELECT key, value FROM containers_devices_config WHERE container_device_id=?`
+		query = `SELECT key, value FROM instances_devices_config WHERE instance_device_id=?`
 	}
 
 	results, err := queryScan(db, query, inargs, outfmt)
@@ -161,11 +161,11 @@ func (c *Cluster) Devices(project, qName string, isprofile bool) (config.Devices
                         JOIN projects ON projects.id=profiles.project_id
    		WHERE projects.name=? AND profiles.name=?`
 	} else {
-		q = `SELECT containers_devices.id, containers_devices.name, containers_devices.type
-			FROM containers_devices
-                        JOIN containers	ON containers_devices.container_id = containers.id
-                        JOIN projects ON projects.id=containers.project_id
-			WHERE projects.name=? AND containers.name=?`
+		q = `SELECT instances_devices.id, instances_devices.name, instances_devices.type
+			FROM instances_devices
+                        JOIN instances	ON instances_devices.instance_id = instances.id
+                        JOIN projects ON projects.id=instances.project_id
+			WHERE projects.name=? AND instances.name=?`
 	}
 	var id, dtype int
 	var name, stype string
diff --git a/lxd/db/profiles.go b/lxd/db/profiles.go
index c59de7d3cb..2113e4d115 100644
--- a/lxd/db/profiles.go
+++ b/lxd/db/profiles.go
@@ -306,14 +306,14 @@ func (c *Cluster) ProfileContainersGet(project, profile string) (map[string][]st
 		return nil, err
 	}
 
-	q := `SELECT containers.name, projects.name FROM containers
-		JOIN containers_profiles ON containers.id == containers_profiles.container_id
-		JOIN projects ON projects.id == containers.project_id
-		WHERE containers_profiles.profile_id ==
+	q := `SELECT instances.name, projects.name FROM instances
+		JOIN instances_profiles ON instances.id == instances_profiles.instance_id
+		JOIN projects ON projects.id == instances.project_id
+		WHERE instances_profiles.profile_id ==
 		  (SELECT profiles.id FROM profiles
 		   JOIN projects ON projects.id == profiles.project_id
 		   WHERE profiles.name=? AND projects.name=?)
-		AND containers.type == 0`
+		AND instances.type == 0`
 
 	results := map[string][]string{}
 	inargs := []interface{}{profile, project}

From 2a84ab3779a65e2303a75aee2c82ecd0053d2d13 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 13:12:46 +0200
Subject: [PATCH 05/11] Change container special-casing in db code generator

---
 shared/generate/db/method.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/shared/generate/db/method.go b/shared/generate/db/method.go
index c8234746e0..0780681844 100644
--- a/shared/generate/db/method.go
+++ b/shared/generate/db/method.go
@@ -274,7 +274,7 @@ func (m *Method) get(buf *file.Buffer) error {
 		buf.L("filter.%s = %s", field.Name, lex.Minuscule(field.Name))
 	}
 	// FIXME: snowflake
-	if m.entity == "container" {
+	if m.entity == "instance" {
 		buf.L("filter.Type = -1")
 	}
 	buf.N()

From 7bed0f8db65fb63cdc164906b6ee804dea49cdd8 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 11:30:09 +0200
Subject: [PATCH 06/11] Re-generate db mapper code

---
 ...ntainers.mapper.go => instances.mapper.go} | 349 +++++++++---------
 1 file changed, 175 insertions(+), 174 deletions(-)
 rename lxd/db/{containers.mapper.go => instances.mapper.go} (51%)

diff --git a/lxd/db/containers.mapper.go b/lxd/db/instances.mapper.go
similarity index 51%
rename from lxd/db/containers.mapper.go
rename to lxd/db/instances.mapper.go
index 49951df18c..e94a449c50 100644
--- a/lxd/db/containers.mapper.go
+++ b/lxd/db/instances.mapper.go
@@ -5,6 +5,7 @@ package db
 import (
 	"database/sql"
 	"fmt"
+
 	"github.com/lxc/lxd/lxd/db/cluster"
 	"github.com/lxc/lxd/lxd/db/query"
 	"github.com/lxc/lxd/shared/api"
@@ -13,150 +14,150 @@ import (
 
 var _ = api.ServerEnvironment{}
 
-var containerObjects = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  ORDER BY projects.id, containers.name
+var instanceObjects = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  ORDER BY projects.id, instances.name
 `)
 
-var containerObjectsByType = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE containers.type = ? ORDER BY projects.id, containers.name
+var instanceObjectsByType = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE instances.type = ? ORDER BY projects.id, instances.name
 `)
 
-var containerObjectsByProjectAndType = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE project = ? AND containers.type = ? ORDER BY projects.id, containers.name
+var instanceObjectsByProjectAndType = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE project = ? AND instances.type = ? ORDER BY projects.id, instances.name
 `)
 
-var containerObjectsByProjectAndTypeAndParent = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE project = ? AND containers.type = ? AND SUBSTR(containers.name,1,?)=? ORDER BY projects.id, containers.name
+var instanceObjectsByProjectAndTypeAndParent = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE project = ? AND instances.type = ? AND SUBSTR(instances.name,1,?)=? ORDER BY projects.id, instances.name
 `)
 
-var containerObjectsByNodeAndType = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE node = ? AND containers.type = ? ORDER BY projects.id, containers.name
+var instanceObjectsByNodeAndType = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE node = ? AND instances.type = ? ORDER BY projects.id, instances.name
 `)
 
-var containerObjectsByProjectAndNodeAndType = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE project = ? AND node = ? AND containers.type = ? ORDER BY projects.id, containers.name
+var instanceObjectsByProjectAndNodeAndType = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE project = ? AND node = ? AND instances.type = ? ORDER BY projects.id, instances.name
 `)
 
-var containerObjectsByProjectAndName = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE project = ? AND containers.name = ? ORDER BY projects.id, containers.name
+var instanceObjectsByProjectAndName = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE project = ? AND instances.name = ? ORDER BY projects.id, instances.name
 `)
 
-var containerObjectsByProjectAndNameAndType = cluster.RegisterStmt(`
-SELECT containers.id, projects.name AS project, containers.name, nodes.name AS node, containers.type, containers.architecture, containers.ephemeral, containers.creation_date, containers.stateful, containers.last_use_date, coalesce(containers.description, ''), containers.expiry_date
-  FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE project = ? AND containers.name = ? AND containers.type = ? ORDER BY projects.id, containers.name
+var instanceObjectsByProjectAndNameAndType = cluster.RegisterStmt(`
+SELECT instances.id, projects.name AS project, instances.name, nodes.name AS node, instances.type, instances.architecture, instances.ephemeral, instances.creation_date, instances.stateful, instances.last_use_date, coalesce(instances.description, ''), instances.expiry_date
+  FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE project = ? AND instances.name = ? AND instances.type = ? ORDER BY projects.id, instances.name
 `)
 
-var containerProfilesRef = cluster.RegisterStmt(`
-SELECT project, name, value FROM containers_profiles_ref ORDER BY project, name
+var instanceProfilesRef = cluster.RegisterStmt(`
+SELECT project, name, value FROM instances_profiles_ref ORDER BY project, name
 `)
 
-var containerProfilesRefByProject = cluster.RegisterStmt(`
-SELECT project, name, value FROM containers_profiles_ref WHERE project = ? ORDER BY project, name
+var instanceProfilesRefByProject = cluster.RegisterStmt(`
+SELECT project, name, value FROM instances_profiles_ref WHERE project = ? ORDER BY project, name
 `)
 
-var containerProfilesRefByNode = cluster.RegisterStmt(`
-SELECT project, name, value FROM containers_profiles_ref WHERE node = ? ORDER BY project, name
+var instanceProfilesRefByNode = cluster.RegisterStmt(`
+SELECT project, name, value FROM instances_profiles_ref WHERE node = ? ORDER BY project, name
 `)
 
-var containerProfilesRefByProjectAndNode = cluster.RegisterStmt(`
-SELECT project, name, value FROM containers_profiles_ref WHERE project = ? AND node = ? ORDER BY project, name
+var instanceProfilesRefByProjectAndNode = cluster.RegisterStmt(`
+SELECT project, name, value FROM instances_profiles_ref WHERE project = ? AND node = ? ORDER BY project, name
 `)
 
-var containerProfilesRefByProjectAndName = cluster.RegisterStmt(`
-SELECT project, name, value FROM containers_profiles_ref WHERE project = ? AND name = ? ORDER BY project, name
+var instanceProfilesRefByProjectAndName = cluster.RegisterStmt(`
+SELECT project, name, value FROM instances_profiles_ref WHERE project = ? AND name = ? ORDER BY project, name
 `)
 
-var containerConfigRef = cluster.RegisterStmt(`
-SELECT project, name, key, value FROM containers_config_ref ORDER BY project, name
+var instanceConfigRef = cluster.RegisterStmt(`
+SELECT project, name, key, value FROM instances_config_ref ORDER BY project, name
 `)
 
-var containerConfigRefByProject = cluster.RegisterStmt(`
-SELECT project, name, key, value FROM containers_config_ref WHERE project = ? ORDER BY project, name
+var instanceConfigRefByProject = cluster.RegisterStmt(`
+SELECT project, name, key, value FROM instances_config_ref WHERE project = ? ORDER BY project, name
 `)
 
-var containerConfigRefByNode = cluster.RegisterStmt(`
-SELECT project, name, key, value FROM containers_config_ref WHERE node = ? ORDER BY project, name
+var instanceConfigRefByNode = cluster.RegisterStmt(`
+SELECT project, name, key, value FROM instances_config_ref WHERE node = ? ORDER BY project, name
 `)
 
-var containerConfigRefByProjectAndNode = cluster.RegisterStmt(`
-SELECT project, name, key, value FROM containers_config_ref WHERE project = ? AND node = ? ORDER BY project, name
+var instanceConfigRefByProjectAndNode = cluster.RegisterStmt(`
+SELECT project, name, key, value FROM instances_config_ref WHERE project = ? AND node = ? ORDER BY project, name
 `)
 
-var containerConfigRefByProjectAndName = cluster.RegisterStmt(`
-SELECT project, name, key, value FROM containers_config_ref WHERE project = ? AND name = ? ORDER BY project, name
+var instanceConfigRefByProjectAndName = cluster.RegisterStmt(`
+SELECT project, name, key, value FROM instances_config_ref WHERE project = ? AND name = ? ORDER BY project, name
 `)
 
-var containerDevicesRef = cluster.RegisterStmt(`
-SELECT project, name, device, type, key, value FROM containers_devices_ref ORDER BY project, name
+var instanceDevicesRef = cluster.RegisterStmt(`
+SELECT project, name, device, type, key, value FROM instances_devices_ref ORDER BY project, name
 `)
 
-var containerDevicesRefByProject = cluster.RegisterStmt(`
-SELECT project, name, device, type, key, value FROM containers_devices_ref WHERE project = ? ORDER BY project, name
+var instanceDevicesRefByProject = cluster.RegisterStmt(`
+SELECT project, name, device, type, key, value FROM instances_devices_ref WHERE project = ? ORDER BY project, name
 `)
 
-var containerDevicesRefByNode = cluster.RegisterStmt(`
-SELECT project, name, device, type, key, value FROM containers_devices_ref WHERE node = ? ORDER BY project, name
+var instanceDevicesRefByNode = cluster.RegisterStmt(`
+SELECT project, name, device, type, key, value FROM instances_devices_ref WHERE node = ? ORDER BY project, name
 `)
 
-var containerDevicesRefByProjectAndNode = cluster.RegisterStmt(`
-SELECT project, name, device, type, key, value FROM containers_devices_ref WHERE project = ? AND node = ? ORDER BY project, name
+var instanceDevicesRefByProjectAndNode = cluster.RegisterStmt(`
+SELECT project, name, device, type, key, value FROM instances_devices_ref WHERE project = ? AND node = ? ORDER BY project, name
 `)
 
-var containerDevicesRefByProjectAndName = cluster.RegisterStmt(`
-SELECT project, name, device, type, key, value FROM containers_devices_ref WHERE project = ? AND name = ? ORDER BY project, name
+var instanceDevicesRefByProjectAndName = cluster.RegisterStmt(`
+SELECT project, name, device, type, key, value FROM instances_devices_ref WHERE project = ? AND name = ? ORDER BY project, name
 `)
 
-var containerID = cluster.RegisterStmt(`
-SELECT containers.id FROM containers JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
-  WHERE projects.name = ? AND containers.name = ?
+var instanceID = cluster.RegisterStmt(`
+SELECT instances.id FROM instances JOIN projects ON project_id = projects.id JOIN nodes ON node_id = nodes.id
+  WHERE projects.name = ? AND instances.name = ?
 `)
 
-var containerCreate = cluster.RegisterStmt(`
-INSERT INTO containers (project_id, name, node_id, type, architecture, ephemeral, creation_date, stateful, last_use_date, description, expiry_date)
+var instanceCreate = cluster.RegisterStmt(`
+INSERT INTO instances (project_id, name, node_id, type, architecture, ephemeral, creation_date, stateful, last_use_date, description, expiry_date)
   VALUES ((SELECT id FROM projects WHERE name = ?), ?, (SELECT id FROM nodes WHERE name = ?), ?, ?, ?, ?, ?, ?, ?, ?)
 `)
 
-var containerCreateConfigRef = cluster.RegisterStmt(`
-INSERT INTO containers_config (container_id, key, value)
+var instanceCreateConfigRef = cluster.RegisterStmt(`
+INSERT INTO instances_config (instance_id, key, value)
   VALUES (?, ?, ?)
 `)
 
-var containerCreateDevicesRef = cluster.RegisterStmt(`
-INSERT INTO containers_devices (container_id, name, type)
+var instanceCreateDevicesRef = cluster.RegisterStmt(`
+INSERT INTO instances_devices (instance_id, name, type)
   VALUES (?, ?, ?)
 `)
-var containerCreateDevicesConfigRef = cluster.RegisterStmt(`
-INSERT INTO containers_devices_config (container_device_id, key, value)
+var instanceCreateDevicesConfigRef = cluster.RegisterStmt(`
+INSERT INTO instances_devices_config (instance_device_id, key, value)
   VALUES (?, ?, ?)
 `)
 
-var containerRename = cluster.RegisterStmt(`
-UPDATE containers SET name = ? WHERE project_id = (SELECT id FROM projects WHERE name = ?) AND name = ?
+var instanceRename = cluster.RegisterStmt(`
+UPDATE instances SET name = ? WHERE project_id = (SELECT id FROM projects WHERE name = ?) AND name = ?
 `)
 
-var containerDelete = cluster.RegisterStmt(`
-DELETE FROM containers WHERE project_id = (SELECT id FROM projects WHERE name = ?) AND name = ?
+var instanceDelete = cluster.RegisterStmt(`
+DELETE FROM instances WHERE project_id = (SELECT id FROM projects WHERE name = ?) AND name = ?
 `)
 
-// ContainerList returns all available containers.
-func (c *ClusterTx) ContainerList(filter ContainerFilter) ([]Container, error) {
+// InstanceList returns all available instances.
+func (c *ClusterTx) InstanceList(filter InstanceFilter) ([]Instance, error) {
 	// Result slice.
-	objects := make([]Container, 0)
+	objects := make([]Instance, 0)
 
 	// Check which filter criteria are active.
 	criteria := map[string]interface{}{}
@@ -181,14 +182,14 @@ func (c *ClusterTx) ContainerList(filter ContainerFilter) ([]Container, error) {
 	var args []interface{}
 
 	if criteria["Project"] != nil && criteria["Name"] != nil && criteria["Type"] != nil {
-		stmt = c.stmt(containerObjectsByProjectAndNameAndType)
+		stmt = c.stmt(instanceObjectsByProjectAndNameAndType)
 		args = []interface{}{
 			filter.Project,
 			filter.Name,
 			filter.Type,
 		}
 	} else if criteria["Project"] != nil && criteria["Type"] != nil && criteria["Parent"] != nil {
-		stmt = c.stmt(containerObjectsByProjectAndTypeAndParent)
+		stmt = c.stmt(instanceObjectsByProjectAndTypeAndParent)
 		args = []interface{}{
 			filter.Project,
 			filter.Type,
@@ -196,43 +197,43 @@ func (c *ClusterTx) ContainerList(filter ContainerFilter) ([]Container, error) {
 			filter.Parent + "/",
 		}
 	} else if criteria["Project"] != nil && criteria["Node"] != nil && criteria["Type"] != nil {
-		stmt = c.stmt(containerObjectsByProjectAndNodeAndType)
+		stmt = c.stmt(instanceObjectsByProjectAndNodeAndType)
 		args = []interface{}{
 			filter.Project,
 			filter.Node,
 			filter.Type,
 		}
-	} else if criteria["Node"] != nil && criteria["Type"] != nil {
-		stmt = c.stmt(containerObjectsByNodeAndType)
+	} else if criteria["Project"] != nil && criteria["Type"] != nil {
+		stmt = c.stmt(instanceObjectsByProjectAndType)
 		args = []interface{}{
-			filter.Node,
+			filter.Project,
 			filter.Type,
 		}
-	} else if criteria["Project"] != nil && criteria["Type"] != nil {
-		stmt = c.stmt(containerObjectsByProjectAndType)
+	} else if criteria["Node"] != nil && criteria["Type"] != nil {
+		stmt = c.stmt(instanceObjectsByNodeAndType)
 		args = []interface{}{
-			filter.Project,
+			filter.Node,
 			filter.Type,
 		}
 	} else if criteria["Project"] != nil && criteria["Name"] != nil {
-		stmt = c.stmt(containerObjectsByProjectAndName)
+		stmt = c.stmt(instanceObjectsByProjectAndName)
 		args = []interface{}{
 			filter.Project,
 			filter.Name,
 		}
 	} else if criteria["Type"] != nil {
-		stmt = c.stmt(containerObjectsByType)
+		stmt = c.stmt(instanceObjectsByType)
 		args = []interface{}{
 			filter.Type,
 		}
 	} else {
-		stmt = c.stmt(containerObjects)
+		stmt = c.stmt(instanceObjects)
 		args = []interface{}{}
 	}
 
 	// Dest function for scanning a row.
 	dest := func(i int) []interface{} {
-		objects = append(objects, Container{})
+		objects = append(objects, Instance{})
 		return []interface{}{
 			&objects[i].ID,
 			&objects[i].Project,
@@ -252,11 +253,11 @@ func (c *ClusterTx) ContainerList(filter ContainerFilter) ([]Container, error) {
 	// Select.
 	err := query.SelectObjects(stmt, dest, args...)
 	if err != nil {
-		return nil, errors.Wrap(err, "Failed to fetch containers")
+		return nil, errors.Wrap(err, "Failed to fetch instances")
 	}
 
 	// Fill field Config.
-	configObjects, err := c.ContainerConfigRef(filter)
+	configObjects, err := c.InstanceConfigRef(filter)
 	if err != nil {
 		return nil, errors.Wrap(err, "Failed to fetch field Config")
 	}
@@ -276,7 +277,7 @@ func (c *ClusterTx) ContainerList(filter ContainerFilter) ([]Container, error) {
 	}
 
 	// Fill field Devices.
-	devicesObjects, err := c.ContainerDevicesRef(filter)
+	devicesObjects, err := c.InstanceDevicesRef(filter)
 	if err != nil {
 		return nil, errors.Wrap(err, "Failed to fetch field Devices")
 	}
@@ -296,7 +297,7 @@ func (c *ClusterTx) ContainerList(filter ContainerFilter) ([]Container, error) {
 	}
 
 	// Fill field Profiles.
-	profilesObjects, err := c.ContainerProfilesRef(filter)
+	profilesObjects, err := c.InstanceProfilesRef(filter)
 	if err != nil {
 		return nil, errors.Wrap(err, "Failed to fetch field Profiles")
 	}
@@ -318,16 +319,16 @@ func (c *ClusterTx) ContainerList(filter ContainerFilter) ([]Container, error) {
 	return objects, nil
 }
 
-// ContainerGet returns the container with the given key.
-func (c *ClusterTx) ContainerGet(project string, name string) (*Container, error) {
-	filter := ContainerFilter{}
+// InstanceGet returns the instance with the given key.
+func (c *ClusterTx) InstanceGet(project string, name string) (*Instance, error) {
+	filter := InstanceFilter{}
 	filter.Project = project
 	filter.Name = name
 	filter.Type = -1
 
-	objects, err := c.ContainerList(filter)
+	objects, err := c.InstanceList(filter)
 	if err != nil {
-		return nil, errors.Wrap(err, "Failed to fetch Container")
+		return nil, errors.Wrap(err, "Failed to fetch Instance")
 	}
 
 	switch len(objects) {
@@ -336,16 +337,16 @@ func (c *ClusterTx) ContainerGet(project string, name string) (*Container, error
 	case 1:
 		return &objects[0], nil
 	default:
-		return nil, fmt.Errorf("More than one container matches")
+		return nil, fmt.Errorf("More than one instance matches")
 	}
 }
 
-// ContainerID return the ID of the container with the given key.
-func (c *ClusterTx) ContainerID(project string, name string) (int64, error) {
-	stmt := c.stmt(containerID)
+// InstanceID return the ID of the instance with the given key.
+func (c *ClusterTx) InstanceID(project string, name string) (int64, error) {
+	stmt := c.stmt(instanceID)
 	rows, err := stmt.Query(project, name)
 	if err != nil {
-		return -1, errors.Wrap(err, "Failed to get container ID")
+		return -1, errors.Wrap(err, "Failed to get instance ID")
 	}
 	defer rows.Close()
 
@@ -369,9 +370,9 @@ func (c *ClusterTx) ContainerID(project string, name string) (int64, error) {
 	return id, nil
 }
 
-// ContainerExists checks if a container with the given key exists.
-func (c *ClusterTx) ContainerExists(project string, name string) (bool, error) {
-	_, err := c.ContainerID(project, name)
+// InstanceExists checks if a instance with the given key exists.
+func (c *ClusterTx) InstanceExists(project string, name string) (bool, error) {
+	_, err := c.InstanceID(project, name)
 	if err != nil {
 		if err == ErrNoSuchObject {
 			return false, nil
@@ -382,15 +383,15 @@ func (c *ClusterTx) ContainerExists(project string, name string) (bool, error) {
 	return true, nil
 }
 
-// ContainerCreate adds a new container to the database.
-func (c *ClusterTx) ContainerCreate(object Container) (int64, error) {
-	// Check if a container with the same key exists.
-	exists, err := c.ContainerExists(object.Project, object.Name)
+// InstanceCreate adds a new instance to the database.
+func (c *ClusterTx) InstanceCreate(object Instance) (int64, error) {
+	// Check if a instance with the same key exists.
+	exists, err := c.InstanceExists(object.Project, object.Name)
 	if err != nil {
 		return -1, errors.Wrap(err, "Failed to check for duplicates")
 	}
 	if exists {
-		return -1, fmt.Errorf("This container already exists")
+		return -1, fmt.Errorf("This instance already exists")
 	}
 
 	args := make([]interface{}, 11)
@@ -409,25 +410,25 @@ func (c *ClusterTx) ContainerCreate(object Container) (int64, error) {
 	args[10] = object.ExpiryDate
 
 	// Prepared statement to use.
-	stmt := c.stmt(containerCreate)
+	stmt := c.stmt(instanceCreate)
 
 	// Execute the statement.
 	result, err := stmt.Exec(args...)
 	if err != nil {
-		return -1, errors.Wrap(err, "Failed to create container")
+		return -1, errors.Wrap(err, "Failed to create instance")
 	}
 
 	id, err := result.LastInsertId()
 	if err != nil {
-		return -1, errors.Wrap(err, "Failed to fetch container ID")
+		return -1, errors.Wrap(err, "Failed to fetch instance ID")
 	}
 
 	// Insert config reference.
-	stmt = c.stmt(containerCreateConfigRef)
+	stmt = c.stmt(instanceCreateConfigRef)
 	for key, value := range object.Config {
 		_, err := stmt.Exec(id, key, value)
 		if err != nil {
-			return -1, errors.Wrap(err, "Insert config for container")
+			return -1, errors.Wrap(err, "Insert config for instance")
 		}
 	}
 
@@ -441,7 +442,7 @@ func (c *ClusterTx) ContainerCreate(object Container) (int64, error) {
 		if err != nil {
 			return -1, errors.Wrapf(err, "Device type code for %s", typ)
 		}
-		stmt = c.stmt(containerCreateDevicesRef)
+		stmt = c.stmt(instanceCreateDevicesRef)
 		result, err := stmt.Exec(id, name, typCode)
 		if err != nil {
 			return -1, errors.Wrapf(err, "Insert device %s", name)
@@ -450,11 +451,11 @@ func (c *ClusterTx) ContainerCreate(object Container) (int64, error) {
 		if err != nil {
 			return -1, errors.Wrap(err, "Failed to fetch device ID")
 		}
-		stmt = c.stmt(containerCreateDevicesConfigRef)
+		stmt = c.stmt(instanceCreateDevicesConfigRef)
 		for key, value := range config {
 			_, err := stmt.Exec(deviceID, key, value)
 			if err != nil {
-				return -1, errors.Wrap(err, "Insert config for container")
+				return -1, errors.Wrap(err, "Insert config for instance")
 			}
 		}
 	}
@@ -462,13 +463,13 @@ func (c *ClusterTx) ContainerCreate(object Container) (int64, error) {
 	// Insert profiles reference.
 	err = ContainerProfilesInsert(c.tx, int(id), object.Project, object.Profiles)
 	if err != nil {
-		return -1, errors.Wrap(err, "Insert profiles for container")
+		return -1, errors.Wrap(err, "Insert profiles for instance")
 	}
 	return id, nil
 }
 
-// ContainerProfilesRef returns entities used by containers.
-func (c *ClusterTx) ContainerProfilesRef(filter ContainerFilter) (map[string]map[string][]string, error) {
+// InstanceProfilesRef returns entities used by instances.
+func (c *ClusterTx) InstanceProfilesRef(filter InstanceFilter) (map[string]map[string][]string, error) {
 	// Result slice.
 	objects := make([]struct {
 		Project string
@@ -493,29 +494,29 @@ func (c *ClusterTx) ContainerProfilesRef(filter ContainerFilter) (map[string]map
 	var args []interface{}
 
 	if criteria["Project"] != nil && criteria["Name"] != nil {
-		stmt = c.stmt(containerProfilesRefByProjectAndName)
+		stmt = c.stmt(instanceProfilesRefByProjectAndName)
 		args = []interface{}{
 			filter.Project,
 			filter.Name,
 		}
 	} else if criteria["Project"] != nil && criteria["Node"] != nil {
-		stmt = c.stmt(containerProfilesRefByProjectAndNode)
+		stmt = c.stmt(instanceProfilesRefByProjectAndNode)
 		args = []interface{}{
 			filter.Project,
 			filter.Node,
 		}
-	} else if criteria["Project"] != nil {
-		stmt = c.stmt(containerProfilesRefByProject)
-		args = []interface{}{
-			filter.Project,
-		}
 	} else if criteria["Node"] != nil {
-		stmt = c.stmt(containerProfilesRefByNode)
+		stmt = c.stmt(instanceProfilesRefByNode)
 		args = []interface{}{
 			filter.Node,
 		}
+	} else if criteria["Project"] != nil {
+		stmt = c.stmt(instanceProfilesRefByProject)
+		args = []interface{}{
+			filter.Project,
+		}
 	} else {
-		stmt = c.stmt(containerProfilesRef)
+		stmt = c.stmt(instanceProfilesRef)
 		args = []interface{}{}
 	}
 
@@ -536,7 +537,7 @@ func (c *ClusterTx) ContainerProfilesRef(filter ContainerFilter) (map[string]map
 	// Select.
 	err := query.SelectObjects(stmt, dest, args...)
 	if err != nil {
-		return nil, errors.Wrap(err, "Failed to fetch string ref for containers")
+		return nil, errors.Wrap(err, "Failed to fetch string ref for instances")
 	}
 
 	// Build index by primary name.
@@ -560,8 +561,8 @@ func (c *ClusterTx) ContainerProfilesRef(filter ContainerFilter) (map[string]map
 	return index, nil
 }
 
-// ContainerConfigRef returns entities used by containers.
-func (c *ClusterTx) ContainerConfigRef(filter ContainerFilter) (map[string]map[string]map[string]string, error) {
+// InstanceConfigRef returns entities used by instances.
+func (c *ClusterTx) InstanceConfigRef(filter InstanceFilter) (map[string]map[string]map[string]string, error) {
 	// Result slice.
 	objects := make([]struct {
 		Project string
@@ -586,30 +587,30 @@ func (c *ClusterTx) ContainerConfigRef(filter ContainerFilter) (map[string]map[s
 	var stmt *sql.Stmt
 	var args []interface{}
 
-	if criteria["Project"] != nil && criteria["Name"] != nil {
-		stmt = c.stmt(containerConfigRefByProjectAndName)
+	if criteria["Project"] != nil && criteria["Node"] != nil {
+		stmt = c.stmt(instanceConfigRefByProjectAndNode)
+		args = []interface{}{
+			filter.Project,
+			filter.Node,
+		}
+	} else if criteria["Project"] != nil && criteria["Name"] != nil {
+		stmt = c.stmt(instanceConfigRefByProjectAndName)
 		args = []interface{}{
 			filter.Project,
 			filter.Name,
 		}
-	} else if criteria["Project"] != nil && criteria["Node"] != nil {
-		stmt = c.stmt(containerConfigRefByProjectAndNode)
+	} else if criteria["Project"] != nil {
+		stmt = c.stmt(instanceConfigRefByProject)
 		args = []interface{}{
 			filter.Project,
-			filter.Node,
 		}
 	} else if criteria["Node"] != nil {
-		stmt = c.stmt(containerConfigRefByNode)
+		stmt = c.stmt(instanceConfigRefByNode)
 		args = []interface{}{
 			filter.Node,
 		}
-	} else if criteria["Project"] != nil {
-		stmt = c.stmt(containerConfigRefByProject)
-		args = []interface{}{
-			filter.Project,
-		}
 	} else {
-		stmt = c.stmt(containerConfigRef)
+		stmt = c.stmt(instanceConfigRef)
 		args = []interface{}{}
 	}
 
@@ -632,7 +633,7 @@ func (c *ClusterTx) ContainerConfigRef(filter ContainerFilter) (map[string]map[s
 	// Select.
 	err := query.SelectObjects(stmt, dest, args...)
 	if err != nil {
-		return nil, errors.Wrap(err, "Failed to fetch  ref for containers")
+		return nil, errors.Wrap(err, "Failed to fetch  ref for instances")
 	}
 
 	// Build index by primary name.
@@ -657,8 +658,8 @@ func (c *ClusterTx) ContainerConfigRef(filter ContainerFilter) (map[string]map[s
 	return index, nil
 }
 
-// ContainerDevicesRef returns entities used by containers.
-func (c *ClusterTx) ContainerDevicesRef(filter ContainerFilter) (map[string]map[string]map[string]map[string]string, error) {
+// InstanceDevicesRef returns entities used by instances.
+func (c *ClusterTx) InstanceDevicesRef(filter InstanceFilter) (map[string]map[string]map[string]map[string]string, error) {
 	// Result slice.
 	objects := make([]struct {
 		Project string
@@ -685,30 +686,30 @@ func (c *ClusterTx) ContainerDevicesRef(filter ContainerFilter) (map[string]map[
 	var stmt *sql.Stmt
 	var args []interface{}
 
-	if criteria["Project"] != nil && criteria["Name"] != nil {
-		stmt = c.stmt(containerDevicesRefByProjectAndName)
+	if criteria["Project"] != nil && criteria["Node"] != nil {
+		stmt = c.stmt(instanceDevicesRefByProjectAndNode)
+		args = []interface{}{
+			filter.Project,
+			filter.Node,
+		}
+	} else if criteria["Project"] != nil && criteria["Name"] != nil {
+		stmt = c.stmt(instanceDevicesRefByProjectAndName)
 		args = []interface{}{
 			filter.Project,
 			filter.Name,
 		}
-	} else if criteria["Project"] != nil && criteria["Node"] != nil {
-		stmt = c.stmt(containerDevicesRefByProjectAndNode)
+	} else if criteria["Project"] != nil {
+		stmt = c.stmt(instanceDevicesRefByProject)
 		args = []interface{}{
 			filter.Project,
-			filter.Node,
 		}
 	} else if criteria["Node"] != nil {
-		stmt = c.stmt(containerDevicesRefByNode)
+		stmt = c.stmt(instanceDevicesRefByNode)
 		args = []interface{}{
 			filter.Node,
 		}
-	} else if criteria["Project"] != nil {
-		stmt = c.stmt(containerDevicesRefByProject)
-		args = []interface{}{
-			filter.Project,
-		}
 	} else {
-		stmt = c.stmt(containerDevicesRef)
+		stmt = c.stmt(instanceDevicesRef)
 		args = []interface{}{}
 	}
 
@@ -735,7 +736,7 @@ func (c *ClusterTx) ContainerDevicesRef(filter ContainerFilter) (map[string]map[
 	// Select.
 	err := query.SelectObjects(stmt, dest, args...)
 	if err != nil {
-		return nil, errors.Wrap(err, "Failed to fetch  ref for containers")
+		return nil, errors.Wrap(err, "Failed to fetch  ref for instances")
 	}
 
 	// Build index by primary name.
@@ -775,12 +776,12 @@ func (c *ClusterTx) ContainerDevicesRef(filter ContainerFilter) (map[string]map[
 	return index, nil
 }
 
-// ContainerRename renames the container matching the given key parameters.
-func (c *ClusterTx) ContainerRename(project string, name string, to string) error {
-	stmt := c.stmt(containerRename)
+// InstanceRename renames the instance matching the given key parameters.
+func (c *ClusterTx) InstanceRename(project string, name string, to string) error {
+	stmt := c.stmt(instanceRename)
 	result, err := stmt.Exec(to, project, name)
 	if err != nil {
-		return errors.Wrap(err, "Rename container")
+		return errors.Wrap(err, "Rename instance")
 	}
 
 	n, err := result.RowsAffected()
@@ -793,12 +794,12 @@ func (c *ClusterTx) ContainerRename(project string, name string, to string) erro
 	return nil
 }
 
-// ContainerDelete deletes the container matching the given key parameters.
-func (c *ClusterTx) ContainerDelete(project string, name string) error {
-	stmt := c.stmt(containerDelete)
+// InstanceDelete deletes the instance matching the given key parameters.
+func (c *ClusterTx) InstanceDelete(project string, name string) error {
+	stmt := c.stmt(instanceDelete)
 	result, err := stmt.Exec(project, name)
 	if err != nil {
-		return errors.Wrap(err, "Delete container")
+		return errors.Wrap(err, "Delete instance")
 	}
 
 	n, err := result.RowsAffected()

From 862bc623f76b61cb8b6c90437241513d6d551d33 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 11:30:22 +0200
Subject: [PATCH 07/11] Update unit tests after containers -> instances
 conversion

---
 lxd/db/containers_test.go | 58 +++++++++++++++++++--------------------
 lxd/db/node.go            | 12 ++++----
 lxd/db/node_test.go       |  6 ++--
 3 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/lxd/db/containers_test.go b/lxd/db/containers_test.go
index 9cd62f0f52..50f9342ec6 100644
--- a/lxd/db/containers_test.go
+++ b/lxd/db/containers_test.go
@@ -32,8 +32,8 @@ func TestContainerList(t *testing.T) {
 	addContainerDevice(t, tx, "c2", "eth0", "nic", nil)
 	addContainerDevice(t, tx, "c3", "root", "disk", map[string]string{"x": "y"})
 
-	filter := db.ContainerFilter{Type: int(db.CTypeRegular)}
-	containers, err := tx.ContainerList(filter)
+	filter := db.InstanceFilter{Type: int(db.CTypeRegular)}
+	containers, err := tx.InstanceList(filter)
 	require.NoError(t, err)
 	assert.Len(t, containers, 3)
 
@@ -71,13 +71,13 @@ func TestContainerList_FilterByNode(t *testing.T) {
 	addContainer(t, tx, nodeID1, "c2")
 	addContainer(t, tx, nodeID2, "c3")
 
-	filter := db.ContainerFilter{
+	filter := db.InstanceFilter{
 		Project: "default",
 		Node:    "node2",
 		Type:    int(db.CTypeRegular),
 	}
 
-	containers, err := tx.ContainerList(filter)
+	containers, err := tx.InstanceList(filter)
 	require.NoError(t, err)
 	assert.Len(t, containers, 2)
 
@@ -89,7 +89,7 @@ func TestContainerList_FilterByNode(t *testing.T) {
 	assert.Equal(t, "node2", containers[1].Node)
 }
 
-func TestContainerList_FilterByParent(t *testing.T) {
+func TestInstanceList_FilterByParent(t *testing.T) {
 	tx, cleanup := db.NewTestClusterTx(t)
 	defer cleanup()
 
@@ -101,13 +101,13 @@ func TestContainerList_FilterByParent(t *testing.T) {
 	addSnapshot(t, tx, nodeID1, "c1", 2)
 	addSnapshot(t, tx, nodeID1, "c2", 1)
 
-	filter := db.ContainerFilter{
+	filter := db.InstanceFilter{
 		Project: "default",
 		Parent:  "c1",
 		Type:    int(db.CTypeSnapshot),
 	}
 
-	containers, err := tx.ContainerList(filter)
+	containers, err := tx.InstanceList(filter)
 	require.NoError(t, err)
 	assert.Len(t, containers, 2)
 
@@ -115,7 +115,7 @@ func TestContainerList_FilterByParent(t *testing.T) {
 	assert.Equal(t, "c1/2", containers[1].Name)
 }
 
-func TestContainerList_ContainerWithSameNameInDifferentProjects(t *testing.T) {
+func TestInstanceList_ContainerWithSameNameInDifferentProjects(t *testing.T) {
 	tx, cleanup := db.NewTestClusterTx(t)
 	defer cleanup()
 
@@ -141,7 +141,7 @@ func TestContainerList_ContainerWithSameNameInDifferentProjects(t *testing.T) {
 
 	// Create a container in project1 using the default profile from the
 	// default project.
-	c1p1 := db.Container{
+	c1p1 := db.Instance{
 		Project:      "blah",
 		Name:         "c1",
 		Node:         "none",
@@ -151,12 +151,12 @@ func TestContainerList_ContainerWithSameNameInDifferentProjects(t *testing.T) {
 		Stateful:     true,
 		Profiles:     []string{"default"},
 	}
-	_, err = tx.ContainerCreate(c1p1)
+	_, err = tx.InstanceCreate(c1p1)
 	require.NoError(t, err)
 
 	// Create a container in project2 using the custom profile from the
 	// project.
-	c1p2 := db.Container{
+	c1p2 := db.Instance{
 		Project:      "test",
 		Name:         "c1",
 		Node:         "none",
@@ -166,10 +166,10 @@ func TestContainerList_ContainerWithSameNameInDifferentProjects(t *testing.T) {
 		Stateful:     true,
 		Profiles:     []string{"intranet"},
 	}
-	_, err = tx.ContainerCreate(c1p2)
+	_, err = tx.InstanceCreate(c1p2)
 	require.NoError(t, err)
 
-	containers, err := tx.ContainerList(db.ContainerFilter{})
+	containers, err := tx.InstanceList(db.InstanceFilter{})
 	require.NoError(t, err)
 
 	assert.Len(t, containers, 2)
@@ -181,7 +181,7 @@ func TestContainerList_ContainerWithSameNameInDifferentProjects(t *testing.T) {
 	assert.Equal(t, []string{"intranet"}, containers[1].Profiles)
 }
 
-func TestContainerListExpanded(t *testing.T) {
+func TestInstanceListExpanded(t *testing.T) {
 	tx, cleanup := db.NewTestClusterTx(t)
 	defer cleanup()
 
@@ -195,7 +195,7 @@ func TestContainerListExpanded(t *testing.T) {
 	_, err := tx.ProfileCreate(profile)
 	require.NoError(t, err)
 
-	container := db.Container{
+	container := db.Instance{
 		Project:      "default",
 		Name:         "c1",
 		Node:         "none",
@@ -208,7 +208,7 @@ func TestContainerListExpanded(t *testing.T) {
 		Profiles:     []string{"default", "profile1"},
 	}
 
-	_, err = tx.ContainerCreate(container)
+	_, err = tx.InstanceCreate(container)
 	require.NoError(t, err)
 
 	containers, err := tx.ContainerListExpanded()
@@ -223,11 +223,11 @@ func TestContainerListExpanded(t *testing.T) {
 	})
 }
 
-func TestContainerCreate(t *testing.T) {
+func TestInstanceCreate(t *testing.T) {
 	tx, cleanup := db.NewTestClusterTx(t)
 	defer cleanup()
 
-	object := db.Container{
+	object := db.Instance{
 		Project:      "default",
 		Name:         "c1",
 		Type:         0,
@@ -242,12 +242,12 @@ func TestContainerCreate(t *testing.T) {
 		Profiles:     []string{"default"},
 	}
 
-	id, err := tx.ContainerCreate(object)
+	id, err := tx.InstanceCreate(object)
 	require.NoError(t, err)
 
 	assert.Equal(t, int64(1), id)
 
-	c1, err := tx.ContainerGet("default", "c1")
+	c1, err := tx.InstanceGet("default", "c1")
 	require.NoError(t, err)
 
 	assert.Equal(t, "c1", c1.Name)
@@ -320,7 +320,7 @@ func TestContainerPool(t *testing.T) {
 	require.NoError(t, err)
 
 	err = cluster.Transaction(func(tx *db.ClusterTx) error {
-		container := db.Container{
+		container := db.Instance{
 			Project: "default",
 			Name:    "c1",
 			Node:    "none",
@@ -332,7 +332,7 @@ func TestContainerPool(t *testing.T) {
 				},
 			},
 		}
-		_, err := tx.ContainerCreate(container)
+		_, err := tx.InstanceCreate(container)
 		return err
 	})
 	require.NoError(t, err)
@@ -411,7 +411,7 @@ func TestContainerNodeList(t *testing.T) {
 
 func addContainer(t *testing.T, tx *db.ClusterTx, nodeID int64, name string) {
 	stmt := `
-INSERT INTO containers(node_id, name, architecture, type, project_id) VALUES (?, ?, 1, ?, 1)
+INSERT INTO instances(node_id, name, architecture, type, project_id) VALUES (?, ?, 1, ?, 1)
 `
 	_, err := tx.Tx().Exec(stmt, nodeID, name, db.CTypeRegular)
 	require.NoError(t, err)
@@ -419,7 +419,7 @@ INSERT INTO containers(node_id, name, architecture, type, project_id) VALUES (?,
 
 func addSnapshot(t *testing.T, tx *db.ClusterTx, nodeID int64, name string, n int) {
 	stmt := `
-INSERT INTO containers(node_id, name, architecture, type, project_id) VALUES (?, ?, 1, ?, 1)
+INSERT INTO instances(node_id, name, architecture, type, project_id) VALUES (?, ?, 1, ?, 1)
 `
 	_, err := tx.Tx().Exec(stmt, nodeID, fmt.Sprintf("%s/%d", name, n), db.CTypeSnapshot)
 	require.NoError(t, err)
@@ -429,7 +429,7 @@ func addContainerConfig(t *testing.T, tx *db.ClusterTx, container, key, value st
 	id := getContainerID(t, tx, container)
 
 	stmt := `
-INSERT INTO containers_config(container_id, key, value) VALUES (?, ?, ?)
+INSERT INTO instances_config(instance_id, key, value) VALUES (?, ?, ?)
 `
 	_, err := tx.Tx().Exec(stmt, id, key, value)
 	require.NoError(t, err)
@@ -442,7 +442,7 @@ func addContainerDevice(t *testing.T, tx *db.ClusterTx, container, name, typ str
 	require.NoError(t, err)
 
 	stmt := `
-INSERT INTO containers_devices(container_id, name, type) VALUES (?, ?, ?)
+INSERT INTO instances_devices(instance_id, name, type) VALUES (?, ?, ?)
 `
 	_, err = tx.Tx().Exec(stmt, id, name, code)
 	require.NoError(t, err)
@@ -451,7 +451,7 @@ INSERT INTO containers_devices(container_id, name, type) VALUES (?, ?, ?)
 
 	for key, value := range config {
 		stmt := `
-INSERT INTO containers_devices_config(container_device_id, key, value) VALUES (?, ?, ?)
+INSERT INTO instances_devices_config(instance_device_id, key, value) VALUES (?, ?, ?)
 `
 		_, err = tx.Tx().Exec(stmt, deviceID, key, value)
 		require.NoError(t, err)
@@ -462,7 +462,7 @@ INSERT INTO containers_devices_config(container_device_id, key, value) VALUES (?
 func getContainerID(t *testing.T, tx *db.ClusterTx, name string) int64 {
 	var id int64
 
-	stmt := "SELECT id FROM containers WHERE name=?"
+	stmt := "SELECT id FROM instances WHERE name=?"
 	row := tx.Tx().QueryRow(stmt, name)
 	err := row.Scan(&id)
 	require.NoError(t, err)
@@ -474,7 +474,7 @@ func getContainerID(t *testing.T, tx *db.ClusterTx, name string) int64 {
 func getDeviceID(t *testing.T, tx *db.ClusterTx, containerID int64, name string) int64 {
 	var id int64
 
-	stmt := "SELECT id FROM containers_devices WHERE container_id=? AND name=?"
+	stmt := "SELECT id FROM instances_devices WHERE instance_id=? AND name=?"
 	row := tx.Tx().QueryRow(stmt, containerID, name)
 	err := row.Scan(&id)
 	require.NoError(t, err)
diff --git a/lxd/db/node.go b/lxd/db/node.go
index cc318177dc..563b158d4a 100644
--- a/lxd/db/node.go
+++ b/lxd/db/node.go
@@ -325,10 +325,10 @@ func (c *ClusterTx) NodeHeartbeat(address string, heartbeat time.Time) error {
 // containers or images associated with it. Otherwise, it returns a message
 // say what's left.
 func (c *ClusterTx) NodeIsEmpty(id int64) (string, error) {
-	// Check if the node has any containers.
-	containers, err := query.SelectStrings(c.tx, "SELECT name FROM containers WHERE node_id=?", id)
+	// Check if the node has any instances.
+	containers, err := query.SelectStrings(c.tx, "SELECT name FROM instances WHERE node_id=?", id)
 	if err != nil {
-		return "", errors.Wrapf(err, "Failed to get containers for node %d", id)
+		return "", errors.Wrapf(err, "Failed to get instances for node %d", id)
 	}
 	if len(containers) > 0 {
 		message := fmt.Sprintf(
@@ -398,7 +398,7 @@ SELECT fingerprint, node_id FROM images JOIN images_nodes ON images.id=images_no
 
 // NodeClear removes any container or image associated with this node.
 func (c *ClusterTx) NodeClear(id int64) error {
-	_, err := c.tx.Exec("DELETE FROM containers WHERE node_id=?", id)
+	_, err := c.tx.Exec("DELETE FROM instances WHERE node_id=?", id)
 	if err != nil {
 		return err
 	}
@@ -474,9 +474,9 @@ func (c *ClusterTx) NodeWithLeastContainers() (string, error) {
 		}
 
 		// Fetch the number of containers already created on this node.
-		created, err := query.Count(c.tx, "containers", "node_id=?", node.ID)
+		created, err := query.Count(c.tx, "instances", "node_id=?", node.ID)
 		if err != nil {
-			return "", errors.Wrap(err, "Failed to get containers count")
+			return "", errors.Wrap(err, "Failed to get instances count")
 		}
 
 		// Fetch the number of containers currently being created on this node.
diff --git a/lxd/db/node_test.go b/lxd/db/node_test.go
index 4094c2cba7..80dc2e0e0b 100644
--- a/lxd/db/node_test.go
+++ b/lxd/db/node_test.go
@@ -226,7 +226,7 @@ func TestNodeIsEmpty_Containers(t *testing.T) {
 	assert.Equal(t, "", message)
 
 	_, err = tx.Tx().Exec(`
-INSERT INTO containers (id, node_id, name, architecture, type, project_id) VALUES (1, ?, 'foo', 1, 1, 1)
+INSERT INTO instances (id, node_id, name, architecture, type, project_id) VALUES (1, ?, 'foo', 1, 1, 1)
 `, id)
 	require.NoError(t, err)
 
@@ -307,7 +307,7 @@ func TestNodeWithLeastContainers(t *testing.T) {
 
 	// Add a container to the default node (ID 1)
 	_, err = tx.Tx().Exec(`
-INSERT INTO containers (id, node_id, name, architecture, type, project_id) VALUES (1, 1, 'foo', 1, 1, 1)
+INSERT INTO instances (id, node_id, name, architecture, type, project_id) VALUES (1, 1, 'foo', 1, 1, 1)
 `)
 	require.NoError(t, err)
 
@@ -327,7 +327,7 @@ func TestNodeWithLeastContainers_OfflineNode(t *testing.T) {
 
 	// Add a container to the newly created node.
 	_, err = tx.Tx().Exec(`
-INSERT INTO containers (id, node_id, name, architecture, type, project_id) VALUES (1, ?, 'foo', 1, 1, 1)
+INSERT INTO instances (id, node_id, name, architecture, type, project_id) VALUES (1, ?, 'foo', 1, 1, 1)
 `, id)
 	require.NoError(t, err)
 

From 7f5729259af8abe5ec62dacb2d82ecc4ed5dbf31 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 12:15:41 +0200
Subject: [PATCH 08/11] Drop unused Container and ContainerFilter structs

---
 lxd/db/containers.go | 30 +-----------------------------
 1 file changed, 1 insertion(+), 29 deletions(-)

diff --git a/lxd/db/containers.go b/lxd/db/containers.go
index 8b55bb8620..78bb27b164 100644
--- a/lxd/db/containers.go
+++ b/lxd/db/containers.go
@@ -63,34 +63,6 @@ import (
 //go:generate mapper method -p db -e instance Rename
 //go:generate mapper method -p db -e instance Delete
 
-// Container is a value object holding db-related details about a container.
-type Container struct {
-	ID           int
-	Project      string `db:"primary=yes&join=projects.name"`
-	Name         string `db:"primary=yes"`
-	Node         string `db:"join=nodes.name"`
-	Type         int
-	Architecture int
-	Ephemeral    bool
-	CreationDate time.Time
-	Stateful     bool
-	LastUseDate  time.Time
-	Description  string `db:"coalesce=''"`
-	Config       map[string]string
-	Devices      map[string]map[string]string
-	Profiles     []string
-	ExpiryDate   time.Time
-}
-
-// ContainerFilter can be used to filter results yielded by ContainerList.
-type ContainerFilter struct {
-	Project string
-	Name    string
-	Node    string
-	Parent  string
-	Type    int
-}
-
 // Instance is a value object holding db-related details about a container.
 type Instance struct {
 	ID           int
@@ -121,7 +93,7 @@ type InstanceFilter struct {
 
 // ContainerToArgs is a convenience to convert the new Container db struct into
 // the legacy ContainerArgs.
-func ContainerToArgs(container *Container) ContainerArgs {
+func ContainerToArgs(container *Instance) ContainerArgs {
 	args := ContainerArgs{
 		ID:           container.ID,
 		Project:      container.Project,

From df34715166d88d50a71e7d2ff87f95ad7a184a9c Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 12:19:44 +0200
Subject: [PATCH 09/11] Update top-level daemon package to new auto-generated
 db method names

---
 lxd/container.go             | 28 ++++++++++++++--------------
 lxd/container_lxc.go         | 12 ++++++------
 lxd/main_activateifneeded.go | 10 +++++-----
 lxd/profiles_utils.go        |  2 +-
 4 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/lxd/container.go b/lxd/container.go
index 10f9e39284..c3c874c294 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -12,8 +12,8 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
-	"gopkg.in/lxc/go-lxc.v2"
-	"gopkg.in/robfig/cron.v2"
+	lxc "gopkg.in/lxc/go-lxc.v2"
+	cron "gopkg.in/robfig/cron.v2"
 
 	"github.com/flosch/pongo2"
 	"github.com/lxc/lxd/lxd/cluster"
@@ -1101,7 +1101,7 @@ func containerCreateInternal(s *state.State, args db.ContainerArgs) (container,
 		args.LastUsedDate = time.Unix(0, 0).UTC()
 	}
 
-	var container db.Container
+	var container db.Instance
 	err = s.Cluster.Transaction(func(tx *db.ClusterTx) error {
 		node, err := tx.NodeName()
 		if err != nil {
@@ -1119,7 +1119,7 @@ func containerCreateInternal(s *state.State, args db.ContainerArgs) (container,
 		}
 
 		// Create the container entry
-		container = db.Container{
+		container = db.Instance{
 			Project:      args.Project,
 			Name:         args.Name,
 			Node:         node,
@@ -1136,13 +1136,13 @@ func containerCreateInternal(s *state.State, args db.ContainerArgs) (container,
 			ExpiryDate:   args.ExpiryDate,
 		}
 
-		_, err = tx.ContainerCreate(container)
+		_, err = tx.InstanceCreate(container)
 		if err != nil {
 			return errors.Wrap(err, "Add container info to the database")
 		}
 
 		// Read back the container, to get ID and creation time.
-		c, err := tx.ContainerGet(args.Project, args.Name)
+		c, err := tx.InstanceGet(args.Project, args.Name)
 		if err != nil {
 			return errors.Wrap(err, "Fetch created container from the database")
 		}
@@ -1239,11 +1239,11 @@ func containerLoadById(s *state.State, id int) (container, error) {
 
 func containerLoadByProjectAndName(s *state.State, project, name string) (container, error) {
 	// Get the DB record
-	var container *db.Container
+	var container *db.Instance
 	err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
 		var err error
 
-		container, err = tx.ContainerGet(project, name)
+		container, err = tx.InstanceGet(project, name)
 		if err != nil {
 			return errors.Wrapf(err, "Failed to fetch container %q in project %q", name, project)
 		}
@@ -1266,14 +1266,14 @@ func containerLoadByProjectAndName(s *state.State, project, name string) (contai
 
 func containerLoadByProject(s *state.State, project string) ([]container, error) {
 	// Get all the containers
-	var cts []db.Container
+	var cts []db.Instance
 	err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
-		filter := db.ContainerFilter{
+		filter := db.InstanceFilter{
 			Project: project,
 			Type:    int(db.CTypeRegular),
 		}
 		var err error
-		cts, err = tx.ContainerList(filter)
+		cts, err = tx.InstanceList(filter)
 		if err != nil {
 			return err
 		}
@@ -1320,7 +1320,7 @@ func containerLoadAll(s *state.State) ([]container, error) {
 // Load all containers of this nodes.
 func containerLoadNodeAll(s *state.State) ([]container, error) {
 	// Get all the container arguments
-	var cts []db.Container
+	var cts []db.Instance
 	err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
 		var err error
 		cts, err = tx.ContainerNodeList()
@@ -1340,7 +1340,7 @@ func containerLoadNodeAll(s *state.State) ([]container, error) {
 // Load all containers of this nodes under the given project.
 func containerLoadNodeProjectAll(s *state.State, project string) ([]container, error) {
 	// Get all the container arguments
-	var cts []db.Container
+	var cts []db.Instance
 	err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
 		var err error
 		cts, err = tx.ContainerNodeProjectList(project)
@@ -1357,7 +1357,7 @@ func containerLoadNodeProjectAll(s *state.State, project string) ([]container, e
 	return containerLoadAllInternal(cts, s)
 }
 
-func containerLoadAllInternal(cts []db.Container, s *state.State) ([]container, error) {
+func containerLoadAllInternal(cts []db.Instance, s *state.State) ([]container, error) {
 	// Figure out what profiles are in use
 	profiles := map[string]map[string]api.Profile{}
 	for _, cArgs := range cts {
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index e9e6b8f9a1..25e6789648 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -23,8 +23,8 @@ import (
 	"github.com/flosch/pongo2"
 	"github.com/pkg/errors"
 	"golang.org/x/sys/unix"
-	"gopkg.in/lxc/go-lxc.v2"
-	"gopkg.in/yaml.v2"
+	lxc "gopkg.in/lxc/go-lxc.v2"
+	yaml "gopkg.in/yaml.v2"
 
 	"github.com/lxc/lxd/lxd/cluster"
 	"github.com/lxc/lxd/lxd/db"
@@ -3661,7 +3661,7 @@ func (c *containerLXC) RenderState() (*api.ContainerState, error) {
 }
 
 func (c *containerLXC) Snapshots() ([]container, error) {
-	var snaps []db.Container
+	var snaps []db.Instance
 
 	// Get all the snapshots
 	err := c.state.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -4115,7 +4115,7 @@ func (c *containerLXC) Rename(newName string) error {
 
 	// Rename the database entry
 	err = c.state.Cluster.Transaction(func(tx *db.ClusterTx) error {
-		return tx.ContainerRename(c.project, oldName, newName)
+		return tx.InstanceRename(c.project, oldName, newName)
 	})
 	if err != nil {
 		logger.Error("Failed renaming container", ctxMap)
@@ -4143,7 +4143,7 @@ func (c *containerLXC) Rename(newName string) error {
 			baseSnapName := filepath.Base(sname)
 			newSnapshotName := newName + shared.SnapshotDelimiter + baseSnapName
 			err := c.state.Cluster.Transaction(func(tx *db.ClusterTx) error {
-				return tx.ContainerRename(c.project, sname, newSnapshotName)
+				return tx.InstanceRename(c.project, sname, newSnapshotName)
 			})
 			if err != nil {
 				logger.Error("Failed renaming container", ctxMap)
@@ -5317,7 +5317,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
 			return errors.Wrap(err, "Profiles insert")
 		}
 
-		err = db.DevicesAdd(tx, "container", int64(c.id), c.localDevices)
+		err = db.DevicesAdd(tx, "instance", int64(c.id), c.localDevices)
 		if err != nil {
 			tx.Rollback()
 			return errors.Wrap(err, "Device add")
diff --git a/lxd/main_activateifneeded.go b/lxd/main_activateifneeded.go
index 2bcde2d665..686a3df4fc 100644
--- a/lxd/main_activateifneeded.go
+++ b/lxd/main_activateifneeded.go
@@ -5,10 +5,10 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/mattn/go-sqlite3"
+	sqlite3 "github.com/mattn/go-sqlite3"
 	"github.com/spf13/cobra"
 
-	"github.com/lxc/lxd/client"
+	lxd "github.com/lxc/lxd/client"
 	"github.com/lxc/lxd/lxd/db"
 	"github.com/lxc/lxd/lxd/node"
 	"github.com/lxc/lxd/shared"
@@ -109,11 +109,11 @@ func (c *cmdActivateifneeded) Run(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	var containers []db.Container
+	var containers []db.Instance
 	err = d.cluster.Transaction(func(tx *db.ClusterTx) error {
-		filter := db.ContainerFilter{Type: int(db.CTypeRegular)}
+		filter := db.InstanceFilter{Type: int(db.CTypeRegular)}
 		var err error
-		containers, err = tx.ContainerList(filter)
+		containers, err = tx.InstanceList(filter)
 		return err
 	})
 	if err != nil {
diff --git a/lxd/profiles_utils.go b/lxd/profiles_utils.go
index 77328690a2..33d7d9a49d 100644
--- a/lxd/profiles_utils.go
+++ b/lxd/profiles_utils.go
@@ -234,7 +234,7 @@ func getProfileContainersInfo(cluster *db.Cluster, project, profile string) ([]d
 	err = cluster.Transaction(func(tx *db.ClusterTx) error {
 		for ctProject, ctNames := range names {
 			for _, ctName := range ctNames {
-				container, err := tx.ContainerGet(ctProject, ctName)
+				container, err := tx.InstanceGet(ctProject, ctName)
 				if err != nil {
 					return err
 				}

From a32aecc38e4d3ee227078fdf0979e3822f73698d Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 12:22:08 +0200
Subject: [PATCH 10/11] Update integration tests

---
 test/includes/lxd.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/test/includes/lxd.sh b/test/includes/lxd.sh
index 0e31fd0629..68a97dbc68 100644
--- a/test/includes/lxd.sh
+++ b/test/includes/lxd.sh
@@ -219,11 +219,11 @@ kill_lxd() {
         check_empty "${daemon_dir}/snapshots/"
 
         echo "==> Checking for leftover DB entries"
-        check_empty_table "${daemon_dir}/database/global/db.bin" "containers"
-        check_empty_table "${daemon_dir}/database/global/db.bin" "containers_config"
-        check_empty_table "${daemon_dir}/database/global/db.bin" "containers_devices"
-        check_empty_table "${daemon_dir}/database/global/db.bin" "containers_devices_config"
-        check_empty_table "${daemon_dir}/database/global/db.bin" "containers_profiles"
+        check_empty_table "${daemon_dir}/database/global/db.bin" "instances"
+        check_empty_table "${daemon_dir}/database/global/db.bin" "instances_config"
+        check_empty_table "${daemon_dir}/database/global/db.bin" "instances_devices"
+        check_empty_table "${daemon_dir}/database/global/db.bin" "instances_devices_config"
+        check_empty_table "${daemon_dir}/database/global/db.bin" "instances_profiles"
         check_empty_table "${daemon_dir}/database/global/db.bin" "images"
         check_empty_table "${daemon_dir}/database/global/db.bin" "images_aliases"
         check_empty_table "${daemon_dir}/database/global/db.bin" "images_properties"

From a67c0f5bc5342db5884da75be63cf7089ac44302 Mon Sep 17 00:00:00 2001
From: Free Ekanayaka <free.ekanayaka at canonical.com>
Date: Tue, 13 Aug 2019 13:04:45 +0200
Subject: [PATCH 11/11] Add unit test for creating a snapshot

---
 lxd/db/containers_test.go | 63 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/lxd/db/containers_test.go b/lxd/db/containers_test.go
index 50f9342ec6..97f77e34f0 100644
--- a/lxd/db/containers_test.go
+++ b/lxd/db/containers_test.go
@@ -257,6 +257,69 @@ func TestInstanceCreate(t *testing.T) {
 	assert.Equal(t, []string{"default"}, c1.Profiles)
 }
 
+func TestInstanceCreate_Snapshot(t *testing.T) {
+	tx, cleanup := db.NewTestClusterTx(t)
+	defer cleanup()
+
+	instance := db.Instance{
+		Project:      "default",
+		Name:         "foo",
+		Type:         0,
+		Node:         "none",
+		Architecture: 2,
+		Ephemeral:    false,
+		Stateful:     false,
+		LastUseDate:  time.Now(),
+		Description:  "container 1",
+		Config: map[string]string{
+			"image.architecture":  "x86_64",
+			"image.description":   "Busybox x86_64",
+			"image.name":          "busybox-x86_64",
+			"image.os":            "Busybox",
+			"volatile.base_image": "1f7f054e6ccb",
+		},
+		Devices:  map[string]map[string]string{},
+		Profiles: []string{"default"},
+	}
+
+	id, err := tx.InstanceCreate(instance)
+	require.NoError(t, err)
+
+	assert.Equal(t, int64(1), id)
+
+	snapshot := db.Instance{
+		Project:      "default",
+		Name:         "foo/snap0",
+		Type:         1,
+		Node:         "none",
+		Architecture: 2,
+		Ephemeral:    false,
+		Stateful:     false,
+		LastUseDate:  time.Now(),
+		Description:  "container 1",
+		Config: map[string]string{
+			"image.architecture":      "x86_64",
+			"image.description":       "Busybox x86_64",
+			"image.name":              "busybox-x86_64",
+			"image.os":                "Busybox",
+			"volatile.apply_template": "create",
+			"volatile.base_image":     "1f7f054e6ccb",
+			"volatile.eth0.hwaddr":    "00:16:3e:2a:3f:e2",
+			"volatile.idmap.base":     "0",
+		},
+		Devices:  map[string]map[string]string{},
+		Profiles: []string{"default"},
+	}
+
+	id, err = tx.InstanceCreate(snapshot)
+	require.NoError(t, err)
+
+	assert.Equal(t, int64(2), id)
+
+	_, err = tx.InstanceGet("default", "foo/snap0")
+	require.NoError(t, err)
+}
+
 // Containers are grouped by node address.
 func TestContainersListByNodeAddress(t *testing.T) {
 	tx, cleanup := db.NewTestClusterTx(t)


More information about the lxc-devel mailing list