The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6726

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===
This PR is the first step in providing a common base implementation of an `instance.Instance` in order to remove common code between LXC and Qemu implementations.

The aim of this PR is to expose generic instance related public functions on the `instance` package and move them out of main, e.g. `instance.Load()`.

However a challenge with this is that the `instance.Intstance` interface references itself with several functions that accept or return `instance.Instance`.

This means that when the drivers (LXC and Qemu) implement the interface they necessarily have to import the `instance` package. In addition the Qemu implementation (at least) also needs to access the generic loader functions for call back functionality.

In order to solve these issues the approach I have used is as follows:

1. Define an `instance/drivers` package - this will be where the `instance.Instance` implementations will live. They will be share the same package so that they can embed a common implementation to share common code (this will come later).
2. Moves the Qemu implementation into `instance/drivers` package.
3. Implements generic load and instantiation functions in the `instance/drivers` package and "pushes" those implementations into the `instance` package's exported API placeholder variables using the `init()` function. This provides the sane API of `instance.X()` rather than external users having to import the `instance/drivers` package.
4. Temporarily, whilst containerLXC still depends on the legacy storage package (and therefore cannot be moved out of `main`) use the same `init()` technique to "push" the `main` implementations of LXC load functions into the `instance/drivers` package into placeholder functions that will later be replaced with the real thing.


From ba732d69ae2a10339ac453b53dcf6d90666b53aa Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 11:32:52 +0000
Subject: [PATCH 01/17] lxd/instance: Moves vm qemu pkg into instance/drivers
 pkg

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/{qemu => drivers}/qmp/errors.go  | 0
 lxd/instance/{qemu => drivers}/qmp/monitor.go | 0
 lxd/instance/{qemu => drivers}/vm_qemu.go     | 4 ++--
 lxd/instance/{qemu => drivers}/vm_qemu_cmd.go | 2 +-
 4 files changed, 3 insertions(+), 3 deletions(-)
 rename lxd/instance/{qemu => drivers}/qmp/errors.go (100%)
 rename lxd/instance/{qemu => drivers}/qmp/monitor.go (100%)
 rename lxd/instance/{qemu => drivers}/vm_qemu.go (99%)
 rename lxd/instance/{qemu => drivers}/vm_qemu_cmd.go (98%)

diff --git a/lxd/instance/qemu/qmp/errors.go 
b/lxd/instance/drivers/qmp/errors.go
similarity index 100%
rename from lxd/instance/qemu/qmp/errors.go
rename to lxd/instance/drivers/qmp/errors.go
diff --git a/lxd/instance/qemu/qmp/monitor.go 
b/lxd/instance/drivers/qmp/monitor.go
similarity index 100%
rename from lxd/instance/qemu/qmp/monitor.go
rename to lxd/instance/drivers/qmp/monitor.go
diff --git a/lxd/instance/qemu/vm_qemu.go b/lxd/instance/drivers/vm_qemu.go
similarity index 99%
rename from lxd/instance/qemu/vm_qemu.go
rename to lxd/instance/drivers/vm_qemu.go
index e5e7690fbc..26cafea6f1 100644
--- a/lxd/instance/qemu/vm_qemu.go
+++ b/lxd/instance/drivers/vm_qemu.go
@@ -1,4 +1,4 @@
-package qemu
+package drivers
 
 import (
        "bytes"
@@ -29,8 +29,8 @@ import (
        "github.com/lxc/lxd/lxd/device"
        deviceConfig "github.com/lxc/lxd/lxd/device/config"
        "github.com/lxc/lxd/lxd/instance"
+       "github.com/lxc/lxd/lxd/instance/drivers/qmp"
        "github.com/lxc/lxd/lxd/instance/instancetype"
-       "github.com/lxc/lxd/lxd/instance/qemu/qmp"
        "github.com/lxc/lxd/lxd/maas"
        "github.com/lxc/lxd/lxd/operations"
        "github.com/lxc/lxd/lxd/project"
diff --git a/lxd/instance/qemu/vm_qemu_cmd.go 
b/lxd/instance/drivers/vm_qemu_cmd.go
similarity index 98%
rename from lxd/instance/qemu/vm_qemu_cmd.go
rename to lxd/instance/drivers/vm_qemu_cmd.go
index 15afc18908..2b117334f0 100644
--- a/lxd/instance/qemu/vm_qemu_cmd.go
+++ b/lxd/instance/drivers/vm_qemu_cmd.go
@@ -1,4 +1,4 @@
-package qemu
+package drivers
 
 import (
        "golang.org/x/sys/unix"

From a65f2adbe3499d66b973cf08031245639b8162bc Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:30:13 +0000
Subject: [PATCH 02/17] lxd/instance/drivers/container/lxc: Adds placeholder
 for future lxc implementation

Will be moved from main package.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/container_lxc.go | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 lxd/instance/drivers/container_lxc.go

diff --git a/lxd/instance/drivers/container_lxc.go 
b/lxd/instance/drivers/container_lxc.go
new file mode 100644
index 0000000000..2e067a435c
--- /dev/null
+++ b/lxd/instance/drivers/container_lxc.go
@@ -0,0 +1,21 @@
+package drivers
+
+import (
+       "github.com/lxc/lxd/lxd/db"
+       deviceConfig "github.com/lxc/lxd/lxd/device/config"
+       "github.com/lxc/lxd/lxd/instance"
+       "github.com/lxc/lxd/lxd/state"
+       "github.com/lxc/lxd/shared/api"
+)
+
+// LXCLoad is used to link containerLXCLoad from main package, it is temporary 
export until such time
+// as containerLXC can be moved into this package.
+var LXCLoad func(s *state.State, args db.InstanceArgs, profiles []api.Profile) 
(instance.Instance, error)
+
+// LXCInstantiate is used to link containerLXCInstantiate from main package, 
it is temporary export until such
+// time as containerLXC can be moved into this package.
+var LXCInstantiate func(s *state.State, args db.InstanceArgs, expandedDevices 
deviceConfig.Devices) instance.Instance
+
+// LXCCreate is used to link containerLXCCreate from main package, it is 
temporary export until such time
+// as containerLXC can be moved into this package.
+var LXCCreate func(s *state.State, args db.InstanceArgs) (instance.Instance, 
error)

From 43eb5051ef4f268525e4462dd71d32a9a2d7e713 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:30:42 +0000
Subject: [PATCH 03/17] lxd/instance/drivers/load: Adds instance load functions

In order to allow use of these functions from the instance package, such that 
the API is the form of instance.Load() it uses the init() function to "push" 
the unexported implementations of the loader functions into the instance 
package.

This avoids circular imports and allows future refactoring without changing the 
API.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/load.go | 109 +++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)
 create mode 100644 lxd/instance/drivers/load.go

diff --git a/lxd/instance/drivers/load.go b/lxd/instance/drivers/load.go
new file mode 100644
index 0000000000..3be1dac60a
--- /dev/null
+++ b/lxd/instance/drivers/load.go
@@ -0,0 +1,109 @@
+package drivers
+
+import (
+       "fmt"
+
+       "github.com/pkg/errors"
+
+       "github.com/lxc/lxd/lxd/db"
+       "github.com/lxc/lxd/lxd/device"
+       deviceConfig "github.com/lxc/lxd/lxd/device/config"
+       "github.com/lxc/lxd/lxd/instance"
+       "github.com/lxc/lxd/lxd/instance/instancetype"
+       "github.com/lxc/lxd/lxd/state"
+       "github.com/lxc/lxd/shared"
+       "github.com/lxc/lxd/shared/api"
+)
+
+func init() {
+       // Expose load to the instance package, to avoid circular imports.
+       instance.Load = load
+
+       // Expose validDevices to the instance package, to avoid circular 
imports.
+       instance.ValidDevices = validDevices
+
+       // Expose create to the instance package, to avoid circular imports.
+       instance.Create = create
+}
+
+// load creates the underlying instance type struct and returns it as an 
Instance.
+func load(s *state.State, args db.InstanceArgs, profiles []api.Profile) 
(instance.Instance, error) {
+       var inst instance.Instance
+       var err error
+
+       if args.Type == instancetype.Container {
+               inst, err = LXCLoad(s, args, profiles)
+       } else if args.Type == instancetype.VM {
+               inst, err = qemuLoad(s, args, profiles)
+       } else {
+               return nil, fmt.Errorf("Invalid instance type for instance %s", 
args.Name)
+       }
+
+       if err != nil {
+               return nil, err
+       }
+
+       return inst, nil
+}
+
+// validDevices validate instance device configs.
+func validDevices(state *state.State, cluster *db.Cluster, instanceType 
instancetype.Type, instanceName string, devices deviceConfig.Devices, expanded 
bool) error {
+       // Empty device list
+       if devices == nil {
+               return nil
+       }
+
+       // Create temporary InstanceArgs, populate it's name, localDevices and 
expandedDevices properties based
+       // on the mode of validation occurring. In non-expanded validation 
expensive checks should be avoided.
+       instArgs := db.InstanceArgs{
+               Name:    instanceName,
+               Type:    instanceType,
+               Devices: devices.Clone(), // Prevent devices from modifying 
their config.
+       }
+
+       var expandedDevices deviceConfig.Devices
+       if expanded {
+               // The devices being validated are already expanded, so just 
use the same
+               // devices clone as we used for the main devices config.
+               expandedDevices = instArgs.Devices
+       }
+
+       // Create a temporary Instance for use in device validation.
+       var inst instance.Instance
+       if instArgs.Type == instancetype.Container {
+               LXCInstantiate(state, instArgs, expandedDevices)
+       } else if instArgs.Type == instancetype.VM {
+               qemuInstantiate(state, instArgs, expandedDevices)
+       } else {
+               return fmt.Errorf("Invalid instance type")
+       }
+
+       // Check each device individually using the device package.
+       for name, config := range devices {
+               _, err := device.New(inst, state, name, config, nil, nil)
+               if err != nil {
+                       return errors.Wrapf(err, "Device validation failed %q", 
name)
+               }
+
+       }
+
+       // Check we have a root disk if in expanded validation mode.
+       if expanded {
+               _, _, err := shared.GetRootDiskDevice(devices.CloneNative())
+               if err != nil {
+                       return errors.Wrap(err, "Failed detecting root disk 
device")
+               }
+       }
+
+       return nil
+}
+
+func create(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
+       if args.Type == instancetype.Container {
+               return LXCCreate(s, args)
+       } else if args.Type == instancetype.VM {
+               return qemuCreate(s, args)
+       }
+
+       return nil, fmt.Errorf("Instance type invalid")
+}

From 49df11131c0d3ec351eb0a710f4fd1c3bc745cd4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:32:47 +0000
Subject: [PATCH 04/17] lxd/container: Removes unused functions

These have been moved into instance/drivers package.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/container.go | 103 -----------------------------------------------
 1 file changed, 103 deletions(-)

diff --git a/lxd/container.go b/lxd/container.go
index b912804b1c..a53477fc9c 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -23,7 +23,6 @@ import (
        deviceConfig "github.com/lxc/lxd/lxd/device/config"
        "github.com/lxc/lxd/lxd/instance"
        "github.com/lxc/lxd/lxd/instance/instancetype"
-       "github.com/lxc/lxd/lxd/instance/qemu"
        "github.com/lxc/lxd/lxd/operations"
        "github.com/lxc/lxd/lxd/project"
        "github.com/lxc/lxd/lxd/state"
@@ -51,14 +50,6 @@ func init() {
        device.InstanceLoadByProjectAndName = func(s *state.State, project, 
name string) (instance.Instance, error) {
                return instance.LoadByProjectAndName(s, project, name)
        }
-
-       // Expose instanceValidDevices to the instance package. This is because 
it relies on
-       // containerLXC which cannot be moved out of main package at this time.
-       instance.ValidDevices = instanceValidDevices
-
-       // Expose instanceLoad to the instance package. This is because it 
relies on containerLXC
-       // which cannot be moved out of main package this time.
-       instance.Load = instanceLoad
 }
 
 // Helper functions
@@ -77,68 +68,6 @@ func containerValidName(name string) error {
        return nil
 }
 
-// instanceValidDevices validate instance device configs.
-func instanceValidDevices(state *state.State, cluster *db.Cluster, 
instanceType instancetype.Type, instanceName string, devices 
deviceConfig.Devices, expanded bool) error {
-       // Empty device list
-       if devices == nil {
-               return nil
-       }
-
-       // Create a temporary Instance for use in device validation.
-       // Populate it's name, localDevices and expandedDevices properties 
based on the mode of
-       // validation occurring. In non-expanded validation expensive checks 
should be avoided.
-       var inst instance.Instance
-
-       if instanceType == instancetype.Container {
-               c := &containerLXC{
-                       dbType:       instancetype.Container,
-                       name:         instanceName,
-                       localDevices: devices.Clone(), // Prevent devices from 
modifying their config.
-               }
-
-               if expanded {
-                       c.expandedDevices = c.localDevices // Avoid another 
clone.
-               }
-
-               inst = c
-       } else if instanceType == instancetype.VM {
-               instArgs := db.InstanceArgs{
-                       Name:    instanceName,
-                       Type:    instancetype.VM,
-                       Devices: devices.Clone(), // Prevent devices from 
modifying their config.
-               }
-
-               if expanded {
-                       // The devices being validated are already expanded, so 
just use the same
-                       // devices clone as we used for the main devices config.
-                       inst = qemu.Instantiate(state, instArgs, 
instArgs.Devices)
-               } else {
-                       inst = qemu.Instantiate(state, instArgs, nil)
-               }
-       } else {
-               return fmt.Errorf("Invalid instance type")
-       }
-
-       // Check each device individually using the device package.
-       for name, config := range devices {
-               _, err := device.New(inst, state, name, config, nil, nil)
-               if err != nil {
-                       return errors.Wrapf(err, "Device validation failed %q", 
name)
-               }
-
-       }
-
-       // Check we have a root disk if in expanded validation mode.
-       if expanded {
-               _, _, err := shared.GetRootDiskDevice(devices.CloneNative())
-               if err != nil {
-                       return errors.Wrap(err, "Failed detecting root disk 
device")
-               }
-       }
-
-       return nil
-}
-
 // instanceCreateAsEmpty creates an empty instance.
 func instanceCreateAsEmpty(d *Daemon, args db.InstanceArgs) 
(instance.Instance, error) {
        // Create the instance record.
@@ -931,18 +860,6 @@ func instanceCreateInternal(s *state.State, args 
db.InstanceArgs) (instance.Inst
        // Wipe any existing log for this instance name.
        os.RemoveAll(shared.LogPath(args.Name))
 
-       args = db.ContainerToArgs(&dbInst)
-
-       var inst instance.Instance
-
-       if args.Type == instancetype.Container {
-               inst, err = containerLXCCreate(s, args)
-       } else if args.Type == instancetype.VM {
-               inst, err = qemu.Create(s, args)
-       } else {
-               return nil, fmt.Errorf("Instance type invalid")
-       }
-
        if err != nil {
                return nil, errors.Wrap(err, "Create instance")
        }
@@ -1167,26 +1084,6 @@ func instanceLoadAllInternal(dbInstances []db.Instance, 
s *state.State) ([]insta
        return instances, nil
 }
 
-// instanceLoad creates the underlying instance type struct and returns it as 
an Instance.
-func instanceLoad(s *state.State, args db.InstanceArgs, profiles 
[]api.Profile) (instance.Instance, error) {
-       var inst instance.Instance
-       var err error
-
-       if args.Type == instancetype.Container {
-               inst, err = containerLXCLoad(s, args, profiles)
-       } else if args.Type == instancetype.VM {
-               inst, err = qemu.Load(s, args, profiles)
-       } else {
-               return nil, fmt.Errorf("Invalid instance type for instance %s", 
args.Name)
-       }
-
-       if err != nil {
-               return nil, err
-       }
-
-       return inst, nil
-}
-
 func autoCreateContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
        f := func(ctx context.Context) {
                // Load all local instances

From b795e4263f8eb1854598f027c8a61e88326966a2 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:29:09 +0000
Subject: [PATCH 05/17] lxd/db/containers: Renames ContainerToArgs to
 InstanceToArgs

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/db/containers.go | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/lxd/db/containers.go b/lxd/db/containers.go
index 351a37b6ab..7f0864fce2 100644
--- a/lxd/db/containers.go
+++ b/lxd/db/containers.go
@@ -102,26 +102,25 @@ type InstanceFilter struct {
        Type    instancetype.Type
 }
 
-// ContainerToArgs is a convenience to convert the new Container db struct into
-// the legacy InstanceArgs.
-func ContainerToArgs(container *Instance) InstanceArgs {
+// InstanceToArgs is a convenience to convert an Instance db struct into the 
legacy InstanceArgs.
+func InstanceToArgs(inst *Instance) InstanceArgs {
        args := InstanceArgs{
-               ID:           container.ID,
-               Project:      container.Project,
-               Name:         container.Name,
-               Node:         container.Node,
-               Type:         container.Type,
-               Snapshot:     container.Snapshot,
-               Architecture: container.Architecture,
-               Ephemeral:    container.Ephemeral,
-               CreationDate: container.CreationDate,
-               Stateful:     container.Stateful,
-               LastUsedDate: container.LastUseDate,
-               Description:  container.Description,
-               Config:       container.Config,
-               Devices:      deviceConfig.NewDevices(container.Devices),
-               Profiles:     container.Profiles,
-               ExpiryDate:   container.ExpiryDate,
+               ID:           inst.ID,
+               Project:      inst.Project,
+               Name:         inst.Name,
+               Node:         inst.Node,
+               Type:         inst.Type,
+               Snapshot:     inst.Snapshot,
+               Architecture: inst.Architecture,
+               Ephemeral:    inst.Ephemeral,
+               CreationDate: inst.CreationDate,
+               Stateful:     inst.Stateful,
+               LastUsedDate: inst.LastUseDate,
+               Description:  inst.Description,
+               Config:       inst.Config,
+               Devices:      deviceConfig.NewDevices(inst.Devices),
+               Profiles:     inst.Profiles,
+               ExpiryDate:   inst.ExpiryDate,
        }
 
        if args.Devices == nil {

From cd0ac1c9e92e42b8cc21c4e872ff63b0ffe0d744 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:34:39 +0000
Subject: [PATCH 06/17] lxd/container: db.InstanceToArgs usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/container.go | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lxd/container.go b/lxd/container.go
index a53477fc9c..b8281e8114 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -860,6 +860,8 @@ func instanceCreateInternal(s *state.State, args 
db.InstanceArgs) (instance.Inst
        // Wipe any existing log for this instance name.
        os.RemoveAll(shared.LogPath(args.Name))
 
+       args = db.InstanceToArgs(&dbInst)
+       inst, err := instance.Create(s, args)
        if err != nil {
                return nil, errors.Wrap(err, "Create instance")
        }
@@ -1072,8 +1074,8 @@ func instanceLoadAllInternal(dbInstances []db.Instance, s 
*state.State) ([]insta
                        cProfiles = append(cProfiles, 
profiles[dbInstance.Project][name])
                }
 
-               args := db.ContainerToArgs(&dbInstance)
-               inst, err := instanceLoad(s, args, cProfiles)
+               args := db.InstanceToArgs(&dbInstance)
+               inst, err := instance.Load(s, args, cProfiles)
                if err != nil {
                        return nil, err
                }

From c6ab89ee304e461c248c70d1259a3f46ab388ea0 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:35:20 +0000
Subject: [PATCH 07/17] lxd/profiles/utils: db.InstanceToArgs usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/profiles_utils.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/profiles_utils.go b/lxd/profiles_utils.go
index 3242167c7f..bc2c5e32e8 100644
--- a/lxd/profiles_utils.go
+++ b/lxd/profiles_utils.go
@@ -246,7 +246,7 @@ func getProfileContainersInfo(cluster *db.Cluster, project, 
profile string) ([]d
                                        return err
                                }
 
-                               containers = append(containers, 
db.ContainerToArgs(container))
+                               containers = append(containers, 
db.InstanceToArgs(container))
                        }
                }
 

From 14702a0b43d306ea732d0ff2942840026ca76df6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:36:20 +0000
Subject: [PATCH 08/17] lxd/profiles/utils: Updates use of
 containerLXCInstantiate

Because containerLXCInstantiate has been changes to return an 
instance.Instance, we must cast it back to containerLXC to use here.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/profiles_utils.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/profiles_utils.go b/lxd/profiles_utils.go
index bc2c5e32e8..b2e00869e4 100644
--- a/lxd/profiles_utils.go
+++ b/lxd/profiles_utils.go
@@ -209,10 +209,10 @@ func doProfileUpdateContainer(d *Daemon, name string, old 
api.ProfilePut, nodeNa
                }
        }
 
-       c := containerLXCInstantiate(d.State(), args)
+       c := containerLXCInstantiate(d.State(), args, nil)
 
-       c.expandConfig(profiles)
-       c.expandDevices(profiles)
+       c.(*containerLXC).expandConfig(profiles)
+       c.(*containerLXC).expandDevices(profiles)
 
        return c.Update(db.InstanceArgs{
                Architecture: c.Architecture(),

From 0856907290e7738058c1ceba182badf9fe383bb4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:37:45 +0000
Subject: [PATCH 09/17] lxd/container/lxc: Push containerLXC load functions
 into instance/drivers package

This allows them to be used with the generic instance load functions.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/container_lxc.go | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 90b6f49508..e705930b64 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -34,6 +34,7 @@ import (
        "github.com/lxc/lxd/lxd/device"
        deviceConfig "github.com/lxc/lxd/lxd/device/config"
        "github.com/lxc/lxd/lxd/instance"
+       instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
        "github.com/lxc/lxd/lxd/instance/instancetype"
        "github.com/lxc/lxd/lxd/instance/operationlock"
        "github.com/lxc/lxd/lxd/maas"
@@ -56,6 +57,15 @@ import (
        "github.com/lxc/lxd/shared/units"
 )
 
+func init() {
+       // Temporarily link containerLXC load functions to instanceDrivers 
package so it can be used by the
+       // internal loader functions. These can be removed once containerLXC 
type is moved into the
+       // instance/drivers package.
+       instanceDrivers.LXCLoad = containerLXCLoad
+       instanceDrivers.LXCInstantiate = containerLXCInstantiate
+       instanceDrivers.LXCCreate = containerLXCCreate
+}
+
 // Helper functions
 func lxcSetConfigItem(c *lxc.Container, key string, value string) error {
        if c == nil {

From 241b87883ff3e9bdd47289d38fa5be0a0e972c1e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:38:18 +0000
Subject: [PATCH 10/17] lxd/container/lxc: containerLXCInstantiate usage

Updates use of containerLXCInstantiate now that the return signature has 
changed.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/container_lxc.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index e705930b64..5370751d08 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -364,18 +364,18 @@ func containerLXCCreate(s *state.State, args 
db.InstanceArgs) (instance.Instance
 
 func containerLXCLoad(s *state.State, args db.InstanceArgs, profiles 
[]api.Profile) (instance.Instance, error) {
        // Create the container struct
-       c := containerLXCInstantiate(s, args)
+       c := containerLXCInstantiate(s, args, nil)
 
        // Setup finalizer
        runtime.SetFinalizer(c, containerLXCUnload)
 
        // Expand config and devices
-       err := c.expandConfig(profiles)
+       err := c.(*containerLXC).expandConfig(profiles)
        if err != nil {
                return nil, err
        }
 
-       err = c.expandDevices(profiles)
+       err = c.(*containerLXC).expandDevices(profiles)
        if err != nil {
                return nil, err
        }

From d5a3ebd7c3f9f794c696db9963c6c7976420482f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:38:42 +0000
Subject: [PATCH 11/17] lxd/container/lxc: Makes containerLXCInstantiate
 compatiable with generic instance load functions

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/container_lxc.go | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 5370751d08..ba32e1ed86 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -393,7 +393,7 @@ func containerLXCUnload(c *containerLXC) {
 }
 
 // Create a container struct without initializing it.
-func containerLXCInstantiate(s *state.State, args db.InstanceArgs) 
*containerLXC {
+func containerLXCInstantiate(s *state.State, args db.InstanceArgs, 
expandedDevices deviceConfig.Devices) instance.Instance {
        c := &containerLXC{
                state:        s,
                id:           args.ID,
@@ -427,6 +427,11 @@ func containerLXCInstantiate(s *state.State, args 
db.InstanceArgs) *containerLXC
                c.lastUsedDate = time.Time{}
        }
 
+       // This is passed during expanded config validation.
+       if expandedDevices != nil {
+               c.expandedDevices = expandedDevices
+       }
+
        return c
 }
 

From 965f45e2d501deb1e0eb52250a8d40ea575e554d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:39:14 +0000
Subject: [PATCH 12/17] lxd/containers: instance.Load usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/containers.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/containers.go b/lxd/containers.go
index 874848c612..fcf0ffbaa9 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -332,7 +332,7 @@ func containersShutdown(s *state.State) error {
 
                for project, names := range cnames {
                        for _, name := range names {
-                               inst, err := instanceLoad(s, db.InstanceArgs{
+                               inst, err := instance.Load(s, db.InstanceArgs{
                                        Project: project,
                                        Name:    name,
                                        Config:  make(map[string]string),

From c58934fd58582f07a6e46c8ebf5b6922e68025b5 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:39:28 +0000
Subject: [PATCH 13/17] lxd/containers/post: instance.Load usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/containers_post.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 975f4726d8..a13838351b 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -296,7 +296,7 @@ func createFromMigration(d *Daemon, project string, req 
*api.InstancesPost) resp
                                }
                        } else {
                                // Retrieve the future storage pool.
-                               tmpInst, err := instanceLoad(d.State(), args, 
nil)
+                               tmpInst, err := instance.Load(d.State(), args, 
nil)
                                if err != nil {
                                        return response.InternalError(err)
                                }

From 32e908b34d6f6ca439690047c8c015fc8cb03725 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:40:44 +0000
Subject: [PATCH 14/17] lxd/instance/drivers/vm/qemu: Unexport and rename load
 functions

Now that qemu implementation shares the same package as the lxc future 
implementation, namespace the qemu specific load functions.

Also unexports them so they externally only generic instance load functions can 
be used.

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/drivers/vm_qemu.go | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/lxd/instance/drivers/vm_qemu.go b/lxd/instance/drivers/vm_qemu.go
index 26cafea6f1..f514bfd249 100644
--- a/lxd/instance/drivers/vm_qemu.go
+++ b/lxd/instance/drivers/vm_qemu.go
@@ -53,10 +53,10 @@ var errQemuAgentOffline = fmt.Errorf("LXD VM agent isn't 
currently running")
 var vmConsole = map[int]bool{}
 var vmConsoleLock sync.Mutex
 
-// Load creates a Qemu instance from the supplied InstanceArgs.
-func Load(s *state.State, args db.InstanceArgs, profiles []api.Profile) 
(instance.Instance, error) {
+// qemuLoad creates a Qemu instance from the supplied InstanceArgs.
+func qemuLoad(s *state.State, args db.InstanceArgs, profiles []api.Profile) 
(instance.Instance, error) {
        // Create the instance struct.
-       vm := Instantiate(s, args, nil)
+       vm := qemuInstantiate(s, args, nil)
 
        // Expand config and devices.
        err := vm.expandConfig(profiles)
@@ -72,10 +72,10 @@ func Load(s *state.State, args db.InstanceArgs, profiles 
[]api.Profile) (instanc
        return vm, nil
 }
 
-// Instantiate creates a Qemu struct without expanding config. The 
expandedDevices argument is
+// qemuInstantiate creates a Qemu struct without expanding config. The 
expandedDevices argument is
 // used during device config validation when the devices have already been 
expanded and we do not
 // have access to the profiles used to do it. This can be safely passed as nil 
if not required.
-func Instantiate(s *state.State, args db.InstanceArgs, expandedDevices 
deviceConfig.Devices) *Qemu {
+func qemuInstantiate(s *state.State, args db.InstanceArgs, expandedDevices 
deviceConfig.Devices) *Qemu {
        vm := &Qemu{
                state:        s,
                id:           args.ID,
@@ -117,8 +117,8 @@ func Instantiate(s *state.State, args db.InstanceArgs, 
expandedDevices deviceCon
        return vm
 }
 
-// Create creates a new storage volume record and returns an initialised 
Instance.
-func Create(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
+// qemuCreate creates a new storage volume record and returns an initialised 
Instance.
+func qemuCreate(s *state.State, args db.InstanceArgs) (instance.Instance, 
error) {
        // Create the instance struct.
        vm := &Qemu{
                state:        s,

From f1440dfb57cbabd22242ff11c16efc94c7ceb2ae Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:42:21 +0000
Subject: [PATCH 15/17] lxd/instance/instance/utils: Load function comments

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/instance_utils.go | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/lxd/instance/instance_utils.go b/lxd/instance/instance_utils.go
index 3dc21d5537..939df5bf3d 100644
--- a/lxd/instance/instance_utils.go
+++ b/lxd/instance/instance_utils.go
@@ -35,12 +35,10 @@ import (
 // ProfileValidationName is an indicator that the instance is just being used 
for profile validation.
 const ProfileValidationName = ""
 
-// ValidDevices is linked from main.instanceValidDevices to validate device 
config. Currently
-// main.instanceValidDevices uses containerLXC internally and so cannot be 
moved from main package.
+// ValidDevices is linked from instance/load.validDevices to validate device 
config.
 var ValidDevices func(state *state.State, cluster *db.Cluster, instanceType 
instancetype.Type, instanceName string, devices deviceConfig.Devices, expanded 
bool) error
 
-// Load is linked from main.instanceLoad to allow different instance types to 
be load,
-// including containerLXC which currently cannot be moved from main package.
+// Load is linked from instance/load.load to allow different instance types to 
be loaded.
 var Load func(s *state.State, args db.InstanceArgs, profiles []api.Profile) 
(Instance, error)
 
 // NetworkGetLeaseAddresses is linked from main.networkGetLeaseAddresses to 
limit scope of moving

From e20f97df78e12e2c6ff1b448b6ec11c44e8637e0 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:42:35 +0000
Subject: [PATCH 16/17] lxd/instance/instance/utils: Adds Create instance
 function placeholder

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/instance_utils.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lxd/instance/instance_utils.go b/lxd/instance/instance_utils.go
index 939df5bf3d..72ca76f6d8 100644
--- a/lxd/instance/instance_utils.go
+++ b/lxd/instance/instance_utils.go
@@ -41,6 +41,9 @@ var ValidDevices func(state *state.State, cluster 
*db.Cluster, instanceType inst
 // Load is linked from instance/load.load to allow different instance types to 
be loaded.
 var Load func(s *state.State, args db.InstanceArgs, profiles []api.Profile) 
(Instance, error)
 
+// Create is linked from instance/load.create to allow difference instance 
types to be created.
+var Create func(s *state.State, args db.InstanceArgs) (Instance, error)
+
 // NetworkGetLeaseAddresses is linked from main.networkGetLeaseAddresses to 
limit scope of moving
 // network related functions into their own package at this time.
 var NetworkGetLeaseAddresses func(s *state.State, network string, hwaddr 
string) ([]api.InstanceStateNetworkAddress, error)

From 58c7c6ff06a0a84449d438a325a024b628c50e16 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Fri, 17 Jan 2020 15:42:57 +0000
Subject: [PATCH 17/17] lxd/instance/instance/utils: db.InstanceToArgs usage

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/instance/instance_utils.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lxd/instance/instance_utils.go b/lxd/instance/instance_utils.go
index 72ca76f6d8..86a0b3724e 100644
--- a/lxd/instance/instance_utils.go
+++ b/lxd/instance/instance_utils.go
@@ -456,7 +456,7 @@ func LoadByProjectAndName(s *state.State, project, name 
string) (Instance, error
                return nil, err
        }
 
-       args := db.ContainerToArgs(container)
+       args := db.InstanceToArgs(container)
        inst, err := Load(s, args, nil)
        if err != nil {
                return nil, errors.Wrap(err, "Failed to load container")
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to