[lxc-devel] [lxd/master] VM Qemu base
tomponline on Github
lxc-bot at linuxcontainers.org
Tue Sep 17 10:00:51 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 553 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190917/ab5c9cce/attachment-0001.bin>
-------------- next part --------------
From 32905cc9c26be901e976c8f6aab6e4714f28d0f6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Mon, 16 Sep 2019 17:55:10 +0100
Subject: [PATCH 1/6] lxd: Renames containerLoadNodeAll to instanceLoadNodeAll
- And changes return type to []Instance
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container.go | 108 ++++++++++++++++++-----------------
lxd/container_lxc.go | 4 +-
lxd/containers.go | 42 +++++++-------
lxd/containers_get.go | 6 +-
lxd/daemon.go | 6 +-
lxd/devices.go | 38 ++++++------
lxd/devlxd.go | 14 +++--
lxd/networks.go | 45 ++++++++-------
lxd/networks_utils.go | 25 ++++----
lxd/storage_volumes_utils.go | 45 +++++++--------
10 files changed, 173 insertions(+), 160 deletions(-)
diff --git a/lxd/container.go b/lxd/container.go
index de03c8e5c6..45c7687dba 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -35,10 +35,10 @@ import (
)
func init() {
- // Expose containerLoadNodeAll to the device package converting the response to a slice of InstanceIdentifiers.
+ // Expose instanceLoadNodeAll to the device package converting the response to a slice of InstanceIdentifiers.
// This is because container types are defined in the main package and are not importable.
device.InstanceLoadNodeAll = func(s *state.State) ([]device.InstanceIdentifier, error) {
- containers, err := containerLoadNodeAll(s)
+ containers, err := instanceLoadNodeAll(s)
if err != nil {
return nil, err
}
@@ -994,7 +994,7 @@ func instanceLoadByProjectAndName(s *state.State, project, name string) (Instanc
return c, nil
}
-func containerLoadByProject(s *state.State, project string) ([]container, error) {
+func instanceLoadByProject(s *state.State, project string) ([]Instance, error) {
// Get all the containers
var cts []db.Instance
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1014,11 +1014,11 @@ func containerLoadByProject(s *state.State, project string) ([]container, error)
return nil, err
}
- return containerLoadAllInternal(cts, s)
+ return instanceLoadAllInternal(cts, s)
}
-// Load all containers across all projects.
-func containerLoadFromAllProjects(s *state.State) ([]container, error) {
+// Load all instances across all projects.
+func instanceLoadFromAllProjects(s *state.State) ([]Instance, error) {
var projects []string
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1030,25 +1030,25 @@ func containerLoadFromAllProjects(s *state.State) ([]container, error) {
return nil, err
}
- containers := []container{}
+ instances := []Instance{}
for _, project := range projects {
- projectContainers, err := containerLoadByProject(s, project)
+ projectInstances, err := instanceLoadByProject(s, project)
if err != nil {
- return nil, errors.Wrapf(nil, "Load containers in project %s", project)
+ return nil, errors.Wrapf(nil, "Load instances in project %s", project)
}
- containers = append(containers, projectContainers...)
+ instances = append(instances, projectInstances...)
}
- return containers, nil
+ return instances, nil
}
// Legacy interface.
-func containerLoadAll(s *state.State) ([]container, error) {
- return containerLoadByProject(s, "default")
+func instanceLoadAll(s *state.State) ([]Instance, error) {
+ return instanceLoadByProject(s, "default")
}
-// Load all containers of this nodes.
-func containerLoadNodeAll(s *state.State) ([]container, error) {
+// Load all instances of this nodes.
+func instanceLoadNodeAll(s *state.State) ([]Instance, error) {
// Get all the container arguments
var cts []db.Instance
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1064,11 +1064,11 @@ func containerLoadNodeAll(s *state.State) ([]container, error) {
return nil, err
}
- return containerLoadAllInternal(cts, s)
+ return instanceLoadAllInternal(cts, s)
}
-// Load all containers of this nodes under the given project.
-func containerLoadNodeProjectAll(s *state.State, project string, instanceType instance.Type) ([]container, error) {
+// Load all instances of this nodes under the given project.
+func instanceLoadNodeProjectAll(s *state.State, project string, instanceType instance.Type) ([]Instance, error) {
// Get all the container arguments
var cts []db.Instance
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1084,19 +1084,19 @@ func containerLoadNodeProjectAll(s *state.State, project string, instanceType in
return nil, err
}
- return containerLoadAllInternal(cts, s)
+ return instanceLoadAllInternal(cts, s)
}
-func containerLoadAllInternal(cts []db.Instance, s *state.State) ([]container, error) {
+func instanceLoadAllInternal(dbInstances []db.Instance, s *state.State) ([]Instance, error) {
// Figure out what profiles are in use
profiles := map[string]map[string]api.Profile{}
- for _, cArgs := range cts {
- projectProfiles, ok := profiles[cArgs.Project]
+ for _, instArgs := range dbInstances {
+ projectProfiles, ok := profiles[instArgs.Project]
if !ok {
projectProfiles = map[string]api.Profile{}
- profiles[cArgs.Project] = projectProfiles
+ profiles[instArgs.Project] = projectProfiles
}
- for _, profile := range cArgs.Profiles {
+ for _, profile := range instArgs.Profiles {
_, ok := projectProfiles[profile]
if !ok {
projectProfiles[profile] = api.Profile{}
@@ -1116,26 +1116,30 @@ func containerLoadAllInternal(cts []db.Instance, s *state.State) ([]container, e
}
}
- // Load the container structs
- containers := []container{}
- for _, container := range cts {
- // Figure out the container's profiles
+ // Load the instances structs
+ instances := []Instance{}
+ for _, dbInstance := range dbInstances {
+ // Figure out the instances's profiles
cProfiles := []api.Profile{}
- for _, name := range container.Profiles {
- cProfiles = append(cProfiles, profiles[container.Project][name])
+ for _, name := range dbInstance.Profiles {
+ cProfiles = append(cProfiles, profiles[dbInstance.Project][name])
}
- args := db.ContainerToArgs(&container)
-
- ct, err := containerLXCLoad(s, args, cProfiles)
- if err != nil {
- return nil, err
+ if dbInstance.Type == instance.TypeContainer {
+ args := db.ContainerToArgs(&dbInstance)
+ ct, err := containerLXCLoad(s, args, cProfiles)
+ if err != nil {
+ return nil, err
+ }
+ instances = append(instances, ct)
+ } else {
+ // TODO add virtual machine load here.
+ continue
}
- containers = append(containers, ct)
}
- return containers, nil
+ return instances, nil
}
func containerCompareSnapshots(source Instance, target Instance) ([]Instance, []Instance, error) {
@@ -1190,15 +1194,15 @@ func containerCompareSnapshots(source Instance, target Instance) ([]Instance, []
func autoCreateContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
f := func(ctx context.Context) {
- // Load all local containers
- allContainers, err := containerLoadNodeAll(d.State())
+ // Load all local instances
+ allContainers, err := instanceLoadNodeAll(d.State())
if err != nil {
logger.Error("Failed to load containers for scheduled snapshots", log.Ctx{"err": err})
return
}
// Figure out which need snapshotting (if any)
- containers := []container{}
+ instances := []Instance{}
for _, c := range allContainers {
schedule := c.ExpandedConfig()["snapshots.schedule"]
@@ -1237,15 +1241,15 @@ func autoCreateContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
continue
}
- containers = append(containers, c)
+ instances = append(instances, c)
}
- if len(containers) == 0 {
+ if len(instances) == 0 {
return
}
opRun := func(op *operation) error {
- return autoCreateContainerSnapshots(ctx, d, containers)
+ return autoCreateContainerSnapshots(ctx, d, instances)
}
op, err := operationCreate(d.cluster, "", operationClassTask, db.OperationSnapshotCreate, nil, nil, opRun, nil, nil)
@@ -1279,9 +1283,9 @@ func autoCreateContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
return f, schedule
}
-func autoCreateContainerSnapshots(ctx context.Context, d *Daemon, containers []container) error {
+func autoCreateContainerSnapshots(ctx context.Context, d *Daemon, instances []Instance) error {
// Make the snapshots
- for _, c := range containers {
+ for _, c := range instances {
ch := make(chan error)
go func() {
snapshotName, err := containerDetermineNextSnapshotName(d, c, "snap%d")
@@ -1333,16 +1337,16 @@ func autoCreateContainerSnapshots(ctx context.Context, d *Daemon, containers []c
func pruneExpiredContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
f := func(ctx context.Context) {
- // Load all local containers
- allContainers, err := containerLoadNodeAll(d.State())
+ // Load all local instances
+ allInstances, err := instanceLoadNodeAll(d.State())
if err != nil {
- logger.Error("Failed to load containers for snapshot expiry", log.Ctx{"err": err})
+ logger.Error("Failed to load instances for snapshot expiry", log.Ctx{"err": err})
return
}
// Figure out which need snapshotting (if any)
expiredSnapshots := []Instance{}
- for _, c := range allContainers {
+ for _, c := range allInstances {
snapshots, err := c.Snapshots()
if err != nil {
logger.Error("Failed to list snapshots", log.Ctx{"err": err, "container": c.Name(), "project": c.Project()})
@@ -1375,14 +1379,14 @@ func pruneExpiredContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
return
}
- logger.Info("Pruning expired container snapshots")
+ logger.Info("Pruning expired instance snapshots")
_, err = op.Run()
if err != nil {
- logger.Error("Failed to remove expired container snapshots", log.Ctx{"err": err})
+ logger.Error("Failed to remove expired instance snapshots", log.Ctx{"err": err})
}
- logger.Info("Done pruning expired container snapshots")
+ logger.Info("Done pruning expired instance snapshots")
}
first := true
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index e48c4f1a86..93b7beaf06 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -867,7 +867,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
idmapLock.Lock()
defer idmapLock.Unlock()
- cts, err := containerLoadAll(state)
+ cts, err := instanceLoadAll(state)
if err != nil {
return nil, 0, err
}
@@ -3391,7 +3391,7 @@ func (c *containerLXC) Snapshots() ([]Instance, error) {
}
// Build the snapshot list
- containers, err := containerLoadAllInternal(snaps, c.state)
+ containers, err := instanceLoadAllInternal(snaps, c.state)
if err != nil {
return nil, err
}
diff --git a/lxd/containers.go b/lxd/containers.go
index 8272242d6b..a340642a00 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -141,7 +141,7 @@ var instanceBackupExportCmd = APIEndpoint{
Get: APIEndpointAction{Handler: containerBackupExportGet, AccessHandler: AllowProjectPermission("containers", "view")},
}
-type containerAutostartList []container
+type containerAutostartList []Instance
func (slice containerAutostartList) Len() int {
return len(slice)
@@ -165,22 +165,22 @@ func (slice containerAutostartList) Swap(i, j int) {
}
func containersRestart(s *state.State) error {
- // Get all the containers
- result, err := containerLoadNodeAll(s)
+ // Get all the instances
+ result, err := instanceLoadNodeAll(s)
if err != nil {
return err
}
- containers := []container{}
+ instances := []Instance{}
for _, c := range result {
- containers = append(containers, c)
+ instances = append(instances, c)
}
- sort.Sort(containerAutostartList(containers))
+ sort.Sort(containerAutostartList(instances))
- // Restart the containers
- for _, c := range containers {
+ // Restart the instances
+ for _, c := range instances {
config := c.ExpandedConfig()
lastState := config["volatile.last_state.power"]
@@ -207,7 +207,7 @@ func containersRestart(s *state.State) error {
return nil
}
-type containerStopList []container
+type containerStopList []Instance
func (slice containerStopList) Len() int {
return len(slice)
@@ -263,12 +263,12 @@ func containersShutdown(s *state.State) error {
dbAvailable := true
- // Get all the containers
- containers, err := containerLoadNodeAll(s)
+ // Get all the instances
+ instances, err := instanceLoadNodeAll(s)
if err != nil {
// Mark database as offline
dbAvailable = false
- containers = []container{}
+ instances = []Instance{}
// List all containers on disk
cnames, err := containersOnDisk()
@@ -287,12 +287,12 @@ func containersShutdown(s *state.State) error {
return err
}
- containers = append(containers, c)
+ instances = append(instances, c)
}
}
}
- sort.Sort(containerStopList(containers))
+ sort.Sort(containerStopList(instances))
if dbAvailable {
// Reset all container states
@@ -304,18 +304,18 @@ func containersShutdown(s *state.State) error {
var lastPriority int
- if len(containers) != 0 {
- lastPriority, _ = strconv.Atoi(containers[0].ExpandedConfig()["boot.stop.priority"])
+ if len(instances) != 0 {
+ lastPriority, _ = strconv.Atoi(instances[0].ExpandedConfig()["boot.stop.priority"])
}
- for _, c := range containers {
+ for _, c := range instances {
priority, _ := strconv.Atoi(c.ExpandedConfig()["boot.stop.priority"])
// Enforce shutdown priority
if priority != lastPriority {
lastPriority = priority
- // Wait for containers with higher priority to finish
+ // Wait for instances with higher priority to finish
wg.Wait()
}
@@ -324,7 +324,7 @@ func containersShutdown(s *state.State) error {
// Stop the container
if lastState != "BROKEN" && lastState != "STOPPED" {
- // Determinate how long to wait for the container to shutdown cleanly
+ // Determinate how long to wait for the instance to shutdown cleanly
var timeoutSeconds int
value, ok := c.ExpandedConfig()["boot.host_shutdown_timeout"]
if ok {
@@ -333,9 +333,9 @@ func containersShutdown(s *state.State) error {
timeoutSeconds = 30
}
- // Stop the container
+ // Stop the instance
wg.Add(1)
- go func(c container, lastState string) {
+ go func(c Instance, lastState string) {
c.Shutdown(time.Second * time.Duration(timeoutSeconds))
c.Stop(false)
c.VolatileSet(map[string]string{"volatile.last_state.power": lastState})
diff --git a/lxd/containers_get.go b/lxd/containers_get.go
index 8d42f15da3..2d4d147920 100644
--- a/lxd/containers_get.go
+++ b/lxd/containers_get.go
@@ -103,10 +103,10 @@ func doContainersGet(d *Daemon, r *http.Request) (interface{}, error) {
return []string{}, err
}
- // Get the local containers
- nodeCts := map[string]container{}
+ // Get the local instances
+ nodeCts := map[string]Instance{}
if recursion > 0 {
- cts, err := containerLoadNodeProjectAll(d.State(), project, instanceType)
+ cts, err := instanceLoadNodeProjectAll(d.State(), project, instanceType)
if err != nil {
return nil, err
}
diff --git a/lxd/daemon.go b/lxd/daemon.go
index 583af879ad..d9a0f1d3a7 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -992,14 +992,14 @@ func (d *Daemon) Ready() error {
}
func (d *Daemon) numRunningContainers() (int, error) {
- results, err := containerLoadNodeAll(d.State())
+ results, err := instanceLoadNodeAll(d.State())
if err != nil {
return 0, err
}
count := 0
- for _, container := range results {
- if container.IsRunning() {
+ for _, instance := range results {
+ if instance.IsRunning() {
count = count + 1
}
}
diff --git a/lxd/devices.go b/lxd/devices.go
index da7c13d42c..aeecf4a69a 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -293,16 +293,16 @@ func deviceTaskBalance(s *state.State) {
return
}
- // Iterate through the containers
- containers, err := containerLoadNodeAll(s)
+ // Iterate through the instances
+ instances, err := instanceLoadNodeAll(s)
if err != nil {
- logger.Error("Problem loading containers list", log.Ctx{"err": err})
+ logger.Error("Problem loading instances list", log.Ctx{"err": err})
return
}
- fixedContainers := map[int][]container{}
- balancedContainers := map[container]int{}
- for _, c := range containers {
+ fixedInstances := map[int][]Instance{}
+ balancedInstances := map[Instance]int{}
+ for _, c := range instances {
conf := c.ExpandedConfig()
cpulimit, ok := conf["limits.cpu"]
if !ok || cpulimit == "" {
@@ -317,7 +317,7 @@ func deviceTaskBalance(s *state.State) {
if err == nil {
// Load-balance
count = min(count, len(cpus))
- balancedContainers[c] = count
+ balancedInstances[c] = count
} else {
// Pinned
containerCpus, err := parseCpuset(cpulimit)
@@ -329,18 +329,18 @@ func deviceTaskBalance(s *state.State) {
continue
}
- _, ok := fixedContainers[nr]
+ _, ok := fixedInstances[nr]
if ok {
- fixedContainers[nr] = append(fixedContainers[nr], c)
+ fixedInstances[nr] = append(fixedInstances[nr], c)
} else {
- fixedContainers[nr] = []container{c}
+ fixedInstances[nr] = []Instance{c}
}
}
}
}
// Balance things
- pinning := map[container][]string{}
+ pinning := map[Instance][]string{}
usage := map[int]deviceTaskCPU{}
for _, id := range cpus {
@@ -353,7 +353,7 @@ func deviceTaskBalance(s *state.State) {
usage[id] = cpu
}
- for cpu, ctns := range fixedContainers {
+ for cpu, ctns := range fixedInstances {
c, ok := usage[cpu]
if !ok {
logger.Errorf("Internal error: container using unavailable cpu")
@@ -376,7 +376,7 @@ func deviceTaskBalance(s *state.State) {
sortedUsage = append(sortedUsage, value)
}
- for ctn, count := range balancedContainers {
+ for ctn, count := range balancedInstances {
sort.Sort(sortedUsage)
for _, cpu := range sortedUsage {
if count == 0 {
@@ -416,12 +416,12 @@ func deviceNetworkPriority(s *state.State, netif string) {
return
}
- containers, err := containerLoadNodeAll(s)
+ instances, err := instanceLoadNodeAll(s)
if err != nil {
return
}
- for _, c := range containers {
+ for _, c := range instances {
// Extract the current priority
networkPriority := c.ExpandedConfig()["limits.network.priority"]
if networkPriority == "" {
@@ -494,16 +494,16 @@ func deviceEventListener(s *state.State) {
// devicesRegister calls the Register() function on all supported devices so they receive events.
func devicesRegister(s *state.State) {
- containers, err := containerLoadNodeAll(s)
+ instances, err := instanceLoadNodeAll(s)
if err != nil {
logger.Error("Problem loading containers list", log.Ctx{"err": err})
return
}
- for _, containerIf := range containers {
- c, ok := containerIf.(*containerLXC)
+ for _, instanceIf := range instances {
+ c, ok := instanceIf.(*containerLXC)
if !ok {
- logger.Errorf("Got non-LXC container")
+ logger.Errorf("Instance is not container type")
continue
}
diff --git a/lxd/devlxd.go b/lxd/devlxd.go
index 3c76c0b030..7ceeb96685 100644
--- a/lxd/devlxd.go
+++ b/lxd/devlxd.go
@@ -483,24 +483,28 @@ func findContainerForPid(pid int32, d *Daemon) (container, error) {
return nil, err
}
- containers, err := containerLoadNodeAll(d.State())
+ instances, err := instanceLoadNodeAll(d.State())
if err != nil {
return nil, err
}
- for _, c := range containers {
- if !c.IsRunning() {
+ for _, inst := range instances {
+ if inst.Type() != instance.TypeContainer {
continue
}
- initpid := c.InitPID()
+ if !inst.IsRunning() {
+ continue
+ }
+
+ initpid := inst.InitPID()
pidNs, err := os.Readlink(fmt.Sprintf("/proc/%d/ns/pid", initpid))
if err != nil {
return nil, err
}
if origPidNs == pidNs {
- return c, nil
+ return inst.(container), nil
}
}
diff --git a/lxd/networks.go b/lxd/networks.go
index 1e7607231d..11e6b2b699 100644
--- a/lxd/networks.go
+++ b/lxd/networks.go
@@ -22,6 +22,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
"github.com/lxc/lxd/lxd/dnsmasq"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/iptables"
"github.com/lxc/lxd/lxd/node"
"github.com/lxc/lxd/lxd/state"
@@ -429,16 +430,16 @@ func doNetworkGet(d *Daemon, name string) (api.Network, error) {
// Look for containers using the interface
if n.Type != "loopback" {
- cts, err := containerLoadFromAllProjects(d.State())
+ insts, err := instanceLoadFromAllProjects(d.State())
if err != nil {
return api.Network{}, err
}
- for _, c := range cts {
- if networkIsInUse(c, n.Name) {
- uri := fmt.Sprintf("/%s/containers/%s", version.APIVersion, c.Name())
- if c.Project() != "default" {
- uri += fmt.Sprintf("?project=%s", c.Project())
+ for _, inst := range insts {
+ if networkIsInUse(inst, n.Name) {
+ uri := fmt.Sprintf("/%s/containers/%s", version.APIVersion, inst.Name())
+ if inst.Project() != "default" {
+ uri += fmt.Sprintf("?project=%s", inst.Project())
}
n.UsedBy = append(n.UsedBy, uri)
}
@@ -712,24 +713,26 @@ func networkLeasesGet(d *Daemon, r *http.Request) Response {
// Get all static leases
if !isClusterNotification(r) {
- // Get all the containers
- containers, err := containerLoadByProject(d.State(), project)
+ // Get all the instances
+ instances, err := instanceLoadByProject(d.State(), project)
if err != nil {
return SmartError(err)
}
- for _, c := range containers {
+ for _, inst := range instances {
// Go through all its devices (including profiles
- for k, d := range c.ExpandedDevices() {
+ for k, d := range inst.ExpandedDevices() {
// Skip uninteresting entries
if d["type"] != "nic" || d["nictype"] != "bridged" || d["parent"] != name {
continue
}
// Fill in the hwaddr from volatile
- d, err = c.(*containerLXC).fillNetworkDevice(k, d)
- if err != nil {
- continue
+ if inst.Type() == instance.TypeContainer {
+ d, err = inst.(*containerLXC).fillNetworkDevice(k, d)
+ if err != nil {
+ continue
+ }
}
// Record the MAC
@@ -740,21 +743,21 @@ func networkLeasesGet(d *Daemon, r *http.Request) Response {
// Add the lease
if d["ipv4.address"] != "" {
leases = append(leases, api.NetworkLease{
- Hostname: c.Name(),
+ Hostname: inst.Name(),
Address: d["ipv4.address"],
Hwaddr: d["hwaddr"],
Type: "static",
- Location: c.Location(),
+ Location: inst.Location(),
})
}
if d["ipv6.address"] != "" {
leases = append(leases, api.NetworkLease{
- Hostname: c.Name(),
+ Hostname: inst.Name(),
Address: d["ipv6.address"],
Hwaddr: d["hwaddr"],
Type: "static",
- Location: c.Location(),
+ Location: inst.Location(),
})
}
}
@@ -956,14 +959,14 @@ func (n *network) IsRunning() bool {
}
func (n *network) IsUsed() bool {
- // Look for containers using the interface
- cts, err := containerLoadFromAllProjects(n.state)
+ // Look for instances using the interface
+ insts, err := instanceLoadFromAllProjects(n.state)
if err != nil {
return true
}
- for _, c := range cts {
- if networkIsInUse(c, n.name) {
+ for _, inst := range insts {
+ if networkIsInUse(inst, n.name) {
return true
}
}
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 299d65c8cd..f6a939aef2 100644
--- a/lxd/networks_utils.go
+++ b/lxd/networks_utils.go
@@ -25,6 +25,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
"github.com/lxc/lxd/lxd/dnsmasq"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
@@ -89,7 +90,7 @@ func networkGetInterfaces(cluster *db.Cluster) ([]string, error) {
return networks, nil
}
-func networkIsInUse(c container, name string) bool {
+func networkIsInUse(c Instance, name string) bool {
for _, d := range c.ExpandedDevices() {
if d["type"] != "nic" {
continue
@@ -637,26 +638,28 @@ func networkUpdateStatic(s *state.State, networkName string) error {
networks = []string{networkName}
}
- // Get all the containers
- containers, err := containerLoadNodeAll(s)
+ // Get all the instances
+ insts, err := instanceLoadNodeAll(s)
if err != nil {
return err
}
// Build a list of dhcp host entries
entries := map[string][][]string{}
- for _, c := range containers {
+ for _, inst := range insts {
// Go through all its devices (including profiles
- for k, d := range c.ExpandedDevices() {
+ for k, d := range inst.ExpandedDevices() {
// Skip uninteresting entries
if d["type"] != "nic" || d["nictype"] != "bridged" || !shared.StringInSlice(d["parent"], networks) {
continue
}
- // Fill in the hwaddr from volatile
- d, err = c.(*containerLXC).fillNetworkDevice(k, d)
- if err != nil {
- continue
+ if inst.Type() == instance.TypeContainer {
+ // Fill in the hwaddr from volatile
+ d, err = inst.(*containerLXC).fillNetworkDevice(k, d)
+ if err != nil {
+ continue
+ }
}
// Add the new host entries
@@ -666,7 +669,7 @@ func networkUpdateStatic(s *state.State, networkName string) error {
}
if (shared.IsTrue(d["security.ipv4_filtering"]) && d["ipv4.address"] == "") || (shared.IsTrue(d["security.ipv6_filtering"]) && d["ipv6.address"] == "") {
- curIPv4, curIPv6, err := dnsmasq.DHCPStaticIPs(d["parent"], c.Name())
+ curIPv4, curIPv6, err := dnsmasq.DHCPStaticIPs(d["parent"], inst.Name())
if err != nil && !os.IsNotExist(err) {
return err
}
@@ -680,7 +683,7 @@ func networkUpdateStatic(s *state.State, networkName string) error {
}
}
- entries[d["parent"]] = append(entries[d["parent"]], []string{d["hwaddr"], c.Project(), c.Name(), d["ipv4.address"], d["ipv6.address"]})
+ entries[d["parent"]] = append(entries[d["parent"]], []string{d["hwaddr"], inst.Project(), inst.Name(), d["ipv4.address"], d["ipv6.address"]})
}
}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 2c2f3d63d7..b25a1288d9 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -238,20 +238,20 @@ func storagePoolVolumeSnapshotUpdate(state *state.State, poolName string, volume
}
func storagePoolVolumeUsedByContainersGet(s *state.State, project, poolName string, volumeName string) ([]string, error) {
- cts, err := containerLoadByProject(s, project)
+ insts, err := instanceLoadByProject(s, project)
if err != nil {
return []string{}, err
}
ctsUsingVolume := []string{}
- for _, c := range cts {
- for _, dev := range c.LocalDevices() {
+ for _, inst := range insts {
+ for _, dev := range inst.LocalDevices() {
if dev["type"] != "disk" {
continue
}
if dev["pool"] == poolName && dev["source"] == volumeName {
- ctsUsingVolume = append(ctsUsingVolume, c.Name())
+ ctsUsingVolume = append(ctsUsingVolume, inst.Name())
break
}
}
@@ -264,14 +264,14 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
oldVolumeName string, newPoolName string, newVolumeName string) error {
s := d.State()
- // update all containers
- cts, err := containerLoadAll(s)
+ // update all instances
+ insts, err := instanceLoadAll(s)
if err != nil {
return err
}
- for _, c := range cts {
- devices := c.LocalDevices()
+ for _, inst := range insts {
+ devices := inst.LocalDevices()
for k := range devices {
if devices[k]["type"] != "disk" {
continue
@@ -298,7 +298,6 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
}
// found entry
-
if oldPoolName != newPoolName {
devices[k]["pool"] = newPoolName
}
@@ -313,18 +312,18 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
}
args := db.ContainerArgs{
- Architecture: c.Architecture(),
- Description: c.Description(),
- Config: c.LocalConfig(),
+ Architecture: inst.Architecture(),
+ Description: inst.Description(),
+ Config: inst.LocalConfig(),
Devices: devices,
- Ephemeral: c.IsEphemeral(),
- Profiles: c.Profiles(),
- Project: c.Project(),
- Type: c.Type(),
- Snapshot: c.IsSnapshot(),
+ Ephemeral: inst.IsEphemeral(),
+ Profiles: inst.Profiles(),
+ Project: inst.Project(),
+ Type: inst.Type(),
+ Snapshot: inst.IsSnapshot(),
}
- err = c.Update(args, false)
+ err = inst.Update(args, false)
if err != nil {
return err
}
@@ -398,19 +397,19 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
func storagePoolVolumeUsedByRunningContainersWithProfilesGet(s *state.State,
poolName string, volumeName string, volumeTypeName string,
runningOnly bool) ([]string, error) {
- cts, err := containerLoadAll(s)
+ insts, err := instanceLoadAll(s)
if err != nil {
return []string{}, err
}
ctsUsingVolume := []string{}
volumeNameWithType := fmt.Sprintf("%s/%s", volumeTypeName, volumeName)
- for _, c := range cts {
- if runningOnly && !c.IsRunning() {
+ for _, inst := range insts {
+ if runningOnly && !inst.IsRunning() {
continue
}
- for _, dev := range c.ExpandedDevices() {
+ for _, dev := range inst.ExpandedDevices() {
if dev["type"] != "disk" {
continue
}
@@ -423,7 +422,7 @@ func storagePoolVolumeUsedByRunningContainersWithProfilesGet(s *state.State,
// "container////bla" but only against "container/bla".
cleanSource := filepath.Clean(dev["source"])
if cleanSource == volumeName || cleanSource == volumeNameWithType {
- ctsUsingVolume = append(ctsUsingVolume, c.Name())
+ ctsUsingVolume = append(ctsUsingVolume, inst.Name())
}
}
}
From 151dc59339feb97aeff14be1a15a6525b7a45941 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 17 Sep 2019 09:07:14 +0100
Subject: [PATCH 2/6] lxd/storage/btrfs: Fixes bug with BTRFS snapshot copy
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage_btrfs.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index a47205b80a..e16d7a2ac2 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -1178,7 +1178,7 @@ func (s *storageBtrfs) ContainerCopy(target Instance, source Instance, container
return err
}
- err = s.copySnapshot(sourceSnapshot, targetSnapshot)
+ err = s.copySnapshot(targetSnapshot, sourceSnapshot)
if err != nil {
return err
}
From 818daadbf6e48b8749706e6aec3e096c51103776 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 17 Sep 2019 10:17:50 +0100
Subject: [PATCH 3/6] lxd/vm/qemu: Adds qemu virtual machine base
implementation of Instance interface
- Had to define in the main package because it relies on storeage and operation types.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/vm_qemu.go | 337 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 337 insertions(+)
create mode 100644 lxd/vm_qemu.go
diff --git a/lxd/vm_qemu.go b/lxd/vm_qemu.go
new file mode 100644
index 0000000000..ecbf328bed
--- /dev/null
+++ b/lxd/vm_qemu.go
@@ -0,0 +1,337 @@
+package main
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "time"
+
+ "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/project"
+ "github.com/lxc/lxd/lxd/state"
+ driver "github.com/lxc/lxd/lxd/storage"
+ "github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/api"
+)
+
+// The QEMU virtual machine driver.
+type vmQemu struct {
+ // Properties
+ architecture int
+ dbType instance.Type
+ snapshot bool
+ creationDate time.Time
+ lastUsedDate time.Time
+ ephemeral bool
+ id int
+ project string
+ name string
+ description string
+ stateful bool
+
+ // Config
+ expandedConfig map[string]string
+ expandedDevices deviceConfig.Devices
+ localConfig map[string]string
+ localDevices deviceConfig.Devices
+ profiles []string
+
+ state *state.State
+
+ // Storage
+ storage storage
+
+ // Clustering
+ node string
+
+ // Progress tracking
+ op *operation
+
+ expiryDate time.Time
+}
+
+func (q *vmQemu) Freeze() error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Shutdown(timeout time.Duration) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Start(stateful bool) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Stop(stateful bool) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Unfreeze() error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) IsPrivileged() bool {
+ return shared.IsTrue(q.expandedConfig["security.privileged"])
+}
+
+func (q *vmQemu) Restore(source Instance, stateful bool) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Snapshots() ([]Instance, error) {
+ return nil, fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Backups() ([]backup, error) {
+ return nil, fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Rename(newName string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Update(args db.ContainerArgs, userRequested bool) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Delete() error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Export(w io.Writer, properties map[string]string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) CGroupGet(key string) (string, error) {
+ return "", fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) CGroupSet(key string, value string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) VolatileSet(changes map[string]string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) FileExists(path string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) FilePull(srcpath string, dstpath string) (int64, int64, os.FileMode, string, []string, error) {
+ return 0, 0, 0, "", nil, fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) FilePush(type_ string, srcpath string, dstpath string, uid int64, gid int64, mode int, write string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) FileRemove(path string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Console(terminal *os.File) *exec.Cmd {
+ return nil
+}
+
+func (q *vmQemu) Exec(command []string, env map[string]string, stdin *os.File, stdout *os.File, stderr *os.File, wait bool, cwd string, uid uint32, gid uint32) (*exec.Cmd, int, int, error) {
+ return nil, 0, 0, fmt.Errorf("Not implemented")
+
+}
+
+func (q *vmQemu) Render() (interface{}, interface{}, error) {
+ return nil, nil, fmt.Errorf("Not implemented")
+
+}
+
+func (q *vmQemu) RenderFull() (*api.InstanceFull, interface{}, error) {
+ return nil, nil, fmt.Errorf("Not implemented")
+
+}
+
+func (q *vmQemu) RenderState() (*api.InstanceState, error) {
+ return nil, fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) IsRunning() bool {
+ state := q.State()
+ return state != "BROKEN" && state != "STOPPED"
+}
+
+func (q *vmQemu) IsFrozen() bool {
+ return q.State() == "FROZEN"
+}
+
+func (q *vmQemu) IsEphemeral() bool {
+ return q.ephemeral
+}
+
+func (q *vmQemu) IsSnapshot() bool {
+ return q.snapshot
+}
+
+func (q *vmQemu) IsStateful() bool {
+ return q.stateful
+}
+
+func (q *vmQemu) DeviceEventHandler(runConf *device.RunConfig) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) Id() int {
+ return q.id
+}
+
+func (q *vmQemu) Location() string {
+ return q.node
+}
+
+func (q *vmQemu) Project() string {
+ return q.project
+}
+
+func (q *vmQemu) Name() string {
+ return q.name
+}
+
+func (q *vmQemu) Type() instance.Type {
+ return q.dbType
+}
+
+func (q *vmQemu) Description() string {
+ return q.description
+}
+
+func (q *vmQemu) Architecture() int {
+ return q.architecture
+}
+
+func (q *vmQemu) CreationDate() time.Time {
+ return q.creationDate
+}
+func (q *vmQemu) LastUsedDate() time.Time {
+ return q.lastUsedDate
+}
+
+func (q *vmQemu) ExpandedConfig() map[string]string {
+ return q.expandedConfig
+}
+
+func (q *vmQemu) ExpandedDevices() deviceConfig.Devices {
+ return q.expandedDevices
+}
+
+func (q *vmQemu) LocalConfig() map[string]string {
+ return q.localConfig
+}
+
+func (q *vmQemu) LocalDevices() deviceConfig.Devices {
+ return q.localDevices
+}
+
+func (q *vmQemu) Profiles() []string {
+ return q.profiles
+}
+
+func (q *vmQemu) InitPID() int {
+ return -1
+}
+
+func (q *vmQemu) State() string {
+ return ""
+}
+
+func (q *vmQemu) ExpiryDate() time.Time {
+ if q.IsSnapshot() {
+ return q.expiryDate
+ }
+
+ // Return zero time if the container is not a snapshot
+ return time.Time{}
+}
+
+func (q *vmQemu) Path() string {
+ name := project.Prefix(q.Project(), q.Name())
+ return driver.ContainerPath(name, q.IsSnapshot())
+}
+
+func (q *vmQemu) DevicesPath() string {
+ name := project.Prefix(q.Project(), q.Name())
+ return shared.VarPath("devices", name)
+}
+
+func (q *vmQemu) ShmountsPath() string {
+ name := project.Prefix(q.Project(), q.Name())
+ return shared.VarPath("shmounts", name)
+}
+
+func (q *vmQemu) LogPath() string {
+ name := project.Prefix(q.Project(), q.Name())
+ return shared.LogPath(name)
+}
+
+func (q *vmQemu) LogFilePath() string {
+ return filepath.Join(q.LogPath(), "lxq.log")
+}
+
+func (q *vmQemu) ConsoleBufferLogPath() string {
+ return filepath.Join(q.LogPath(), "console.log")
+}
+
+func (q *vmQemu) RootfsPath() string {
+ return filepath.Join(q.Path(), "rootfs")
+}
+
+func (q *vmQemu) TemplatesPath() string {
+ return filepath.Join(q.Path(), "templates")
+}
+
+func (q *vmQemu) StatePath() string {
+ return filepath.Join(q.Path(), "state")
+}
+
+func (q *vmQemu) StoragePool() (string, error) {
+ poolName, err := q.state.Cluster.ContainerPool(q.Project(), q.Name())
+ if err != nil {
+ return "", err
+ }
+
+ return poolName, nil
+}
+
+func (q *vmQemu) SetOperation(op *operation) {
+ q.op = op
+}
+
+func (q *vmQemu) StorageStart() (bool, error) {
+ return false, fmt.Errorf("Not implemented")
+
+}
+
+func (q *vmQemu) StorageStop() (bool, error) {
+ return false, fmt.Errorf("Not implemented")
+
+}
+
+func (q *vmQemu) Storage() storage {
+ return nil
+}
+
+func (q *vmQemu) TemplateApply(trigger string) error {
+ return fmt.Errorf("Not implemented")
+}
+
+func (q *vmQemu) DaemonState() *state.State {
+ // FIXME: This function should go away, since the abstract container
+ // interface should not be coupled with internal state details.
+ // However this is not currently possible, because many
+ // higher-level APIs use container variables as "implicit
+ // handles" to database/OS state and then need a way to get a
+ // reference to it.
+ return q.state
+}
From 2ae062e22891d5f651caff610918e413d2e1cec6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 17 Sep 2019 10:40:17 +0100
Subject: [PATCH 4/6] vm qemu cont
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/vm_qemu.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/lxd/vm_qemu.go b/lxd/vm_qemu.go
index ecbf328bed..2a048a584c 100644
--- a/lxd/vm_qemu.go
+++ b/lxd/vm_qemu.go
@@ -19,6 +19,62 @@ import (
"github.com/lxc/lxd/shared/api"
)
+func vmQemuLoad(s *state.State, args db.ContainerArgs, profiles []api.Profile) (Instance, error) {
+ // Create the container struct
+ q := vmQemuInstantiate(s, args)
+
+ // Expand config and devices
+ err := q.expandConfig(profiles)
+ if err != nil {
+ return nil, err
+ }
+
+ err = q.expandDevices(profiles)
+ if err != nil {
+ return nil, err
+ }
+
+ return q, nil
+}
+
+// vmQemuInstantiate creates a vmQemu struct without initializing it.
+func vmQemuInstantiate(s *state.State, args db.ContainerArgs) *vmQemu {
+ q := &vmQemu{
+ state: s,
+ id: args.ID,
+ project: args.Project,
+ name: args.Name,
+ description: args.Description,
+ ephemeral: args.Ephemeral,
+ architecture: args.Architecture,
+ dbType: args.Type,
+ snapshot: args.Snapshot,
+ creationDate: args.CreationDate,
+ lastUsedDate: args.LastUsedDate,
+ profiles: args.Profiles,
+ localConfig: args.Config,
+ localDevices: args.Devices,
+ stateful: args.Stateful,
+ node: args.Node,
+ expiryDate: args.ExpiryDate,
+ }
+
+ // Cleanup the zero values
+ if q.expiryDate.IsZero() {
+ q.expiryDate = time.Time{}
+ }
+
+ if q.creationDate.IsZero() {
+ q.creationDate = time.Time{}
+ }
+
+ if q.lastUsedDate.IsZero() {
+ q.lastUsedDate = time.Time{}
+ }
+
+ return q
+}
+
// The QEMU virtual machine driver.
type vmQemu struct {
// Properties
@@ -218,6 +274,34 @@ func (q *vmQemu) LastUsedDate() time.Time {
return q.lastUsedDate
}
+func (q *vmQemu) expandConfig(profiles []api.Profile) error {
+ if profiles == nil && len(q.profiles) > 0 {
+ var err error
+ profiles, err = q.state.Cluster.ProfilesGet(q.project, q.profiles)
+ if err != nil {
+ return err
+ }
+ }
+
+ q.expandedConfig = db.ProfilesExpandConfig(q.localConfig, profiles)
+
+ return nil
+}
+
+func (q *vmQemu) expandDevices(profiles []api.Profile) error {
+ if profiles == nil && len(q.profiles) > 0 {
+ var err error
+ profiles, err = q.state.Cluster.ProfilesGet(q.project, q.profiles)
+ if err != nil {
+ return err
+ }
+ }
+
+ q.expandedDevices = db.ProfilesExpandDevices(q.localDevices, profiles)
+
+ return nil
+}
+
func (q *vmQemu) ExpandedConfig() map[string]string {
return q.expandedConfig
}
From 093a7a0b411f90406765f17ffb168806954d2f28 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 17 Sep 2019 10:57:17 +0100
Subject: [PATCH 5/6] lxd/container: Adds instanceInstantiate function
instanceInstantiate function will create the correct underlying struct based on instance type and returns it as an Instance.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container.go | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/lxd/container.go b/lxd/container.go
index 45c7687dba..35aefe5a67 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -1142,6 +1142,26 @@ func instanceLoadAllInternal(dbInstances []db.Instance, s *state.State) ([]Insta
return instances, nil
}
+// instanceInstantiate creates the underlying instance type struct and returns it as an Instance.
+func instanceInstantiate(s *state.State, args db.ContainerArgs, cProfiles []api.Profile) (Instance, error) {
+ var inst Instance
+ var err error
+
+ if args.Type == instance.TypeContainer {
+ inst, err = containerLXCLoad(s, args, cProfiles)
+ } else if args.Type == instance.TypeVM {
+ inst, err = vmQemuLoad(s, args, cProfiles)
+ } else {
+ return nil, fmt.Errorf("Invalid instance type for instance %s", args.Name)
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ return inst, nil
+}
+
func containerCompareSnapshots(source Instance, target Instance) ([]Instance, []Instance, error) {
// Get the source snapshots
sourceSnapshots, err := source.Snapshots()
From eff91d441abb7765dc842aa484a98daf00371fff Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Tue, 17 Sep 2019 10:58:22 +0100
Subject: [PATCH 6/6] lxd: Replaces use of containerLXCLoad with
instanceInstantiate
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container.go | 20 +++++++-------------
lxd/containers.go | 4 ++--
lxd/containers_post.go | 4 ++--
3 files changed, 11 insertions(+), 17 deletions(-)
diff --git a/lxd/container.go b/lxd/container.go
index 35aefe5a67..9d1e384982 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -985,13 +985,12 @@ func instanceLoadByProjectAndName(s *state.State, project, name string) (Instanc
}
args := db.ContainerToArgs(container)
-
- c, err := containerLXCLoad(s, args, nil)
+ inst, err := instanceInstantiate(s, args, nil)
if err != nil {
return nil, errors.Wrap(err, "Failed to load container")
}
- return c, nil
+ return inst, nil
}
func instanceLoadByProject(s *state.State, project string) ([]Instance, error) {
@@ -1125,18 +1124,13 @@ func instanceLoadAllInternal(dbInstances []db.Instance, s *state.State) ([]Insta
cProfiles = append(cProfiles, profiles[dbInstance.Project][name])
}
- if dbInstance.Type == instance.TypeContainer {
- args := db.ContainerToArgs(&dbInstance)
- ct, err := containerLXCLoad(s, args, cProfiles)
- if err != nil {
- return nil, err
- }
- instances = append(instances, ct)
- } else {
- // TODO add virtual machine load here.
- continue
+ args := db.ContainerToArgs(&dbInstance)
+ inst, err := instanceInstantiate(s, args, cProfiles)
+ if err != nil {
+ return nil, err
}
+ instances = append(instances, inst)
}
return instances, nil
diff --git a/lxd/containers.go b/lxd/containers.go
index a340642a00..bf5e682067 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -278,7 +278,7 @@ func containersShutdown(s *state.State) error {
for project, names := range cnames {
for _, name := range names {
- c, err := containerLXCLoad(s, db.ContainerArgs{
+ inst, err := instanceInstantiate(s, db.ContainerArgs{
Project: project,
Name: name,
Config: make(map[string]string),
@@ -287,7 +287,7 @@ func containersShutdown(s *state.State) error {
return err
}
- instances = append(instances, c)
+ instances = append(instances, inst)
}
}
}
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 822af02534..d6720b64ce 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -321,12 +321,12 @@ func createFromMigration(d *Daemon, project string, req *api.InstancesPost) Resp
}
} else {
// Retrieve the future storage pool
- cM, err := containerLXCLoad(d.State(), args, nil)
+ inst, err := instanceInstantiate(d.State(), args, nil)
if err != nil {
return InternalError(err)
}
- _, rootDiskDevice, err := shared.GetRootDiskDevice(cM.ExpandedDevices().CloneNative())
+ _, rootDiskDevice, err := shared.GetRootDiskDevice(inst.ExpandedDevices().CloneNative())
if err != nil {
return InternalError(err)
}
More information about the lxc-devel
mailing list