[lxc-devel] [lxd/master] Move Device/Devices types to lxd package

stgraber on Github lxc-bot at linuxcontainers.org
Wed Dec 21 23:22:40 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 493 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20161221/778fe08a/attachment.bin>
-------------- next part --------------
From b38e119e447593f871f0f7a5f53d44c716ec9963 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 21 Dec 2016 18:03:46 -0500
Subject: [PATCH] Move Device/Devices types to lxd package
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

We don't need any of their functions in the client code so move them to
be daemon-only and instead use generic go types in the client.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 client.go                 |  19 +++---
 lxc/config.go             |   2 +-
 lxc/copy.go               |   2 +-
 lxc/init.go               |   6 +-
 lxc/launch.go             |   6 +-
 lxd/container.go          |  11 +--
 lxd/container_lxc.go      |  71 ++++++++++----------
 lxd/container_put.go      |   3 +-
 lxd/container_test.go     |  11 +--
 lxd/containers_post.go    |   5 +-
 lxd/db_containers.go      |   3 +-
 lxd/db_devices.go         |  12 ++--
 lxd/db_profiles.go        |   7 +-
 lxd/db_test.go            |  17 ++---
 lxd/profiles.go           |   3 +-
 lxd/storage.go            |   3 +-
 lxd/types/devices.go      | 166 ++++++++++++++++++++++++++++++++++++++++++++++
 lxd/types/devices_test.go |  22 ++++++
 shared/container.go       |  68 +++++++++----------
 shared/devices.go         | 164 ---------------------------------------------
 shared/devices_test.go    |  22 ------
 21 files changed, 319 insertions(+), 304 deletions(-)
 create mode 100644 lxd/types/devices.go
 create mode 100644 lxd/types/devices_test.go
 delete mode 100644 shared/devices.go
 delete mode 100644 shared/devices_test.go

diff --git a/client.go b/client.go
index 6326d59..b9ca129 100644
--- a/client.go
+++ b/client.go
@@ -1317,7 +1317,7 @@ func (c *Client) GetAlias(alias string) string {
 
 // Init creates a container from either a fingerprint or an alias; you must
 // provide at least one.
-func (c *Client) Init(name string, imgremote string, image string, profiles *[]string, config map[string]string, devices shared.Devices, ephem bool) (*Response, error) {
+func (c *Client) Init(name string, imgremote string, image string, profiles *[]string, config map[string]string, devices map[string]map[string]string, ephem bool) (*Response, error) {
 	if c.Remote.Public {
 		return nil, fmt.Errorf("This function isn't supported by public remotes.")
 	}
@@ -2019,7 +2019,7 @@ func (c *Client) GetMigrationSourceWS(container string) (*Response, error) {
 
 func (c *Client) MigrateFrom(name string, operation string, certificate string,
 	sourceSecrets map[string]string, architecture string, config map[string]string,
-	devices shared.Devices, profiles []string,
+	devices map[string]map[string]string, profiles []string,
 	baseImage string, ephemeral bool, push bool, sourceClient *Client,
 	sourceOperation string) (*Response, error) {
 	if c.Remote.Public {
@@ -2572,7 +2572,7 @@ func (c *Client) ContainerDeviceAdd(container, devname, devtype string, props []
 		return nil, err
 	}
 
-	newdev := shared.Device{}
+	newdev := map[string]string{}
 	for _, p := range props {
 		results := strings.SplitN(p, "=", 2)
 		if len(results) != 2 {
@@ -2583,13 +2583,13 @@ func (c *Client) ContainerDeviceAdd(container, devname, devtype string, props []
 		newdev[k] = v
 	}
 
-	if st.Devices != nil && st.Devices.ContainsName(devname) {
+	if st.Devices != nil && st.Devices[devname] != nil {
 		return nil, fmt.Errorf("device already exists")
 	}
 
 	newdev["type"] = devtype
 	if st.Devices == nil {
-		st.Devices = shared.Devices{}
+		st.Devices = map[string]map[string]string{}
 	}
 
 	st.Devices[devname] = newdev
@@ -2643,7 +2643,7 @@ func (c *Client) ProfileDeviceAdd(profile, devname, devtype string, props []stri
 		return nil, err
 	}
 
-	newdev := shared.Device{}
+	newdev := map[string]string{}
 	for _, p := range props {
 		results := strings.SplitN(p, "=", 2)
 		if len(results) != 2 {
@@ -2653,13 +2653,16 @@ func (c *Client) ProfileDeviceAdd(profile, devname, devtype string, props []stri
 		v := results[1]
 		newdev[k] = v
 	}
-	if st.Devices != nil && st.Devices.ContainsName(devname) {
+
+	if st.Devices != nil && st.Devices[devname] != nil {
 		return nil, fmt.Errorf("device already exists")
 	}
+
 	newdev["type"] = devtype
 	if st.Devices == nil {
-		st.Devices = shared.Devices{}
+		st.Devices = map[string]map[string]string{}
 	}
+
 	st.Devices[devname] = newdev
 
 	return c.put(fmt.Sprintf("profiles/%s", profile), st, Sync)
diff --git a/lxc/config.go b/lxc/config.go
index 73091a4..59c67cd 100644
--- a/lxc/config.go
+++ b/lxc/config.go
@@ -872,7 +872,7 @@ func (c *configCmd) deviceShow(config *lxd.Config, which string, args []string)
 		return err
 	}
 
-	var devices map[string]shared.Device
+	var devices map[string]map[string]string
 	if which == "profile" {
 		resp, err := client.ProfileConfig(name)
 		if err != nil {
diff --git a/lxc/copy.go b/lxc/copy.go
index 3715127..9f8437a 100644
--- a/lxc/copy.go
+++ b/lxc/copy.go
@@ -55,7 +55,7 @@ func (c *copyCmd) copyContainer(config *lxd.Config, sourceResource string, destR
 
 	var status struct {
 		Architecture string
-		Devices      shared.Devices
+		Devices      map[string]map[string]string
 		Config       map[string]string
 		Profiles     []string
 	}
diff --git a/lxc/init.go b/lxc/init.go
index 95f0507..20d062b 100644
--- a/lxc/init.go
+++ b/lxc/init.go
@@ -182,7 +182,7 @@ func (c *initCmd) run(config *lxd.Config, args []string) error {
 
 	iremote, image = c.guessImage(config, d, remote, iremote, image)
 
-	devicesMap := map[string]shared.Device{}
+	devicesMap := map[string]map[string]string{}
 	if c.network != "" {
 		network, err := d.NetworkGet(c.network)
 		if err != nil {
@@ -190,9 +190,9 @@ func (c *initCmd) run(config *lxd.Config, args []string) error {
 		}
 
 		if network.Type == "bridge" {
-			devicesMap[c.network] = shared.Device{"type": "nic", "nictype": "bridged", "parent": c.network}
+			devicesMap[c.network] = map[string]string{"type": "nic", "nictype": "bridged", "parent": c.network}
 		} else {
-			devicesMap[c.network] = shared.Device{"type": "nic", "nictype": "macvlan", "parent": c.network}
+			devicesMap[c.network] = map[string]string{"type": "nic", "nictype": "macvlan", "parent": c.network}
 		}
 	}
 
diff --git a/lxc/launch.go b/lxc/launch.go
index 90823df..1f8a414 100644
--- a/lxc/launch.go
+++ b/lxc/launch.go
@@ -70,7 +70,7 @@ func (c *launchCmd) run(config *lxd.Config, args []string) error {
 
 	iremote, image = c.init.guessImage(config, d, remote, iremote, image)
 
-	devicesMap := map[string]shared.Device{}
+	devicesMap := map[string]map[string]string{}
 	if c.init.network != "" {
 		network, err := d.NetworkGet(c.init.network)
 		if err != nil {
@@ -78,9 +78,9 @@ func (c *launchCmd) run(config *lxd.Config, args []string) error {
 		}
 
 		if network.Type == "bridge" {
-			devicesMap[c.init.network] = shared.Device{"type": "nic", "nictype": "bridged", "parent": c.init.network}
+			devicesMap[c.init.network] = map[string]string{"type": "nic", "nictype": "bridged", "parent": c.init.network}
 		} else {
-			devicesMap[c.init.network] = shared.Device{"type": "nic", "nictype": "macvlan", "parent": c.init.network}
+			devicesMap[c.init.network] = map[string]string{"type": "nic", "nictype": "macvlan", "parent": c.init.network}
 		}
 	}
 
diff --git a/lxd/container.go b/lxd/container.go
index 6b43e07..2b916ea 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -9,6 +9,7 @@ import (
 
 	"gopkg.in/lxc/go-lxc.v2"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/osarch"
 )
@@ -215,7 +216,7 @@ func containerValidConfig(d *Daemon, config map[string]string, profile bool, exp
 	return nil
 }
 
-func containerValidDevices(devices shared.Devices, profile bool, expanded bool) error {
+func containerValidDevices(devices types.Devices, profile bool, expanded bool) error {
 	// Empty device list
 	if devices == nil {
 		return nil
@@ -315,7 +316,7 @@ type containerArgs struct {
 	CreationDate time.Time
 	LastUsedDate time.Time
 	Ctype        containerType
-	Devices      shared.Devices
+	Devices      types.Devices
 	Ephemeral    bool
 	Name         string
 	Profiles     []string
@@ -393,9 +394,9 @@ type container interface {
 	CreationDate() time.Time
 	LastUsedDate() time.Time
 	ExpandedConfig() map[string]string
-	ExpandedDevices() shared.Devices
+	ExpandedDevices() types.Devices
 	LocalConfig() map[string]string
-	LocalDevices() shared.Devices
+	LocalDevices() types.Devices
 	Profiles() []string
 	InitPID() int
 	State() string
@@ -596,7 +597,7 @@ func containerCreateInternal(d *Daemon, args containerArgs) (container, error) {
 	}
 
 	if args.Devices == nil {
-		args.Devices = shared.Devices{}
+		args.Devices = types.Devices{}
 	}
 
 	if args.Architecture == 0 {
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 3d84d7d..a660370 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -24,6 +24,7 @@ import (
 	"gopkg.in/lxc/go-lxc.v2"
 	"gopkg.in/yaml.v2"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/osarch"
 
@@ -231,7 +232,7 @@ func containerLXCCreate(d *Daemon, args containerArgs) (container, error) {
 			deviceName += "_"
 		}
 
-		c.localDevices[deviceName] = shared.Device{"type": "disk", "path": "/"}
+		c.localDevices[deviceName] = types.Device{"type": "disk", "path": "/"}
 
 		updateArgs := containerArgs{
 			Architecture: c.architecture,
@@ -382,10 +383,10 @@ type containerLXC struct {
 
 	// Config
 	expandedConfig  map[string]string
-	expandedDevices shared.Devices
+	expandedDevices types.Devices
 	fromHook        bool
 	localConfig     map[string]string
-	localDevices    shared.Devices
+	localDevices    types.Devices
 	profiles        []string
 
 	// Cache
@@ -1398,7 +1399,7 @@ func (c *containerLXC) expandConfig() error {
 }
 
 func (c *containerLXC) expandDevices() error {
-	devices := shared.Devices{}
+	devices := types.Devices{}
 
 	// Apply all the profiles
 	for _, p := range c.profiles {
@@ -1423,7 +1424,7 @@ func (c *containerLXC) expandDevices() error {
 
 // setupUnixDevice() creates the unix device and sets up the necessary low-level
 // liblxc configuration items.
-func (c *containerLXC) setupUnixDevice(devType string, dev shared.Device, major int, minor int, path string, createMustSucceed bool) error {
+func (c *containerLXC) setupUnixDevice(devType string, dev types.Device, major int, minor int, path string, createMustSucceed bool) error {
 	if c.IsPrivileged() && !runningInUserns && cgDevicesController {
 		err := lxcSetConfigItem(c.c, "lxc.cgroup.devices.allow", fmt.Sprintf("c %d:%d rwm", major, minor))
 		if err != nil {
@@ -1431,7 +1432,7 @@ func (c *containerLXC) setupUnixDevice(devType string, dev shared.Device, major
 		}
 	}
 
-	temp := shared.Device{}
+	temp := types.Device{}
 	if err := shared.DeepCopy(&dev, &temp); err != nil {
 		return err
 	}
@@ -1592,7 +1593,7 @@ func (c *containerLXC) startCommon() (string, error) {
 	var usbs []usbDevice
 	var gpus []gpuDevice
 	var nvidiaDevices []nvidiaGpuDevices
-	diskDevices := map[string]shared.Device{}
+	diskDevices := map[string]types.Device{}
 
 	// Create the devices
 	for _, k := range c.expandedDevices.DeviceNames() {
@@ -1722,7 +1723,7 @@ func (c *containerLXC) startCommon() (string, error) {
 		}
 	}
 
-	err = c.addDiskDevices(diskDevices, func(name string, d shared.Device) error {
+	err = c.addDiskDevices(diskDevices, func(name string, d types.Device) error {
 		_, err := c.createDiskDevice(name, d)
 		return err
 	})
@@ -2030,7 +2031,7 @@ func (c *containerLXC) OnStart() error {
 			continue
 		}
 
-		go func(c *containerLXC, name string, m shared.Device) {
+		go func(c *containerLXC, name string, m types.Device) {
 			c.fromHook = false
 			err = c.setNetworkLimits(name, m)
 			if err != nil {
@@ -2864,7 +2865,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 	}
 
 	if args.Devices == nil {
-		args.Devices = shared.Devices{}
+		args.Devices = types.Devices{}
 	}
 
 	if args.Profiles == nil {
@@ -2939,7 +2940,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 		return err
 	}
 
-	oldExpandedDevices := shared.Devices{}
+	oldExpandedDevices := types.Devices{}
 	err = shared.DeepCopy(&c.expandedDevices, &oldExpandedDevices)
 	if err != nil {
 		return err
@@ -2951,7 +2952,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 		return err
 	}
 
-	oldLocalDevices := shared.Devices{}
+	oldLocalDevices := types.Devices{}
 	err = shared.DeepCopy(&c.localDevices, &oldLocalDevices)
 	if err != nil {
 		return err
@@ -3112,7 +3113,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 	// Apply the live changes
 	if c.IsRunning() {
 		// Confirm that the rootfs source didn't change
-		var oldRootfs shared.Device
+		var oldRootfs types.Device
 		for _, m := range oldExpandedDevices {
 			if m["type"] == "disk" && m["path"] == "/" {
 				oldRootfs = m
@@ -3120,7 +3121,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 			}
 		}
 
-		var newRootfs shared.Device
+		var newRootfs types.Device
 		for _, name := range c.expandedDevices.DeviceNames() {
 			m := c.expandedDevices[name]
 			if m["type"] == "disk" && m["path"] == "/" {
@@ -3432,7 +3433,7 @@ func (c *containerLXC) Update(args containerArgs, userRequested bool) error {
 			}
 		}
 
-		diskDevices := map[string]shared.Device{}
+		diskDevices := map[string]types.Device{}
 
 		for k, m := range addDevices {
 			if shared.StringInSlice(m["type"], []string{"unix-char", "unix-block"}) {
@@ -4918,7 +4919,7 @@ func (c *containerLXC) deviceExists(path string) bool {
 }
 
 // Unix devices handling
-func (c *containerLXC) createUnixDevice(m shared.Device) ([]string, error) {
+func (c *containerLXC) createUnixDevice(m types.Device) ([]string, error) {
 	var err error
 	var major, minor int
 
@@ -5049,7 +5050,7 @@ func (c *containerLXC) createUnixDevice(m shared.Device) ([]string, error) {
 	return []string{devPath, tgtPath}, nil
 }
 
-func (c *containerLXC) insertUnixDevice(m shared.Device) error {
+func (c *containerLXC) insertUnixDevice(m types.Device) error {
 	// Check that the container is running
 	if !c.IsRunning() {
 		return fmt.Errorf("Can't insert device into stopped container")
@@ -5111,8 +5112,8 @@ func (c *containerLXC) insertUnixDevice(m shared.Device) error {
 	return nil
 }
 
-func (c *containerLXC) insertUnixDeviceNum(m shared.Device, major int, minor int, path string) error {
-	temp := shared.Device{}
+func (c *containerLXC) insertUnixDeviceNum(m types.Device, major int, minor int, path string) error {
+	temp := types.Device{}
 	if err := shared.DeepCopy(&m, &temp); err != nil {
 		return err
 	}
@@ -5124,7 +5125,7 @@ func (c *containerLXC) insertUnixDeviceNum(m shared.Device, major int, minor int
 	return c.insertUnixDevice(temp)
 }
 
-func (c *containerLXC) removeUnixDevice(m shared.Device) error {
+func (c *containerLXC) removeUnixDevice(m types.Device) error {
 	// Check that the container is running
 	pid := c.InitPID()
 	if pid == -1 {
@@ -5202,13 +5203,13 @@ func (c *containerLXC) removeUnixDevice(m shared.Device) error {
 	return nil
 }
 
-func (c *containerLXC) removeUnixDeviceNum(m shared.Device, major int, minor int, path string) error {
+func (c *containerLXC) removeUnixDeviceNum(m types.Device, major int, minor int, path string) error {
 	pid := c.InitPID()
 	if pid == -1 {
 		return fmt.Errorf("Can't remove device from stopped container")
 	}
 
-	temp := shared.Device{}
+	temp := types.Device{}
 	if err := shared.DeepCopy(&m, &temp); err != nil {
 		return err
 	}
@@ -5258,7 +5259,7 @@ func (c *containerLXC) removeUnixDevices() error {
 }
 
 // Network device handling
-func (c *containerLXC) createNetworkDevice(name string, m shared.Device) (string, error) {
+func (c *containerLXC) createNetworkDevice(name string, m types.Device) (string, error) {
 	var dev, n1 string
 
 	if shared.StringInSlice(m["nictype"], []string{"bridged", "p2p", "macvlan"}) {
@@ -5338,8 +5339,8 @@ func (c *containerLXC) createNetworkDevice(name string, m shared.Device) (string
 	return dev, nil
 }
 
-func (c *containerLXC) fillNetworkDevice(name string, m shared.Device) (shared.Device, error) {
-	newDevice := shared.Device{}
+func (c *containerLXC) fillNetworkDevice(name string, m types.Device) (types.Device, error) {
+	newDevice := types.Device{}
 	err := shared.DeepCopy(&m, &newDevice)
 	if err != nil {
 		return nil, err
@@ -5549,7 +5550,7 @@ func (c *containerLXC) removeNetworkFilters() error {
 	return nil
 }
 
-func (c *containerLXC) insertNetworkDevice(name string, m shared.Device) error {
+func (c *containerLXC) insertNetworkDevice(name string, m types.Device) error {
 	// Load the go-lxc struct
 	err := c.initLXC()
 	if err != nil {
@@ -5586,7 +5587,7 @@ func (c *containerLXC) insertNetworkDevice(name string, m shared.Device) error {
 	return nil
 }
 
-func (c *containerLXC) removeNetworkDevice(name string, m shared.Device) error {
+func (c *containerLXC) removeNetworkDevice(name string, m types.Device) error {
 	// Load the go-lxc struct
 	err := c.initLXC()
 	if err != nil {
@@ -5641,7 +5642,7 @@ func (c *containerLXC) removeNetworkDevice(name string, m shared.Device) error {
 }
 
 // Disk device handling
-func (c *containerLXC) createDiskDevice(name string, m shared.Device) (string, error) {
+func (c *containerLXC) createDiskDevice(name string, m types.Device) (string, error) {
 	// Prepare all the paths
 	srcPath := m["source"]
 	tgtPath := strings.TrimPrefix(m["path"], "/")
@@ -5702,7 +5703,7 @@ func (c *containerLXC) createDiskDevice(name string, m shared.Device) (string, e
 	return devPath, nil
 }
 
-func (c *containerLXC) insertDiskDevice(name string, m shared.Device) error {
+func (c *containerLXC) insertDiskDevice(name string, m types.Device) error {
 	// Check that the container is running
 	if !c.IsRunning() {
 		return fmt.Errorf("Can't insert device into stopped container")
@@ -5731,7 +5732,7 @@ func (c *containerLXC) insertDiskDevice(name string, m shared.Device) error {
 	return nil
 }
 
-type byPath []shared.Device
+type byPath []types.Device
 
 func (a byPath) Len() int {
 	return len(a)
@@ -5745,7 +5746,7 @@ func (a byPath) Less(i, j int) bool {
 	return a[i]["path"] < a[j]["path"]
 }
 
-func (c *containerLXC) addDiskDevices(devices map[string]shared.Device, handler func(string, shared.Device) error) error {
+func (c *containerLXC) addDiskDevices(devices map[string]types.Device, handler func(string, types.Device) error) error {
 	ordered := byPath{}
 
 	for _, d := range devices {
@@ -5763,7 +5764,7 @@ func (c *containerLXC) addDiskDevices(devices map[string]shared.Device, handler
 	return nil
 }
 
-func (c *containerLXC) removeDiskDevice(name string, m shared.Device) error {
+func (c *containerLXC) removeDiskDevice(name string, m types.Device) error {
 	// Check that the container is running
 	pid := c.InitPID()
 	if pid == -1 {
@@ -6059,7 +6060,7 @@ func (c *containerLXC) getHostInterface(name string) string {
 	return ""
 }
 
-func (c *containerLXC) setNetworkLimits(name string, m shared.Device) error {
+func (c *containerLXC) setNetworkLimits(name string, m types.Device) error {
 	// We can only do limits on some network type
 	if m["nictype"] != "bridged" && m["nictype"] != "p2p" {
 		return fmt.Errorf("Network limits are only supported on bridged and p2p interfaces")
@@ -6194,7 +6195,7 @@ func (c *containerLXC) ExpandedConfig() map[string]string {
 	return c.expandedConfig
 }
 
-func (c *containerLXC) ExpandedDevices() shared.Devices {
+func (c *containerLXC) ExpandedDevices() types.Devices {
 	return c.expandedDevices
 }
 
@@ -6220,7 +6221,7 @@ func (c *containerLXC) LocalConfig() map[string]string {
 	return c.localConfig
 }
 
-func (c *containerLXC) LocalDevices() shared.Devices {
+func (c *containerLXC) LocalDevices() types.Devices {
 	return c.localDevices
 }
 
diff --git a/lxd/container_put.go b/lxd/container_put.go
index 471b022..15407df 100644
--- a/lxd/container_put.go
+++ b/lxd/container_put.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/gorilla/mux"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/osarch"
 
@@ -17,7 +18,7 @@ import (
 type containerPutReq struct {
 	Architecture string            `json:"architecture"`
 	Config       map[string]string `json:"config"`
-	Devices      shared.Devices    `json:"devices"`
+	Devices      types.Devices     `json:"devices"`
 	Ephemeral    bool              `json:"ephemeral"`
 	Profiles     []string          `json:"profiles"`
 	Restore      string            `json:"restore"`
diff --git a/lxd/container_test.go b/lxd/container_test.go
index bfcdf66..da83174 100644
--- a/lxd/container_test.go
+++ b/lxd/container_test.go
@@ -3,6 +3,7 @@ package main
 import (
 	"fmt"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 )
 
@@ -36,7 +37,7 @@ func (suite *lxdTestSuite) TestContainer_ProfilesMulti() {
 		"unprivileged",
 		"unprivileged",
 		map[string]string{"security.privileged": "true"},
-		shared.Devices{})
+		types.Devices{})
 
 	suite.Req.Nil(err, "Failed to create the unprivileged profile.")
 	defer func() {
@@ -70,8 +71,8 @@ func (suite *lxdTestSuite) TestContainer_ProfilesOverwriteDefaultNic() {
 		Ctype:     cTypeRegular,
 		Ephemeral: false,
 		Config:    map[string]string{"security.privileged": "true"},
-		Devices: shared.Devices{
-			"eth0": shared.Device{
+		Devices: types.Devices{
+			"eth0": types.Device{
 				"type":    "nic",
 				"nictype": "bridged",
 				"parent":  "unknownbr0"}},
@@ -100,8 +101,8 @@ func (suite *lxdTestSuite) TestContainer_LoadFromDB() {
 		Ctype:     cTypeRegular,
 		Ephemeral: false,
 		Config:    map[string]string{"security.privileged": "true"},
-		Devices: shared.Devices{
-			"eth0": shared.Device{
+		Devices: types.Devices{
+			"eth0": types.Device{
 				"type":    "nic",
 				"nictype": "bridged",
 				"parent":  "unknownbr0"}},
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 93b21a4..b7754ea 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -11,6 +11,7 @@ import (
 	"github.com/dustinkirkland/golang-petname"
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/osarch"
 
@@ -52,7 +53,7 @@ type containerImageSource struct {
 type containerPostReq struct {
 	Architecture string               `json:"architecture"`
 	Config       map[string]string    `json:"config"`
-	Devices      shared.Devices       `json:"devices"`
+	Devices      types.Devices        `json:"devices"`
 	Ephemeral    bool                 `json:"ephemeral"`
 	Name         string               `json:"name"`
 	Profiles     []string             `json:"profiles"`
@@ -431,7 +432,7 @@ func containersPost(d *Daemon, r *http.Request) Response {
 	}
 
 	if req.Devices == nil {
-		req.Devices = shared.Devices{}
+		req.Devices = types.Devices{}
 	}
 
 	if req.Config == nil {
diff --git a/lxd/db_containers.go b/lxd/db_containers.go
index eec6e9c..74aacbf 100644
--- a/lxd/db_containers.go
+++ b/lxd/db_containers.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"time"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 
 	log "gopkg.in/inconshreveable/log15.v2"
@@ -108,7 +109,7 @@ func dbContainerGet(db *sql.DB, name string) (containerArgs, error) {
 	args.Profiles = profiles
 
 	/* get container_devices */
-	args.Devices = shared.Devices{}
+	args.Devices = types.Devices{}
 	newdevs, err := dbDevices(db, name, false)
 	if err != nil {
 		return args, err
diff --git a/lxd/db_devices.go b/lxd/db_devices.go
index c65afd8..941bad8 100644
--- a/lxd/db_devices.go
+++ b/lxd/db_devices.go
@@ -6,7 +6,7 @@ import (
 
 	_ "github.com/mattn/go-sqlite3"
 
-	"github.com/lxc/lxd/shared"
+	"github.com/lxc/lxd/lxd/types"
 )
 
 func dbDeviceTypeToString(t int) (string, error) {
@@ -51,7 +51,7 @@ func dbDeviceTypeToInt(t string) (int, error) {
 	}
 }
 
-func dbDevicesAdd(tx *sql.Tx, w string, cID int64, devices shared.Devices) error {
+func dbDevicesAdd(tx *sql.Tx, w string, cID int64, devices types.Devices) error {
 	// Prepare the devices entry SQL
 	str1 := fmt.Sprintf("INSERT INTO %ss_devices (%s_id, name, type) VALUES (?, ?, ?)", w, w)
 	stmt1, err := tx.Prepare(str1)
@@ -102,10 +102,10 @@ func dbDevicesAdd(tx *sql.Tx, w string, cID int64, devices shared.Devices) error
 	return nil
 }
 
-func dbDeviceConfig(db *sql.DB, id int, isprofile bool) (shared.Device, error) {
+func dbDeviceConfig(db *sql.DB, id int, isprofile bool) (types.Device, error) {
 	var query string
 	var key, value string
-	newdev := shared.Device{} // That's a map[string]string
+	newdev := types.Device{} // That's a map[string]string
 	inargs := []interface{}{id}
 	outfmt := []interface{}{key, value}
 
@@ -130,7 +130,7 @@ func dbDeviceConfig(db *sql.DB, id int, isprofile bool) (shared.Device, error) {
 	return newdev, nil
 }
 
-func dbDevices(db *sql.DB, qName string, isprofile bool) (shared.Devices, error) {
+func dbDevices(db *sql.DB, qName string, isprofile bool) (types.Devices, error) {
 	var q string
 	if isprofile {
 		q = `SELECT profiles_devices.id, profiles_devices.name, profiles_devices.type
@@ -152,7 +152,7 @@ func dbDevices(db *sql.DB, qName string, isprofile bool) (shared.Devices, error)
 		return nil, err
 	}
 
-	devices := shared.Devices{}
+	devices := types.Devices{}
 	for _, r := range results {
 		id = r[0].(int)
 		name = r[1].(string)
diff --git a/lxd/db_profiles.go b/lxd/db_profiles.go
index 4cbfc9d..d935848 100644
--- a/lxd/db_profiles.go
+++ b/lxd/db_profiles.go
@@ -6,6 +6,7 @@ import (
 
 	_ "github.com/mattn/go-sqlite3"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 )
 
@@ -59,7 +60,7 @@ func dbProfileGet(db *sql.DB, profile string) (int64, *shared.ProfileConfig, err
 }
 
 func dbProfileCreate(db *sql.DB, profile string, description string, config map[string]string,
-	devices shared.Devices) (int64, error) {
+	devices types.Devices) (int64, error) {
 
 	tx, err := dbBegin(db)
 	if err != nil {
@@ -104,7 +105,7 @@ func dbProfileCreateDefault(db *sql.DB) error {
 		return nil
 	}
 
-	id, err := dbProfileCreate(db, "default", "Default LXD profile", map[string]string{}, shared.Devices{})
+	id, err := dbProfileCreate(db, "default", "Default LXD profile", map[string]string{}, types.Devices{})
 	if err != nil {
 		return err
 	}
@@ -128,7 +129,7 @@ func dbProfileCreateDocker(db *sql.DB) error {
 		"type":   "disk",
 		"source": "/dev/null",
 	}
-	devices := map[string]shared.Device{"aadisable": aadisable}
+	devices := map[string]map[string]string{"aadisable": aadisable}
 
 	_, err = dbProfileCreate(db, "docker", "Profile supporting docker in containers", config, devices)
 	return err
diff --git a/lxd/db_test.go b/lxd/db_test.go
index b2e3984..9e9aa38 100644
--- a/lxd/db_test.go
+++ b/lxd/db_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/logging"
 )
@@ -580,9 +581,9 @@ func Test_dbContainerProfiles(t *testing.T) {
 func Test_dbDevices_profiles(t *testing.T) {
 	var db *sql.DB
 	var err error
-	var result shared.Devices
-	var subresult shared.Device
-	var expected shared.Device
+	var result types.Devices
+	var subresult types.Device
+	var expected types.Device
 
 	db = createTestDb(t)
 	defer db.Close()
@@ -592,7 +593,7 @@ func Test_dbDevices_profiles(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	expected = shared.Device{"type": "nic", "devicekey": "devicevalue"}
+	expected = types.Device{"type": "nic", "devicekey": "devicevalue"}
 	subresult = result["devicename"]
 
 	for key, value := range expected {
@@ -606,9 +607,9 @@ func Test_dbDevices_profiles(t *testing.T) {
 func Test_dbDevices_containers(t *testing.T) {
 	var db *sql.DB
 	var err error
-	var result shared.Devices
-	var subresult shared.Device
-	var expected shared.Device
+	var result types.Devices
+	var subresult types.Device
+	var expected types.Device
 
 	db = createTestDb(t)
 	defer db.Close()
@@ -618,7 +619,7 @@ func Test_dbDevices_containers(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	expected = shared.Device{"type": "nic", "configkey": "configvalue"}
+	expected = types.Device{"type": "nic", "configkey": "configvalue"}
 	subresult = result["somename"]
 
 	for key, value := range expected {
diff --git a/lxd/profiles.go b/lxd/profiles.go
index 3c7d08b..98e852c 100644
--- a/lxd/profiles.go
+++ b/lxd/profiles.go
@@ -12,6 +12,7 @@ import (
 	"github.com/gorilla/mux"
 	_ "github.com/mattn/go-sqlite3"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/version"
 
@@ -23,7 +24,7 @@ type profilesPostReq struct {
 	Name        string            `json:"name"`
 	Config      map[string]string `json:"config"`
 	Description string            `json:"description"`
-	Devices     shared.Devices    `json:"devices"`
+	Devices     types.Devices     `json:"devices"`
 }
 
 func profilesGet(d *Daemon, r *http.Request) Response {
diff --git a/lxd/storage.go b/lxd/storage.go
index f2b919f..44c131f 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -13,6 +13,7 @@ import (
 
 	"github.com/gorilla/websocket"
 
+	"github.com/lxc/lxd/lxd/types"
 	"github.com/lxc/lxd/shared"
 	"github.com/lxc/lxd/shared/ioprogress"
 	"github.com/lxc/lxd/shared/logging"
@@ -654,7 +655,7 @@ func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) conta
 		config[ent.GetKey()] = ent.GetValue()
 	}
 
-	devices := shared.Devices{}
+	devices := types.Devices{}
 	for _, ent := range snap.LocalDevices {
 		props := map[string]string{}
 		for _, prop := range ent.Config {
diff --git a/lxd/types/devices.go b/lxd/types/devices.go
new file mode 100644
index 0000000..04cd766
--- /dev/null
+++ b/lxd/types/devices.go
@@ -0,0 +1,166 @@
+package types
+
+import (
+	"sort"
+
+	"github.com/lxc/lxd/shared"
+)
+
+type Device map[string]string
+type Devices map[string]map[string]string
+
+func (list Devices) ContainsName(k string) bool {
+	if list[k] != nil {
+		return true
+	}
+	return false
+}
+
+func (d Device) get(key string) string {
+	return d[key]
+}
+
+func (list Devices) Contains(k string, d Device) bool {
+	// If it didn't exist, it's different
+	if list[k] == nil {
+		return false
+	}
+
+	old := list[k]
+
+	return deviceEquals(old, d)
+}
+
+func deviceEquals(old Device, d Device) bool {
+	// Check for any difference and addition/removal of properties
+	for k, _ := range d {
+		if d[k] != old[k] {
+			return false
+		}
+	}
+
+	for k, _ := range old {
+		if d[k] != old[k] {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (old Devices) Update(newlist Devices) (map[string]Device, map[string]Device, map[string]Device) {
+	rmlist := map[string]Device{}
+	addlist := map[string]Device{}
+	updatelist := map[string]Device{}
+
+	for key, d := range old {
+		if !newlist.Contains(key, d) {
+			rmlist[key] = d
+		}
+	}
+
+	for key, d := range newlist {
+		if !old.Contains(key, d) {
+			addlist[key] = d
+		}
+	}
+
+	for key, d := range addlist {
+		srcOldDevice := rmlist[key]
+		var oldDevice Device
+		err := shared.DeepCopy(&srcOldDevice, &oldDevice)
+		if err != nil {
+			continue
+		}
+
+		srcNewDevice := newlist[key]
+		var newDevice Device
+		err = shared.DeepCopy(&srcNewDevice, &newDevice)
+		if err != nil {
+			continue
+		}
+
+		for _, k := range []string{"limits.max", "limits.read", "limits.write", "limits.egress", "limits.ingress", "ipv4.address", "ipv6.address"} {
+			delete(oldDevice, k)
+			delete(newDevice, k)
+		}
+
+		if deviceEquals(oldDevice, newDevice) {
+			delete(rmlist, key)
+			delete(addlist, key)
+			updatelist[key] = d
+		}
+	}
+
+	return rmlist, addlist, updatelist
+}
+
+func (newBaseDevices Devices) ExtendFromProfile(currentFullDevices Devices, newDevicesFromProfile Devices) error {
+	// For any entry which exists in a profile and doesn't in the container config, add it
+
+	for name, newDev := range newDevicesFromProfile {
+		if curDev, ok := currentFullDevices[name]; ok {
+			newBaseDevices[name] = curDev
+		} else {
+			newBaseDevices[name] = newDev
+		}
+	}
+
+	return nil
+}
+
+type namedDevice struct {
+	name   string
+	device Device
+}
+type sortableDevices []namedDevice
+
+func (devices Devices) toSortable() sortableDevices {
+	named := []namedDevice{}
+	for k, d := range devices {
+		named = append(named, namedDevice{k, d})
+	}
+
+	return named
+}
+
+func (devices sortableDevices) Len() int {
+	return len(devices)
+}
+
+func (devices sortableDevices) Less(i, j int) bool {
+	a := devices[i]
+	b := devices[j]
+
+	if a.device["type"] == "disk" && b.device["type"] == "disk" {
+		if a.device["path"] == b.device["path"] {
+			return a.name < b.name
+		}
+
+		return a.device["path"] < b.device["path"]
+	}
+
+	return a.name < b.name
+}
+
+func (devices sortableDevices) Swap(i, j int) {
+	tmp := devices[i]
+	devices[i] = devices[j]
+	devices[j] = tmp
+}
+
+func (devices sortableDevices) Names() []string {
+	result := []string{}
+	for _, d := range devices {
+		result = append(result, d.name)
+	}
+
+	return result
+}
+
+/* DeviceNames returns the device names for this Devices in sorted order */
+func (devices Devices) DeviceNames() []string {
+	sortable := devices.toSortable()
+	sort.Sort(sortable)
+	return sortable.Names()
+}
diff --git a/lxd/types/devices_test.go b/lxd/types/devices_test.go
new file mode 100644
index 0000000..4eee791
--- /dev/null
+++ b/lxd/types/devices_test.go
@@ -0,0 +1,22 @@
+package types
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestSortableDevices(t *testing.T) {
+	devices := Devices{
+		"1": Device{"type": "nic"},
+		"3": Device{"type": "disk", "path": "/foo/bar"},
+		"4": Device{"type": "disk", "path": "/foo"},
+		"2": Device{"type": "nic"},
+	}
+
+	expected := []string{"1", "2", "4", "3"}
+
+	result := devices.DeviceNames()
+	if !reflect.DeepEqual(result, expected) {
+		t.Error("devices sorted incorrectly")
+	}
+}
diff --git a/shared/container.go b/shared/container.go
index fd15bc5..0af7f44 100644
--- a/shared/container.go
+++ b/shared/container.go
@@ -65,33 +65,33 @@ type ContainerExecControl struct {
 }
 
 type SnapshotInfo struct {
-	Architecture    string            `json:"architecture"`
-	Config          map[string]string `json:"config"`
-	CreationDate    time.Time         `json:"created_at"`
-	Devices         Devices           `json:"devices"`
-	Ephemeral       bool              `json:"ephemeral"`
-	ExpandedConfig  map[string]string `json:"expanded_config"`
-	ExpandedDevices Devices           `json:"expanded_devices"`
-	LastUsedDate    time.Time         `json:"last_used_at"`
-	Name            string            `json:"name"`
-	Profiles        []string          `json:"profiles"`
-	Stateful        bool              `json:"stateful"`
+	Architecture    string                       `json:"architecture"`
+	Config          map[string]string            `json:"config"`
+	CreationDate    time.Time                    `json:"created_at"`
+	Devices         map[string]map[string]string `json:"devices"`
+	Ephemeral       bool                         `json:"ephemeral"`
+	ExpandedConfig  map[string]string            `json:"expanded_config"`
+	ExpandedDevices map[string]map[string]string `json:"expanded_devices"`
+	LastUsedDate    time.Time                    `json:"last_used_at"`
+	Name            string                       `json:"name"`
+	Profiles        []string                     `json:"profiles"`
+	Stateful        bool                         `json:"stateful"`
 }
 
 type ContainerInfo struct {
-	Architecture    string            `json:"architecture"`
-	Config          map[string]string `json:"config"`
-	CreationDate    time.Time         `json:"created_at"`
-	Devices         Devices           `json:"devices"`
-	Ephemeral       bool              `json:"ephemeral"`
-	ExpandedConfig  map[string]string `json:"expanded_config"`
-	ExpandedDevices Devices           `json:"expanded_devices"`
-	LastUsedDate    time.Time         `json:"last_used_at"`
-	Name            string            `json:"name"`
-	Profiles        []string          `json:"profiles"`
-	Stateful        bool              `json:"stateful"`
-	Status          string            `json:"status"`
-	StatusCode      StatusCode        `json:"status_code"`
+	Architecture    string                       `json:"architecture"`
+	Config          map[string]string            `json:"config"`
+	CreationDate    time.Time                    `json:"created_at"`
+	Devices         map[string]map[string]string `json:"devices"`
+	Ephemeral       bool                         `json:"ephemeral"`
+	ExpandedConfig  map[string]string            `json:"expanded_config"`
+	ExpandedDevices map[string]map[string]string `json:"expanded_devices"`
+	LastUsedDate    time.Time                    `json:"last_used_at"`
+	Name            string                       `json:"name"`
+	Profiles        []string                     `json:"profiles"`
+	Stateful        bool                         `json:"stateful"`
+	Status          string                       `json:"status"`
+	StatusCode      StatusCode                   `json:"status_code"`
 }
 
 func (c ContainerInfo) IsActive() bool {
@@ -110,11 +110,11 @@ func (c ContainerInfo) IsActive() bool {
  * ContainerState, namely those which a user may update
  */
 type BriefContainerInfo struct {
-	Name      string            `json:"name"`
-	Profiles  []string          `json:"profiles"`
-	Config    map[string]string `json:"config"`
-	Devices   Devices           `json:"devices"`
-	Ephemeral bool              `json:"ephemeral"`
+	Name      string                       `json:"name"`
+	Profiles  []string                     `json:"profiles"`
+	Config    map[string]string            `json:"config"`
+	Devices   map[string]map[string]string `json:"devices"`
+	Ephemeral bool                         `json:"ephemeral"`
 }
 
 func (c *ContainerInfo) Brief() BriefContainerInfo {
@@ -146,11 +146,11 @@ const (
 )
 
 type ProfileConfig struct {
-	Name        string            `json:"name"`
-	Config      map[string]string `json:"config"`
-	Description string            `json:"description"`
-	Devices     Devices           `json:"devices"`
-	UsedBy      []string          `json:"used_by"`
+	Name        string                       `json:"name"`
+	Config      map[string]string            `json:"config"`
+	Description string                       `json:"description"`
+	Devices     map[string]map[string]string `json:"devices"`
+	UsedBy      []string                     `json:"used_by"`
 }
 
 type NetworkConfig struct {
diff --git a/shared/devices.go b/shared/devices.go
deleted file mode 100644
index fe43c9a..0000000
--- a/shared/devices.go
+++ /dev/null
@@ -1,164 +0,0 @@
-package shared
-
-import (
-	"sort"
-)
-
-type Device map[string]string
-type Devices map[string]Device
-
-func (list Devices) ContainsName(k string) bool {
-	if list[k] != nil {
-		return true
-	}
-	return false
-}
-
-func (d Device) get(key string) string {
-	return d[key]
-}
-
-func (list Devices) Contains(k string, d Device) bool {
-	// If it didn't exist, it's different
-	if list[k] == nil {
-		return false
-	}
-
-	old := list[k]
-
-	return deviceEquals(old, d)
-}
-
-func deviceEquals(old Device, d Device) bool {
-	// Check for any difference and addition/removal of properties
-	for k, _ := range d {
-		if d[k] != old[k] {
-			return false
-		}
-	}
-
-	for k, _ := range old {
-		if d[k] != old[k] {
-			return false
-		}
-	}
-
-	return true
-}
-
-func (old Devices) Update(newlist Devices) (map[string]Device, map[string]Device, map[string]Device) {
-	rmlist := map[string]Device{}
-	addlist := map[string]Device{}
-	updatelist := map[string]Device{}
-
-	for key, d := range old {
-		if !newlist.Contains(key, d) {
-			rmlist[key] = d
-		}
-	}
-
-	for key, d := range newlist {
-		if !old.Contains(key, d) {
-			addlist[key] = d
-		}
-	}
-
-	for key, d := range addlist {
-		srcOldDevice := rmlist[key]
-		var oldDevice Device
-		err := DeepCopy(&srcOldDevice, &oldDevice)
-		if err != nil {
-			continue
-		}
-
-		srcNewDevice := newlist[key]
-		var newDevice Device
-		err = DeepCopy(&srcNewDevice, &newDevice)
-		if err != nil {
-			continue
-		}
-
-		for _, k := range []string{"limits.max", "limits.read", "limits.write", "limits.egress", "limits.ingress", "ipv4.address", "ipv6.address"} {
-			delete(oldDevice, k)
-			delete(newDevice, k)
-		}
-
-		if deviceEquals(oldDevice, newDevice) {
-			delete(rmlist, key)
-			delete(addlist, key)
-			updatelist[key] = d
-		}
-	}
-
-	return rmlist, addlist, updatelist
-}
-
-func (newBaseDevices Devices) ExtendFromProfile(currentFullDevices Devices, newDevicesFromProfile Devices) error {
-	// For any entry which exists in a profile and doesn't in the container config, add it
-
-	for name, newDev := range newDevicesFromProfile {
-		if curDev, ok := currentFullDevices[name]; ok {
-			newBaseDevices[name] = curDev
-		} else {
-			newBaseDevices[name] = newDev
-		}
-	}
-
-	return nil
-}
-
-type namedDevice struct {
-	name   string
-	device Device
-}
-type sortableDevices []namedDevice
-
-func (devices Devices) toSortable() sortableDevices {
-	named := []namedDevice{}
-	for k, d := range devices {
-		named = append(named, namedDevice{k, d})
-	}
-
-	return named
-}
-
-func (devices sortableDevices) Len() int {
-	return len(devices)
-}
-
-func (devices sortableDevices) Less(i, j int) bool {
-	a := devices[i]
-	b := devices[j]
-
-	if a.device["type"] == "disk" && b.device["type"] == "disk" {
-		if a.device["path"] == b.device["path"] {
-			return a.name < b.name
-		}
-
-		return a.device["path"] < b.device["path"]
-	}
-
-	return a.name < b.name
-}
-
-func (devices sortableDevices) Swap(i, j int) {
-	tmp := devices[i]
-	devices[i] = devices[j]
-	devices[j] = tmp
-}
-
-func (devices sortableDevices) Names() []string {
-	result := []string{}
-	for _, d := range devices {
-		result = append(result, d.name)
-	}
-
-	return result
-}
-
-/* DeviceNames returns the device names for this Devices in sorted order */
-func (devices Devices) DeviceNames() []string {
-	sortable := devices.toSortable()
-	sort.Sort(sortable)
-	return sortable.Names()
-}
diff --git a/shared/devices_test.go b/shared/devices_test.go
deleted file mode 100644
index 07aaed6..0000000
--- a/shared/devices_test.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package shared
-
-import (
-	"reflect"
-	"testing"
-)
-
-func TestSortableDevices(t *testing.T) {
-	devices := Devices{
-		"1": Device{"type": "nic"},
-		"3": Device{"type": "disk", "path": "/foo/bar"},
-		"4": Device{"type": "disk", "path": "/foo"},
-		"2": Device{"type": "nic"},
-	}
-
-	expected := []string{"1", "2", "4", "3"}
-
-	result := devices.DeviceNames()
-	if !reflect.DeepEqual(result, expected) {
-		t.Error("devices sorted incorrectly")
-	}
-}


More information about the lxc-devel mailing list