[lxc-devel] [lxd/master] Instance interface into instance package
tomponline on Github
lxc-bot at linuxcontainers.org
Thu Nov 21 11:10:57 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 572 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191121/e158bd65/attachment-0001.bin>
-------------- next part --------------
From 5c85d60df84c9d43dd4c6b2486e2d32d7f15943a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 21 Nov 2019 11:06:50 +0000
Subject: [PATCH 1/4] lxd/vm/qemu: Removes deprecated Storage() function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/vm_qemu.go | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/lxd/vm_qemu.go b/lxd/vm_qemu.go
index 19781a3d2f..7f84e5eb35 100644
--- a/lxd/vm_qemu.go
+++ b/lxd/vm_qemu.go
@@ -49,7 +49,7 @@ import (
var vmVsockTimeout time.Duration = time.Second
-func vmQemuLoad(s *state.State, args db.InstanceArgs, profiles []api.Profile) (Instance, error) {
+func vmQemuLoad(s *state.State, args db.InstanceArgs, profiles []api.Profile) (instance.Instance, error) {
// Create the container struct.
vm := vmQemuInstantiate(s, args)
@@ -111,7 +111,7 @@ func vmQemuInstantiate(s *state.State, args db.InstanceArgs) *vmQemu {
}
// vmQemuCreate creates a new storage volume record and returns an initialised Instance.
-func vmQemuCreate(s *state.State, args db.InstanceArgs) (Instance, error) {
+func vmQemuCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
// Create the instance struct.
vm := &vmQemu{
state: s,
@@ -1262,12 +1262,12 @@ func (vm *vmQemu) IsPrivileged() bool {
return shared.IsTrue(vm.expandedConfig["security.privileged"])
}
-func (vm *vmQemu) Restore(source Instance, stateful bool) error {
+func (vm *vmQemu) Restore(source instance.Instance, stateful bool) error {
return fmt.Errorf("Restore Not implemented")
}
-func (vm *vmQemu) Snapshots() ([]Instance, error) {
- return []Instance{}, nil
+func (vm *vmQemu) Snapshots() ([]instance.Instance, error) {
+ return []instance.Instance{}, nil
}
func (vm *vmQemu) Backups() ([]backup.Backup, error) {
@@ -2699,12 +2699,6 @@ func (vm *vmQemu) StorageStop() (bool, error) {
return false, storagePools.ErrNotImplemented
}
-// Storage is deprecated will always return nil.
-// It is here just to satisfy the Instance interface (which will be updated in the future).
-func (vm *vmQemu) Storage() storage {
- return nil
-}
-
func (vm *vmQemu) DeferTemplateApply(trigger string) error {
return nil
}
From 28e76d920760c3ffdc20c64729bcaf181a631813 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 21 Nov 2019 11:07:25 +0000
Subject: [PATCH 2/4] lxd/instance/instance/interface: Moves Instance interface
into instance pkg
- Also removes Storage() function from interface so as not dependent on storage type in main pkg.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/instance_interface.go | 113 +++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)
create mode 100644 lxd/instance/instance_interface.go
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
new file mode 100644
index 0000000000..fecd7d48b9
--- /dev/null
+++ b/lxd/instance/instance_interface.go
@@ -0,0 +1,113 @@
+package instance
+
+import (
+ "io"
+ "os"
+ "time"
+
+ "github.com/lxc/lxd/lxd/backup"
+ "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/instancetype"
+ "github.com/lxc/lxd/lxd/operations"
+ "github.com/lxc/lxd/lxd/state"
+ "github.com/lxc/lxd/shared/api"
+)
+
+// The Instance interface
+type Instance interface {
+ // Instance actions
+ Freeze() error
+ Shutdown(timeout time.Duration) error
+ Start(stateful bool) error
+ Stop(stateful bool) error
+ Unfreeze() error
+
+ IsPrivileged() bool
+
+ // Snapshots & migration & backups
+ Restore(source Instance, stateful bool) error
+ Snapshots() ([]Instance, error)
+ Backups() ([]backup.Backup, error)
+
+ // Config handling
+ Rename(newName string) error
+
+ // TODO rename db.InstanceArgs to db.InstanceArgs.
+ Update(newConfig db.InstanceArgs, userRequested bool) error
+
+ Delete() error
+ Export(w io.Writer, properties map[string]string) error
+
+ // Live configuration
+ CGroupGet(key string) (string, error)
+ CGroupSet(key string, value string) error
+ VolatileSet(changes map[string]string) error
+
+ // File handling
+ FileExists(path string) error
+ FilePull(srcpath string, dstpath string) (int64, int64, os.FileMode, string, []string, error)
+ FilePush(fileType string, srcpath string, dstpath string, uid int64, gid int64, mode int, write string) error
+ FileRemove(path string) error
+
+ // Console - Allocate and run a console tty.
+ Console() (*os.File, error)
+ Exec(command []string, env map[string]string, stdin *os.File, stdout *os.File, stderr *os.File, cwd string, uid uint32, gid uint32) (Cmd, error)
+
+ // Status
+ Render() (interface{}, interface{}, error)
+ RenderFull() (*api.InstanceFull, interface{}, error)
+ RenderState() (*api.InstanceState, error)
+ IsRunning() bool
+ IsFrozen() bool
+ IsEphemeral() bool
+ IsSnapshot() bool
+ IsStateful() bool
+
+ // Hooks
+ DeviceEventHandler(*device.RunConfig) error
+
+ // Properties
+ ID() int
+ Location() string
+ Project() string
+ Name() string
+ Type() instancetype.Type
+ Description() string
+ Architecture() int
+ CreationDate() time.Time
+ LastUsedDate() time.Time
+ ExpandedConfig() map[string]string
+ ExpandedDevices() deviceConfig.Devices
+ LocalConfig() map[string]string
+ LocalDevices() deviceConfig.Devices
+ Profiles() []string
+ InitPID() int
+ State() string
+ ExpiryDate() time.Time
+
+ // Paths
+ Path() string
+ RootfsPath() string
+ TemplatesPath() string
+ StatePath() string
+ LogFilePath() string
+ ConsoleBufferLogPath() string
+ LogPath() string
+ DevicesPath() string
+
+ // Storage
+ StoragePool() (string, error)
+
+ // Progress reporting
+
+ SetOperation(op *operations.Operation)
+
+ // FIXME: Those should be internal functions
+ // Needed for migration for now.
+ StorageStart() (bool, error)
+ StorageStop() (bool, error)
+ DeferTemplateApply(trigger string) error
+ DaemonState() *state.State
+}
From 239ed8365356e20f068527c304d03a426c5c9afe Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 21 Nov 2019 11:07:55 +0000
Subject: [PATCH 3/4] lxd/instance/interface: Removes old Instance interface
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance_interface.go | 115 --------------------------------------
1 file changed, 115 deletions(-)
delete mode 100644 lxd/instance_interface.go
diff --git a/lxd/instance_interface.go b/lxd/instance_interface.go
deleted file mode 100644
index 274de7a8b8..0000000000
--- a/lxd/instance_interface.go
+++ /dev/null
@@ -1,115 +0,0 @@
-package main
-
-import (
- "io"
- "os"
- "time"
-
- "github.com/lxc/lxd/lxd/backup"
- "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/operations"
- "github.com/lxc/lxd/lxd/state"
- "github.com/lxc/lxd/shared/api"
-)
-
-// The Instance interface
-type Instance interface {
- // Instance actions
- Freeze() error
- Shutdown(timeout time.Duration) error
- Start(stateful bool) error
- Stop(stateful bool) error
- Unfreeze() error
-
- IsPrivileged() bool
-
- // Snapshots & migration & backups
- Restore(source Instance, stateful bool) error
- Snapshots() ([]Instance, error)
- Backups() ([]backup.Backup, error)
-
- // Config handling
- Rename(newName string) error
-
- // TODO rename db.InstanceArgs to db.InstanceArgs.
- Update(newConfig db.InstanceArgs, userRequested bool) error
-
- Delete() error
- Export(w io.Writer, properties map[string]string) error
-
- // Live configuration
- CGroupGet(key string) (string, error)
- CGroupSet(key string, value string) error
- VolatileSet(changes map[string]string) error
-
- // File handling
- FileExists(path string) error
- FilePull(srcpath string, dstpath string) (int64, int64, os.FileMode, string, []string, error)
- FilePush(fileType string, srcpath string, dstpath string, uid int64, gid int64, mode int, write string) error
- FileRemove(path string) error
-
- // Console - Allocate and run a console tty.
- Console() (*os.File, error)
- Exec(command []string, env map[string]string, stdin *os.File, stdout *os.File, stderr *os.File, cwd string, uid uint32, gid uint32) (instance.Cmd, error)
-
- // Status
- Render() (interface{}, interface{}, error)
- RenderFull() (*api.InstanceFull, interface{}, error)
- RenderState() (*api.InstanceState, error)
- IsRunning() bool
- IsFrozen() bool
- IsEphemeral() bool
- IsSnapshot() bool
- IsStateful() bool
-
- // Hooks
- DeviceEventHandler(*device.RunConfig) error
-
- // Properties
- ID() int
- Location() string
- Project() string
- Name() string
- Type() instancetype.Type
- Description() string
- Architecture() int
- CreationDate() time.Time
- LastUsedDate() time.Time
- ExpandedConfig() map[string]string
- ExpandedDevices() deviceConfig.Devices
- LocalConfig() map[string]string
- LocalDevices() deviceConfig.Devices
- Profiles() []string
- InitPID() int
- State() string
- ExpiryDate() time.Time
-
- // Paths
- Path() string
- RootfsPath() string
- TemplatesPath() string
- StatePath() string
- LogFilePath() string
- ConsoleBufferLogPath() string
- LogPath() string
- DevicesPath() string
-
- // Storage
- StoragePool() (string, error)
-
- // Progress reporting
-
- SetOperation(op *operations.Operation)
-
- // FIXME: Those should be internal functions
- // Needed for migration for now.
- StorageStart() (bool, error)
- StorageStop() (bool, error)
- Storage() storage
- DeferTemplateApply(trigger string) error
- DaemonState() *state.State
-}
From f5a0370c14f072cc631a9d92d533ade51021c104 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 21 Nov 2019 11:08:15 +0000
Subject: [PATCH 4/4] lxd: Updates references to Instance interface
- Also where Storage() is needed, converts to containerLXC type.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/backup.go | 22 +++++--
lxd/container.go | 104 ++++++++++++++++++++-------------
lxd/container_console.go | 3 +-
lxd/container_exec.go | 2 +-
lxd/container_file.go | 7 ++-
lxd/container_lxc.go | 12 ++--
lxd/container_metadata.go | 3 +-
lxd/container_post.go | 7 ++-
lxd/containers.go | 11 ++--
lxd/containers_get.go | 3 +-
lxd/containers_post.go | 5 +-
lxd/devices.go | 12 ++--
lxd/migrate.go | 7 ++-
lxd/migrate_container.go | 29 +++++----
lxd/networks_utils.go | 3 +-
lxd/storage.go | 37 ++++++------
lxd/storage_btrfs.go | 84 +++++++++++++++++---------
lxd/storage_ceph.go | 59 +++++++++++--------
lxd/storage_ceph_utils.go | 7 ++-
lxd/storage_cephfs.go | 39 +++++++------
lxd/storage_dir.go | 70 +++++++++++++---------
lxd/storage_lvm.go | 59 +++++++++++--------
lxd/storage_lvm_utils.go | 15 ++---
lxd/storage_migration.go | 17 ++++--
lxd/storage_migration_btrfs.go | 14 ++++-
lxd/storage_migration_ceph.go | 7 ++-
lxd/storage_migration_zfs.go | 5 +-
lxd/storage_mock.go | 37 ++++++------
lxd/storage_zfs.go | 72 +++++++++++++----------
29 files changed, 455 insertions(+), 297 deletions(-)
diff --git a/lxd/backup.go b/lxd/backup.go
index 3be5273cd7..bdaa14315d 100644
--- a/lxd/backup.go
+++ b/lxd/backup.go
@@ -14,6 +14,8 @@ import (
"github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/state"
@@ -25,7 +27,7 @@ import (
)
// Create a new backup
-func backupCreate(s *state.State, args db.InstanceBackupArgs, sourceContainer Instance) error {
+func backupCreate(s *state.State, args db.InstanceBackupArgs, sourceContainer instance.Instance) error {
// Create the database entry
err := s.Cluster.ContainerBackupCreate(args)
if err != nil {
@@ -59,8 +61,14 @@ func backupCreate(s *state.State, args db.InstanceBackupArgs, sourceContainer In
}
defer os.RemoveAll(tmpPath)
+ if sourceContainer.Type() != instancetype.Container {
+ return fmt.Errorf("Instance type must be container")
+ }
+
+ ct := sourceContainer.(*containerLXC)
+
// Now create the empty snapshot
- err = sourceContainer.Storage().ContainerBackupCreate(tmpPath, *b, sourceContainer)
+ err = ct.Storage().ContainerBackupCreate(tmpPath, *b, sourceContainer)
if err != nil {
s.Cluster.ContainerBackupRemove(args.Name)
return errors.Wrap(err, "Backup storage")
@@ -164,16 +172,22 @@ func backupFixStoragePool(c *db.Cluster, b backup.Info, useDefaultPool bool) err
return nil
}
-func backupCreateTarball(s *state.State, path string, b backup.Backup, c Instance) error {
+func backupCreateTarball(s *state.State, path string, b backup.Backup, c instance.Instance) error {
// Create the index
pool, err := c.StoragePool()
if err != nil {
return err
}
+ if c.Type() != instancetype.Container {
+ return fmt.Errorf("Instance type must be container")
+ }
+
+ ct := c.(*containerLXC)
+
indexFile := backup.Info{
Name: c.Name(),
- Backend: c.Storage().GetStorageTypeName(),
+ Backend: ct.Storage().GetStorageTypeName(),
Privileged: c.IsPrivileged(),
Pool: pool,
Snapshots: []string{},
diff --git a/lxd/container.go b/lxd/container.go
index 1b25779c21..38ddca37e5 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -22,6 +22,7 @@ import (
"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/operations"
"github.com/lxc/lxd/lxd/seccomp"
@@ -205,7 +206,7 @@ func instanceValidDevices(state *state.State, cluster *db.Cluster, instanceType
// 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
+ var inst instance.Instance
if instanceType == instancetype.Container {
c := &containerLXC{
@@ -257,7 +258,7 @@ func instanceValidDevices(state *state.State, cluster *db.Cluster, instanceType
// The container interface
type container interface {
- Instance
+ instance.Instance
/* actionScript here is a script called action.sh in the stateDir, to
* be passed to CRIU as --action-script
@@ -282,7 +283,7 @@ type container interface {
}
// instanceCreateAsEmpty creates an empty instance.
-func instanceCreateAsEmpty(d *Daemon, args db.InstanceArgs) (Instance, error) {
+func instanceCreateAsEmpty(d *Daemon, args db.InstanceArgs) (instance.Instance, error) {
// Create the instance record.
inst, err := instanceCreateInternal(d.State(), args)
if err != nil {
@@ -310,8 +311,10 @@ func instanceCreateAsEmpty(d *Daemon, args db.InstanceArgs) (Instance, error) {
return nil, errors.Wrap(err, "Create instance")
}
} else if inst.Type() == instancetype.Container {
+ ct := inst.(*containerLXC)
+
// Now create the empty storage.
- err = inst.Storage().ContainerCreate(inst)
+ err = ct.Storage().ContainerCreate(inst)
if err != nil {
return nil, err
}
@@ -436,15 +439,21 @@ func containerCreateFromBackup(s *state.State, info backup.Info, data io.ReadSee
return pool, nil
}
-func containerCreateEmptySnapshot(s *state.State, args db.InstanceArgs) (Instance, error) {
+func containerCreateEmptySnapshot(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
// Create the snapshot
c, err := instanceCreateInternal(s, args)
if err != nil {
return nil, err
}
+ if c.Type() != instancetype.Container {
+ return nil, fmt.Errorf("Instance type must be container")
+ }
+
+ ct := c.(*containerLXC)
+
// Now create the empty snapshot
- err = c.Storage().ContainerSnapshotCreateEmpty(c)
+ err = ct.Storage().ContainerSnapshotCreateEmpty(c)
if err != nil {
c.Delete()
return nil, err
@@ -454,7 +463,7 @@ func containerCreateEmptySnapshot(s *state.State, args db.InstanceArgs) (Instanc
}
// instanceCreateFromImage creates an instance from a rootfs image.
-func instanceCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *operations.Operation) (Instance, error) {
+func instanceCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *operations.Operation) (instance.Instance, error) {
s := d.State()
// Get the image properties.
@@ -552,7 +561,8 @@ func instanceCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *o
}
// Now create the storage from an image.
- err = inst.Storage().ContainerCreateFromImage(inst, hash, tracker)
+ ct := inst.(*containerLXC)
+ err = ct.Storage().ContainerCreateFromImage(inst, hash, tracker)
if err != nil {
return nil, errors.Wrap(err, "Create instance from image")
}
@@ -570,8 +580,8 @@ func instanceCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *o
return inst, nil
}
-func instanceCreateAsCopy(s *state.State, args db.InstanceArgs, sourceInst Instance, instanceOnly bool, refresh bool) (Instance, error) {
- var inst, revertInst Instance
+func instanceCreateAsCopy(s *state.State, args db.InstanceArgs, sourceInst instance.Instance, instanceOnly bool, refresh bool) (instance.Instance, error) {
+ var inst, revertInst instance.Instance
var err error
defer func() {
@@ -613,8 +623,8 @@ func instanceCreateAsCopy(s *state.State, args db.InstanceArgs, sourceInst Insta
parentStoragePool = parentLocalRootDiskDevice["pool"]
}
- snapList := []*Instance{}
- var snapshots []Instance
+ snapList := []*instance.Instance{}
+ var snapshots []instance.Instance
if !instanceOnly {
if refresh {
@@ -695,13 +705,19 @@ func instanceCreateAsCopy(s *state.State, args db.InstanceArgs, sourceInst Insta
}
// Now clone or refresh the storage.
+ if inst.Type() != instancetype.Container {
+ return nil, fmt.Errorf("Instance type must be container")
+ }
+
+ ct := inst.(*containerLXC)
+
if refresh {
- err = inst.Storage().ContainerRefresh(inst, sourceInst, snapshots)
+ err = ct.Storage().ContainerRefresh(inst, sourceInst, snapshots)
if err != nil {
return nil, err
}
} else {
- err = inst.Storage().ContainerCopy(inst, sourceInst, instanceOnly)
+ err = ct.Storage().ContainerCopy(inst, sourceInst, instanceOnly)
if err != nil {
return nil, err
}
@@ -727,7 +743,7 @@ func instanceCreateAsCopy(s *state.State, args db.InstanceArgs, sourceInst Insta
return inst, nil
}
-func containerCreateAsSnapshot(s *state.State, args db.InstanceArgs, sourceInstance Instance) (Instance, error) {
+func containerCreateAsSnapshot(s *state.State, args db.InstanceArgs, sourceInstance instance.Instance) (instance.Instance, error) {
if sourceInstance.Type() != instancetype.Container {
return nil, fmt.Errorf("Instance not container type")
}
@@ -784,7 +800,13 @@ func containerCreateAsSnapshot(s *state.State, args db.InstanceArgs, sourceInsta
}
// Clone the container
- err = sourceInstance.Storage().ContainerSnapshotCreate(c, sourceInstance)
+ if sourceInstance.Type() != instancetype.Container {
+ return nil, fmt.Errorf("Instance type must be container")
+ }
+
+ ct := sourceInstance.(*containerLXC)
+
+ err = ct.Storage().ContainerSnapshotCreate(c, sourceInstance)
if err != nil {
c.Delete()
return nil, err
@@ -821,7 +843,7 @@ func containerCreateAsSnapshot(s *state.State, args db.InstanceArgs, sourceInsta
}
// instanceCreateInternal creates an instance record and storage volume record in the database.
-func instanceCreateInternal(s *state.State, args db.InstanceArgs) (Instance, error) {
+func instanceCreateInternal(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
// Set default values.
if args.Project == "" {
args.Project = "default"
@@ -1022,7 +1044,7 @@ func instanceCreateInternal(s *state.State, args db.InstanceArgs) (Instance, err
args = db.ContainerToArgs(&dbInst)
- var inst Instance
+ var inst instance.Instance
if args.Type == instancetype.Container {
inst, err = containerLXCCreate(s, args)
@@ -1041,7 +1063,7 @@ func instanceCreateInternal(s *state.State, args db.InstanceArgs) (Instance, err
}
// instanceConfigureInternal applies quota set in volatile "apply_quota" and writes a backup file.
-func instanceConfigureInternal(state *state.State, c Instance) error {
+func instanceConfigureInternal(state *state.State, c instance.Instance) error {
// Find the root device
rootDiskDeviceKey, rootDiskDevice, err := shared.GetRootDiskDevice(c.ExpandedDevices().CloneNative())
if err != nil {
@@ -1074,8 +1096,10 @@ func instanceConfigureInternal(state *state.State, c Instance) error {
return err
}
+ ct := c.(*containerLXC)
+
// handle quota: at this point, storage is guaranteed to be ready
- storage := c.Storage()
+ storage := ct.Storage()
if rootDiskDevice["size"] != "" {
storageTypeName := storage.GetStorageTypeName()
if (storageTypeName == "lvm" || storageTypeName == "ceph") && c.IsRunning() {
@@ -1111,7 +1135,7 @@ func instanceConfigureInternal(state *state.State, c Instance) error {
return nil
}
-func instanceLoadById(s *state.State, id int) (Instance, error) {
+func instanceLoadById(s *state.State, id int) (instance.Instance, error) {
// Get the DB record
project, name, err := s.Cluster.ContainerProjectAndName(id)
if err != nil {
@@ -1121,7 +1145,7 @@ func instanceLoadById(s *state.State, id int) (Instance, error) {
return instanceLoadByProjectAndName(s, project, name)
}
-func instanceLoadByProjectAndName(s *state.State, project, name string) (Instance, error) {
+func instanceLoadByProjectAndName(s *state.State, project, name string) (instance.Instance, error) {
// Get the DB record
var container *db.Instance
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1166,7 +1190,7 @@ func instanceLoadByProjectAndName(s *state.State, project, name string) (Instanc
return inst, nil
}
-func instanceLoadByProject(s *state.State, project string) ([]Instance, error) {
+func instanceLoadByProject(s *state.State, project string) ([]instance.Instance, error) {
// Get all the containers
var cts []db.Instance
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1190,7 +1214,7 @@ func instanceLoadByProject(s *state.State, project string) ([]Instance, error) {
}
// Load all instances across all projects.
-func instanceLoadFromAllProjects(s *state.State) ([]Instance, error) {
+func instanceLoadFromAllProjects(s *state.State) ([]instance.Instance, error) {
var projects []string
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1202,7 +1226,7 @@ func instanceLoadFromAllProjects(s *state.State) ([]Instance, error) {
return nil, err
}
- instances := []Instance{}
+ instances := []instance.Instance{}
for _, project := range projects {
projectInstances, err := instanceLoadByProject(s, project)
if err != nil {
@@ -1215,12 +1239,12 @@ func instanceLoadFromAllProjects(s *state.State) ([]Instance, error) {
}
// Legacy interface.
-func instanceLoadAll(s *state.State) ([]Instance, error) {
+func instanceLoadAll(s *state.State) ([]instance.Instance, error) {
return instanceLoadByProject(s, "default")
}
// Load all instances of this nodes.
-func instanceLoadNodeAll(s *state.State) ([]Instance, error) {
+func instanceLoadNodeAll(s *state.State) ([]instance.Instance, error) {
// Get all the container arguments
var cts []db.Instance
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1240,7 +1264,7 @@ func instanceLoadNodeAll(s *state.State) ([]Instance, error) {
}
// Load all instances of this nodes under the given project.
-func instanceLoadNodeProjectAll(s *state.State, project string, instanceType instancetype.Type) ([]Instance, error) {
+func instanceLoadNodeProjectAll(s *state.State, project string, instanceType instancetype.Type) ([]instance.Instance, error) {
// Get all the container arguments
var cts []db.Instance
err := s.Cluster.Transaction(func(tx *db.ClusterTx) error {
@@ -1259,7 +1283,7 @@ func instanceLoadNodeProjectAll(s *state.State, project string, instanceType ins
return instanceLoadAllInternal(cts, s)
}
-func instanceLoadAllInternal(dbInstances []db.Instance, s *state.State) ([]Instance, error) {
+func instanceLoadAllInternal(dbInstances []db.Instance, s *state.State) ([]instance.Instance, error) {
// Figure out what profiles are in use
profiles := map[string]map[string]api.Profile{}
for _, instArgs := range dbInstances {
@@ -1289,7 +1313,7 @@ func instanceLoadAllInternal(dbInstances []db.Instance, s *state.State) ([]Insta
}
// Load the instances structs
- instances := []Instance{}
+ instances := []instance.Instance{}
for _, dbInstance := range dbInstances {
// Figure out the instances's profiles
cProfiles := []api.Profile{}
@@ -1310,8 +1334,8 @@ func instanceLoadAllInternal(dbInstances []db.Instance, s *state.State) ([]Insta
}
// 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, error) {
- var inst 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 {
@@ -1333,7 +1357,7 @@ func instanceLoad(s *state.State, args db.InstanceArgs, profiles []api.Profile)
// snapshots to remove from the target. A snapshot will be marked as "to sync" if it either doesn't
// exist in the target or its creation date is different to the source. A snapshot will be marked
// as "to delete" if it doesn't exist in the source or creation date is different to the source.
-func instanceCompareSnapshots(source Instance, target Instance) ([]Instance, []Instance, error) {
+func instanceCompareSnapshots(source instance.Instance, target instance.Instance) ([]instance.Instance, []instance.Instance, error) {
// Get the source snapshots.
sourceSnapshots, err := source.Snapshots()
if err != nil {
@@ -1350,8 +1374,8 @@ func instanceCompareSnapshots(source Instance, target Instance) ([]Instance, []I
sourceSnapshotsTime := map[string]time.Time{}
targetSnapshotsTime := map[string]time.Time{}
- toDelete := []Instance{}
- toSync := []Instance{}
+ toDelete := []instance.Instance{}
+ toSync := []instance.Instance{}
// Generate a list of source snapshot creation dates.
for _, snap := range sourceSnapshots {
@@ -1402,7 +1426,7 @@ func autoCreateContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
}
// Figure out which need snapshotting (if any)
- instances := []Instance{}
+ instances := []instance.Instance{}
for _, c := range allContainers {
schedule := c.ExpandedConfig()["snapshots.schedule"]
@@ -1483,7 +1507,7 @@ func autoCreateContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
return f, schedule
}
-func autoCreateContainerSnapshots(ctx context.Context, d *Daemon, instances []Instance) error {
+func autoCreateContainerSnapshots(ctx context.Context, d *Daemon, instances []instance.Instance) error {
// Make the snapshots
for _, c := range instances {
ch := make(chan error)
@@ -1545,7 +1569,7 @@ func pruneExpiredContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
}
// Figure out which need snapshotting (if any)
- expiredSnapshots := []Instance{}
+ expiredSnapshots := []instance.Instance{}
for _, c := range allInstances {
snapshots, err := c.Snapshots()
if err != nil {
@@ -1604,7 +1628,7 @@ func pruneExpiredContainerSnapshotsTask(d *Daemon) (task.Func, task.Schedule) {
return f, schedule
}
-func pruneExpiredContainerSnapshots(ctx context.Context, d *Daemon, snapshots []Instance) error {
+func pruneExpiredContainerSnapshots(ctx context.Context, d *Daemon, snapshots []instance.Instance) error {
// Find snapshots to delete
for _, snapshot := range snapshots {
err := snapshot.Delete()
@@ -1616,7 +1640,7 @@ func pruneExpiredContainerSnapshots(ctx context.Context, d *Daemon, snapshots []
return nil
}
-func containerDetermineNextSnapshotName(d *Daemon, c Instance, defaultPattern string) (string, error) {
+func containerDetermineNextSnapshotName(d *Daemon, c instance.Instance, defaultPattern string) (string, error) {
var err error
pattern := c.ExpandedConfig()["snapshots.pattern"]
diff --git a/lxd/container_console.go b/lxd/container_console.go
index 4c009e5961..3ac9fd45e0 100644
--- a/lxd/container_console.go
+++ b/lxd/container_console.go
@@ -16,6 +16,7 @@ import (
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/response"
@@ -28,7 +29,7 @@ import (
type consoleWs struct {
// instance currently worked on
- instance Instance
+ instance instance.Instance
// websocket connections to bridge pty fds to
conns map[int]*websocket.Conn
diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index fb1fa90972..de7e6ded6d 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -31,7 +31,7 @@ import (
type execWs struct {
command []string
- instance Instance
+ instance instance.Instance
env map[string]string
rootUid int64
diff --git a/lxd/container_file.go b/lxd/container_file.go
index ce87766ed7..ce8fcac1b6 100644
--- a/lxd/container_file.go
+++ b/lxd/container_file.go
@@ -10,6 +10,7 @@ import (
"github.com/gorilla/mux"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/response"
"github.com/lxc/lxd/shared"
)
@@ -53,7 +54,7 @@ func containerFileHandler(d *Daemon, r *http.Request) response.Response {
}
}
-func containerFileGet(c Instance, path string, r *http.Request) response.Response {
+func containerFileGet(c instance.Instance, path string, r *http.Request) response.Response {
/*
* Copy out of the ns to a temporary file, and then use that to serve
* the request from. This prevents us from having to worry about stuff
@@ -98,7 +99,7 @@ func containerFileGet(c Instance, path string, r *http.Request) response.Respons
}
}
-func containerFilePost(c Instance, path string, r *http.Request) response.Response {
+func containerFilePost(c instance.Instance, path string, r *http.Request) response.Response {
// Extract file ownership and mode from headers
uid, gid, mode, type_, write := shared.ParseLXDFileHeaders(r.Header)
@@ -151,7 +152,7 @@ func containerFilePost(c Instance, path string, r *http.Request) response.Respon
}
}
-func containerFileDelete(c Instance, path string, r *http.Request) response.Response {
+func containerFileDelete(c instance.Instance, path string, r *http.Request) response.Response {
err := c.FileRemove(path)
if err != nil {
return response.SmartError(err)
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index 9cd60ca5ae..fac2ecc7e9 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -3260,11 +3260,11 @@ func (c *containerLXC) RenderState() (*api.InstanceState, error) {
return &status, nil
}
-func (c *containerLXC) Snapshots() ([]Instance, error) {
+func (c *containerLXC) Snapshots() ([]instance.Instance, error) {
var snaps []db.Instance
if c.IsSnapshot() {
- return []Instance{}, nil
+ return []instance.Instance{}, nil
}
// Get all the snapshots
@@ -3287,9 +3287,9 @@ func (c *containerLXC) Snapshots() ([]Instance, error) {
return nil, err
}
- instances := make([]Instance, len(containers))
+ instances := make([]instance.Instance, len(containers))
for k, v := range containers {
- instances[k] = Instance(v)
+ instances[k] = instance.Instance(v)
}
return instances, nil
@@ -3316,7 +3316,7 @@ func (c *containerLXC) Backups() ([]backup.Backup, error) {
return backups, nil
}
-func (c *containerLXC) Restore(sourceContainer Instance, stateful bool) error {
+func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool) error {
var ctxMap log.Ctx
// Initialize storage interface for the container.
@@ -4015,7 +4015,7 @@ type backupFile struct {
Volume *api.StorageVolume `yaml:"volume"`
}
-func writeBackupFile(c Instance) error {
+func writeBackupFile(c instance.Instance) error {
// We only write backup files out for actual containers
if c.IsSnapshot() {
return nil
diff --git a/lxd/container_metadata.go b/lxd/container_metadata.go
index 0f6ecf828c..35d0aac470 100644
--- a/lxd/container_metadata.go
+++ b/lxd/container_metadata.go
@@ -13,6 +13,7 @@ import (
"github.com/gorilla/mux"
"gopkg.in/yaml.v2"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/response"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
@@ -358,7 +359,7 @@ func containerMetadataTemplatesDelete(d *Daemon, r *http.Request) response.Respo
}
// Return the full path of a container template.
-func getContainerTemplatePath(c Instance, filename string) (string, error) {
+func getContainerTemplatePath(c instance.Instance, filename string) (string, error) {
if strings.Contains(filename, "/") {
return "", fmt.Errorf("Invalid template filename")
}
diff --git a/lxd/container_post.go b/lxd/container_post.go
index 3371b332b9..65010b9338 100644
--- a/lxd/container_post.go
+++ b/lxd/container_post.go
@@ -14,6 +14,7 @@ import (
lxd "github.com/lxc/lxd/client"
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/response"
@@ -104,7 +105,7 @@ func containerPost(d *Daemon, r *http.Request) response.Response {
return response.BadRequest(fmt.Errorf("Target node is offline"))
}
- var inst Instance
+ var inst instance.Instance
// Check whether to forward the request to the node that is running the
// container. Here are the possible cases:
@@ -265,7 +266,7 @@ func containerPost(d *Daemon, r *http.Request) response.Response {
}
// Move a non-ceph container to another cluster node.
-func containerPostClusteringMigrate(d *Daemon, c Instance, oldName, newName, newNode string) response.Response {
+func containerPostClusteringMigrate(d *Daemon, c instance.Instance, oldName, newName, newNode string) response.Response {
cert := d.endpoints.NetworkCert()
var sourceAddress string
@@ -408,7 +409,7 @@ func containerPostClusteringMigrate(d *Daemon, c Instance, oldName, newName, new
}
// Special case migrating a container backed by ceph across two cluster nodes.
-func containerPostClusteringMigrateWithCeph(d *Daemon, c Instance, project, oldName, newName, newNode string, instanceType instancetype.Type) response.Response {
+func containerPostClusteringMigrateWithCeph(d *Daemon, c instance.Instance, project, oldName, newName, newNode string, instanceType instancetype.Type) response.Response {
run := func(*operations.Operation) error {
// If source node is online (i.e. we're serving the request on
// it, and c != nil), let's unmap the RBD volume locally
diff --git a/lxd/containers.go b/lxd/containers.go
index d98e4e6f47..a3a0b1f86f 100644
--- a/lxd/containers.go
+++ b/lxd/containers.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/logger"
@@ -180,7 +181,7 @@ var instanceBackupExportCmd = APIEndpoint{
Get: APIEndpointAction{Handler: containerBackupExportGet, AccessHandler: AllowProjectPermission("containers", "view")},
}
-type containerAutostartList []Instance
+type containerAutostartList []instance.Instance
func (slice containerAutostartList) Len() int {
return len(slice)
@@ -210,7 +211,7 @@ func containersRestart(s *state.State) error {
return err
}
- instances := []Instance{}
+ instances := []instance.Instance{}
for _, c := range result {
instances = append(instances, c)
@@ -246,7 +247,7 @@ func containersRestart(s *state.State) error {
return nil
}
-type containerStopList []Instance
+type containerStopList []instance.Instance
func (slice containerStopList) Len() int {
return len(slice)
@@ -307,7 +308,7 @@ func containersShutdown(s *state.State) error {
if err != nil {
// Mark database as offline
dbAvailable = false
- instances = []Instance{}
+ instances = []instance.Instance{}
// List all containers on disk
cnames, err := containersOnDisk()
@@ -374,7 +375,7 @@ func containersShutdown(s *state.State) error {
// Stop the instance
wg.Add(1)
- go func(c Instance, lastState string) {
+ go func(c instance.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 3e4dc3d2bb..5fe0015cf3 100644
--- a/lxd/containers_get.go
+++ b/lxd/containers_get.go
@@ -15,6 +15,7 @@ import (
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/db/query"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/response"
"github.com/lxc/lxd/shared"
@@ -107,7 +108,7 @@ func doContainersGet(d *Daemon, r *http.Request) (interface{}, error) {
}
// Get the local instances
- nodeCts := map[string]Instance{}
+ nodeCts := map[string]instance.Instance{}
if recursion > 0 {
cts, err := instanceLoadNodeProjectAll(d.State(), project, instanceType)
if err != nil {
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index dacc135db2..8c89892a15 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -21,6 +21,7 @@ import (
"github.com/lxc/lxd/lxd/cluster"
"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/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -207,7 +208,7 @@ func createFromMigration(d *Daemon, project string, req *api.InstancesPost) resp
return response.NotImplemented(fmt.Errorf("Mode '%s' not implemented", req.Source.Mode))
}
- var c Instance
+ var c instance.Instance
// Parse the architecture name
architecture, err := osarch.ArchitectureId(req.Architecture)
@@ -894,7 +895,7 @@ func containerFindStoragePool(d *Daemon, project string, req *api.InstancesPost)
return storagePool, storagePoolProfile, localRootDiskDeviceKey, localRootDiskDevice, nil
}
-func clusterCopyContainerInternal(d *Daemon, source Instance, project string, req *api.InstancesPost) response.Response {
+func clusterCopyContainerInternal(d *Daemon, source instance.Instance, project string, req *api.InstancesPost) response.Response {
name := req.Source.Source
// Locate the source of the container
diff --git a/lxd/devices.go b/lxd/devices.go
index 6b161e21fd..5939a0c494 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -16,11 +16,11 @@ import (
"github.com/lxc/lxd/lxd/cgroup"
"github.com/lxc/lxd/lxd/device"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
- "github.com/lxc/lxd/shared/logger"
-
log "github.com/lxc/lxd/shared/log15"
+ "github.com/lxc/lxd/shared/logger"
)
type deviceTaskCPU struct {
@@ -299,8 +299,8 @@ func deviceTaskBalance(s *state.State) {
return
}
- fixedInstances := map[int][]Instance{}
- balancedInstances := map[Instance]int{}
+ fixedInstances := map[int][]instance.Instance{}
+ balancedInstances := map[instance.Instance]int{}
for _, c := range instances {
conf := c.ExpandedConfig()
cpulimit, ok := conf["limits.cpu"]
@@ -332,14 +332,14 @@ func deviceTaskBalance(s *state.State) {
if ok {
fixedInstances[nr] = append(fixedInstances[nr], c)
} else {
- fixedInstances[nr] = []Instance{c}
+ fixedInstances[nr] = []instance.Instance{c}
}
}
}
}
// Balance things
- pinning := map[Instance][]string{}
+ pinning := map[instance.Instance][]string{}
usage := map[int]deviceTaskCPU{}
for _, id := range cpus {
diff --git a/lxd/migrate.go b/lxd/migrate.go
index b51e712bdf..bf0a0ea11e 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -18,6 +18,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/shared"
@@ -39,7 +40,7 @@ type migrationFields struct {
// container specific fields
live bool
instanceOnly bool
- instance Instance
+ instance instance.Instance
// storage specific fields
storage storage
@@ -264,7 +265,7 @@ type MigrationSinkArgs struct {
Url string
// Instance specific fields
- Instance Instance
+ Instance instance.Instance
InstanceOnly bool
Idmap *idmap.IdmapSet
Live bool
@@ -281,7 +282,7 @@ type MigrationSinkArgs struct {
type MigrationSourceArgs struct {
// Instance specific fields
- Instance Instance
+ Instance instance.Instance
InstanceOnly bool
// Transport specific fields
diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index fda13de567..c36df95fee 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -16,6 +16,7 @@ import (
"gopkg.in/lxc/go-lxc.v2"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -27,7 +28,7 @@ import (
"github.com/lxc/lxd/shared/logger"
)
-func NewMigrationSource(inst Instance, stateful bool, instanceOnly bool) (*migrationSourceWs, error) {
+func NewMigrationSource(inst instance.Instance, stateful bool, instanceOnly bool) (*migrationSourceWs, error) {
ret := migrationSourceWs{migrationFields{instance: inst}, make(chan bool, 1)}
ret.instanceOnly = instanceOnly
@@ -80,7 +81,7 @@ fi
return err
}
-func snapshotToProtobuf(c Instance) *migration.Snapshot {
+func snapshotToProtobuf(c instance.Instance) *migration.Snapshot {
config := []*migration.Config{}
for k, v := range c.LocalConfig() {
kCopy := string(k)
@@ -400,7 +401,13 @@ func (s *migrationSourceWs) Do(migrateOp *operations.Operation) error {
// The protocol says we have to send a header no matter what, so let's
// do that, but then immediately send an error.
- myType := s.instance.Storage().MigrationType()
+ if s.instance.Type() != instancetype.Container {
+ return fmt.Errorf("Instance type must be container")
+ }
+
+ ct := s.instance.(*containerLXC)
+
+ myType := ct.Storage().MigrationType()
hasFeature := true
header := migration.MigrationHeader{
Fs: &myType,
@@ -455,7 +462,7 @@ func (s *migrationSourceWs) Do(migrateOp *operations.Operation) error {
}
// Initialize storage driver
- driver, fsErr := s.instance.Storage().MigrationSource(sourceArgs)
+ driver, fsErr := ct.Storage().MigrationSource(sourceArgs)
if fsErr != nil {
s.sendControl(fsErr)
return fsErr
@@ -473,7 +480,7 @@ func (s *migrationSourceWs) Do(migrateOp *operations.Operation) error {
}
// Check if this storage pool has a rate limit set for rsync.
- poolwritable := s.instance.Storage().GetStoragePoolWritable()
+ poolwritable := ct.Storage().GetStoragePoolWritable()
if poolwritable.Config != nil {
bwlimit = poolwritable.Config["rsync.bwlimit"]
}
@@ -780,10 +787,10 @@ func NewMigrationSink(args *MigrationSinkArgs) (*migrationSink, error) {
func (c *migrationSink) Do(migrateOp *operations.Operation) error {
if c.src.instance.Type() != instancetype.Container {
- return fmt.Errorf("Instance not container type")
+ return fmt.Errorf("Instance type must be container")
}
- ct := c.src.instance.(container)
+ ct := c.src.instance.(*containerLXC)
var err error
@@ -858,12 +865,12 @@ func (c *migrationSink) Do(migrateOp *operations.Operation) error {
}
}
- mySink := c.src.instance.Storage().MigrationSink
+ mySink := ct.Storage().MigrationSink
if c.refresh {
mySink = rsyncMigrationSink
}
- myType := c.src.instance.Storage().MigrationType()
+ myType := ct.Storage().MigrationType()
resp := migration.MigrationHeader{
Fs: &myType,
Criu: criuType,
@@ -1166,12 +1173,12 @@ func (s *migrationSourceWs) ConnectContainerTarget(target api.InstancePostTarget
return s.ConnectTarget(target.Certificate, target.Operation, target.Websockets)
}
-func migrationCompareSnapshots(sourceSnapshots []*migration.Snapshot, targetSnapshots []Instance) ([]*migration.Snapshot, []Instance) {
+func migrationCompareSnapshots(sourceSnapshots []*migration.Snapshot, targetSnapshots []instance.Instance) ([]*migration.Snapshot, []instance.Instance) {
// Compare source and target
sourceSnapshotsTime := map[string]int64{}
targetSnapshotsTime := map[string]int64{}
- toDelete := []Instance{}
+ toDelete := []instance.Instance{}
toSync := []*migration.Snapshot{}
for _, snap := range sourceSnapshots {
diff --git a/lxd/networks_utils.go b/lxd/networks_utils.go
index 05334b00c7..aa90ca415e 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/instance/instancetype"
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/state"
@@ -90,7 +91,7 @@ func networkGetInterfaces(cluster *db.Cluster) ([]string, error) {
return networks, nil
}
-func networkIsInUse(c Instance, name string) bool {
+func networkIsInUse(c instance.Instance, name string) bool {
for _, d := range c.ExpandedDevices() {
if d["type"] != "nic" {
continue
diff --git a/lxd/storage.go b/lxd/storage.go
index 138f7d144f..4fca279fca 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -14,6 +14,7 @@ import (
"github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -193,32 +194,32 @@ type storage interface {
// Functions dealing with container storage volumes.
// ContainerCreate creates an empty container (no rootfs/metadata.yaml)
- ContainerCreate(container Instance) error
+ ContainerCreate(container instance.Instance) error
// ContainerCreateFromImage creates a container from a image.
- ContainerCreateFromImage(c Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error
- ContainerDelete(c Instance) error
- ContainerCopy(target Instance, source Instance, containerOnly bool) error
- ContainerRefresh(target Instance, source Instance, snapshots []Instance) error
- ContainerMount(c Instance) (bool, error)
- ContainerUmount(c Instance, path string) (bool, error)
- ContainerRename(container Instance, newName string) error
- ContainerRestore(container Instance, sourceContainer Instance) error
- ContainerGetUsage(container Instance) (int64, error)
+ ContainerCreateFromImage(c instance.Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error
+ ContainerDelete(c instance.Instance) error
+ ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error
+ ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error
+ ContainerMount(c instance.Instance) (bool, error)
+ ContainerUmount(c instance.Instance, path string) (bool, error)
+ ContainerRename(container instance.Instance, newName string) error
+ ContainerRestore(container instance.Instance, sourceContainer instance.Instance) error
+ ContainerGetUsage(container instance.Instance) (int64, error)
GetContainerPoolInfo() (int64, string, string)
- ContainerStorageReady(container Instance) bool
+ ContainerStorageReady(container instance.Instance) bool
- ContainerSnapshotCreate(target Instance, source Instance) error
- ContainerSnapshotDelete(c Instance) error
- ContainerSnapshotRename(c Instance, newName string) error
- ContainerSnapshotStart(c Instance) (bool, error)
- ContainerSnapshotStop(c Instance) (bool, error)
+ ContainerSnapshotCreate(target instance.Instance, source instance.Instance) error
+ ContainerSnapshotDelete(c instance.Instance) error
+ ContainerSnapshotRename(c instance.Instance, newName string) error
+ ContainerSnapshotStart(c instance.Instance) (bool, error)
+ ContainerSnapshotStop(c instance.Instance) (bool, error)
- ContainerBackupCreate(path string, backup backup.Backup, sourceContainer Instance) error
+ ContainerBackupCreate(path string, backup backup.Backup, sourceContainer instance.Instance) error
ContainerBackupLoad(info backup.Info, data io.ReadSeeker, tarArgs []string) error
// For use in migrating snapshots.
- ContainerSnapshotCreateEmpty(c Instance) error
+ ContainerSnapshotCreateEmpty(c instance.Instance) error
// Functions dealing with image storage volumes.
ImageCreate(fingerprint string, tracker *ioprogress.ProgressTracker) error
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 99ef097b09..c598d76d89 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -17,6 +17,8 @@ import (
"golang.org/x/sys/unix"
"github.com/lxc/lxd/lxd/backup"
+ "github.com/lxc/lxd/lxd/instance"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -803,7 +805,7 @@ func (s *storageBtrfs) StoragePoolVolumeRename(newName string) error {
}
// Functions dealing with container storage.
-func (s *storageBtrfs) ContainerStorageReady(container Instance) bool {
+func (s *storageBtrfs) ContainerStorageReady(container instance.Instance) bool {
containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
return isBtrfsSubVolume(containerMntPoint)
}
@@ -848,7 +850,7 @@ func (s *storageBtrfs) doContainerCreate(projectName, name string, privileged bo
return nil
}
-func (s *storageBtrfs) ContainerCreate(container Instance) error {
+func (s *storageBtrfs) ContainerCreate(container instance.Instance) error {
err := s.doContainerCreate(container.Project(), container.Name(), container.IsPrivileged())
if err != nil {
return err
@@ -858,7 +860,7 @@ func (s *storageBtrfs) ContainerCreate(container Instance) error {
}
// And this function is why I started hating on btrfs...
-func (s *storageBtrfs) ContainerCreateFromImage(container Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
+func (s *storageBtrfs) ContainerCreateFromImage(container instance.Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
logger.Debugf("Creating BTRFS storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
source := s.pool.Config["source"]
@@ -941,7 +943,7 @@ func (s *storageBtrfs) ContainerCreateFromImage(container Instance, fingerprint
return nil
}
-func (s *storageBtrfs) ContainerDelete(container Instance) error {
+func (s *storageBtrfs) ContainerDelete(container instance.Instance) error {
logger.Debugf("Deleting BTRFS storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
// The storage pool needs to be mounted.
@@ -988,7 +990,7 @@ func (s *storageBtrfs) ContainerDelete(container Instance) error {
return nil
}
-func (s *storageBtrfs) copyContainer(target Instance, source Instance) error {
+func (s *storageBtrfs) copyContainer(target instance.Instance, source instance.Instance) error {
sourceContainerSubvolumeName := driver.GetContainerMountPoint(source.Project(), s.pool.Name, source.Name())
if source.IsSnapshot() {
sourceContainerSubvolumeName = driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, source.Name())
@@ -1022,7 +1024,7 @@ func (s *storageBtrfs) copyContainer(target Instance, source Instance) error {
return nil
}
-func (s *storageBtrfs) copySnapshot(target Instance, source Instance) error {
+func (s *storageBtrfs) copySnapshot(target instance.Instance, source instance.Instance) error {
sourceName := source.Name()
targetName := target.Name()
sourceContainerSubvolumeName := driver.GetSnapshotMountPoint(source.Project(), s.pool.Name, sourceName)
@@ -1053,7 +1055,7 @@ func (s *storageBtrfs) copySnapshot(target Instance, source Instance) error {
return nil
}
-func (s *storageBtrfs) doCrossPoolContainerCopy(target Instance, source Instance, containerOnly bool, refresh bool, refreshSnapshots []Instance) error {
+func (s *storageBtrfs) doCrossPoolContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool, refresh bool, refreshSnapshots []instance.Instance) error {
sourcePool, err := source.StoragePool()
if err != nil {
return err
@@ -1078,7 +1080,7 @@ func (s *storageBtrfs) doCrossPoolContainerCopy(target Instance, source Instance
return err
}
- var snapshots []Instance
+ var snapshots []instance.Instance
if refresh {
snapshots = refreshSnapshots
@@ -1125,7 +1127,7 @@ func (s *storageBtrfs) doCrossPoolContainerCopy(target Instance, source Instance
return nil
}
-func (s *storageBtrfs) ContainerCopy(target Instance, source Instance, containerOnly bool) error {
+func (s *storageBtrfs) ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error {
logger.Debugf("Copying BTRFS container storage %s to %s", source.Name(), target.Name())
// The storage pool needs to be mounted.
@@ -1142,8 +1144,19 @@ func (s *storageBtrfs) ContainerCopy(target Instance, source Instance, container
defer source.StorageStop()
}
- _, sourcePool, _ := source.Storage().GetContainerPoolInfo()
- _, targetPool, _ := target.Storage().GetContainerPoolInfo()
+ if target.Type() != instancetype.Container {
+ return fmt.Errorf("Target Instance type must be container")
+ }
+
+ if source.Type() != instancetype.Container {
+ return fmt.Errorf("Source Instance type must be container")
+ }
+
+ targetCt := target.(*containerLXC)
+ srcCt := source.(*containerLXC)
+
+ _, sourcePool, _ := srcCt.Storage().GetContainerPoolInfo()
+ _, targetPool, _ := targetCt.Storage().GetContainerPoolInfo()
if sourcePool != targetPool {
return s.doCrossPoolContainerCopy(target, source, containerOnly, false, nil)
}
@@ -1191,7 +1204,7 @@ func (s *storageBtrfs) ContainerCopy(target Instance, source Instance, container
return nil
}
-func (s *storageBtrfs) ContainerRefresh(target Instance, source Instance, snapshots []Instance) error {
+func (s *storageBtrfs) ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error {
logger.Debugf("Refreshing BTRFS container storage for %s from %s", target.Name(), source.Name())
// The storage pool needs to be mounted.
@@ -1211,7 +1224,7 @@ func (s *storageBtrfs) ContainerRefresh(target Instance, source Instance, snapsh
return s.doCrossPoolContainerCopy(target, source, len(snapshots) == 0, true, snapshots)
}
-func (s *storageBtrfs) ContainerMount(c Instance) (bool, error) {
+func (s *storageBtrfs) ContainerMount(c instance.Instance) (bool, error) {
logger.Debugf("Mounting BTRFS storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
// The storage pool must be mounted.
@@ -1224,11 +1237,11 @@ func (s *storageBtrfs) ContainerMount(c Instance) (bool, error) {
return true, nil
}
-func (s *storageBtrfs) ContainerUmount(c Instance, path string) (bool, error) {
+func (s *storageBtrfs) ContainerUmount(c instance.Instance, path string) (bool, error) {
return true, nil
}
-func (s *storageBtrfs) ContainerRename(container Instance, newName string) error {
+func (s *storageBtrfs) ContainerRename(container instance.Instance, newName string) error {
logger.Debugf("Renaming BTRFS storage volume for container \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newName)
// The storage pool must be mounted.
@@ -1277,7 +1290,7 @@ func (s *storageBtrfs) ContainerRename(container Instance, newName string) error
return nil
}
-func (s *storageBtrfs) ContainerRestore(container Instance, sourceContainer Instance) error {
+func (s *storageBtrfs) ContainerRestore(container instance.Instance, sourceContainer instance.Instance) error {
logger.Debugf("Restoring BTRFS storage volume for container \"%s\" from %s to %s", s.volume.Name, sourceContainer.Name(), container.Name())
// The storage pool must be mounted.
@@ -1309,7 +1322,13 @@ func (s *storageBtrfs) ContainerRestore(container Instance, sourceContainer Inst
}
// Mount the source container.
- srcContainerStorage := sourceContainer.Storage()
+ if sourceContainer.Type() != instancetype.Container {
+ return fmt.Errorf("Instance type must be container")
+ }
+
+ ct := sourceContainer.(*containerLXC)
+
+ srcContainerStorage := ct.Storage()
_, sourcePool, _ := srcContainerStorage.GetContainerPoolInfo()
sourceContainerSubvolumeName := ""
if sourceContainer.IsSnapshot() {
@@ -1362,7 +1381,7 @@ func (s *storageBtrfs) ContainerRestore(container Instance, sourceContainer Inst
return failure
}
-func (s *storageBtrfs) ContainerGetUsage(container Instance) (int64, error) {
+func (s *storageBtrfs) ContainerGetUsage(container instance.Instance) (int64, error) {
return s.btrfsPoolVolumeQGroupUsage(container.Path())
}
@@ -1415,7 +1434,7 @@ func (s *storageBtrfs) doContainerSnapshotCreate(projectName string, targetName
return nil
}
-func (s *storageBtrfs) ContainerSnapshotCreate(snapshotContainer Instance, sourceContainer Instance) error {
+func (s *storageBtrfs) ContainerSnapshotCreate(snapshotContainer instance.Instance, sourceContainer instance.Instance) error {
err := s.doContainerSnapshotCreate(sourceContainer.Project(), snapshotContainer.Name(), sourceContainer.Name())
if err != nil {
s.ContainerSnapshotDelete(snapshotContainer)
@@ -1454,7 +1473,7 @@ func btrfsSnapshotDeleteInternal(projectName, poolName string, snapshotName stri
return nil
}
-func (s *storageBtrfs) ContainerSnapshotDelete(snapshotContainer Instance) error {
+func (s *storageBtrfs) ContainerSnapshotDelete(snapshotContainer instance.Instance) error {
logger.Debugf("Deleting BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -1471,7 +1490,7 @@ func (s *storageBtrfs) ContainerSnapshotDelete(snapshotContainer Instance) error
return nil
}
-func (s *storageBtrfs) ContainerSnapshotStart(container Instance) (bool, error) {
+func (s *storageBtrfs) ContainerSnapshotStart(container instance.Instance) (bool, error) {
logger.Debugf("Initializing BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -1500,7 +1519,7 @@ func (s *storageBtrfs) ContainerSnapshotStart(container Instance) (bool, error)
return true, nil
}
-func (s *storageBtrfs) ContainerSnapshotStop(container Instance) (bool, error) {
+func (s *storageBtrfs) ContainerSnapshotStop(container instance.Instance) (bool, error) {
logger.Debugf("Stopping BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -1532,7 +1551,7 @@ func (s *storageBtrfs) ContainerSnapshotStop(container Instance) (bool, error) {
}
// ContainerSnapshotRename renames a snapshot of a container.
-func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer Instance, newName string) error {
+func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer instance.Instance, newName string) error {
logger.Debugf("Renaming BTRFS storage volume for snapshot \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newName)
// The storage pool must be mounted.
@@ -1556,7 +1575,7 @@ func (s *storageBtrfs) ContainerSnapshotRename(snapshotContainer Instance, newNa
// Needed for live migration where an empty snapshot needs to be created before
// rsyncing into it.
-func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer Instance) error {
+func (s *storageBtrfs) ContainerSnapshotCreateEmpty(snapshotContainer instance.Instance) error {
logger.Debugf("Creating empty BTRFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
// Mount the storage pool.
@@ -1618,7 +1637,7 @@ func (s *storageBtrfs) doBtrfsBackup(cur string, prev string, target string) err
return err
}
-func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup backup.Backup, source Instance) error {
+func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup backup.Backup, source instance.Instance) error {
// Handle snapshots
finalParent := ""
if !backup.InstanceOnly() {
@@ -1691,7 +1710,7 @@ func (s *storageBtrfs) doContainerBackupCreateOptimized(tmpPath string, backup b
return nil
}
-func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup backup.Backup, source Instance) error {
+func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup backup.Backup, source instance.Instance) error {
// Prepare for rsync
rsync := func(oldPath string, newPath string, bwlimit string) error {
output, err := rsync.LocalCopy(oldPath, newPath, bwlimit, true)
@@ -1774,7 +1793,7 @@ func (s *storageBtrfs) doContainerBackupCreateVanilla(tmpPath string, backup bac
return nil
}
-func (s *storageBtrfs) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
+func (s *storageBtrfs) ContainerBackupCreate(path string, backup backup.Backup, source instance.Instance) error {
var err error
// Generate the actual backup
@@ -2439,7 +2458,7 @@ func (s *storageBtrfs) MigrationSource(args MigrationSourceArgs) (MigrationStora
* xfer costs. Then, after all that, we send the container itself.
*/
var err error
- var snapshots = []Instance{}
+ var snapshots = []instance.Instance{}
if !args.InstanceOnly {
snapshots, err = args.Instance.Snapshots()
if err != nil {
@@ -2539,7 +2558,14 @@ func (s *storageBtrfs) MigrationSink(conn *websocket.Conn, op *operations.Operat
}
instanceName := args.Instance.Name()
- _, instancePool, _ := args.Instance.Storage().GetContainerPoolInfo()
+
+ if args.Instance.Type() != instancetype.Container {
+ return fmt.Errorf("Instance type must be container")
+ }
+
+ ct := args.Instance.(*containerLXC)
+
+ _, instancePool, _ := ct.Storage().GetContainerPoolInfo()
containersPath := driver.GetSnapshotMountPoint(args.Instance.Project(), instancePool, instanceName)
if !args.InstanceOnly && len(args.Snapshots) > 0 {
err := os.MkdirAll(containersPath, driver.ContainersDirMode)
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 45a21a4f19..d9872487db 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -16,6 +16,8 @@ import (
"github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -767,7 +769,7 @@ func (s *storageCeph) StoragePoolUpdate(writable *api.StoragePoolPut, changedCon
return nil
}
-func (s *storageCeph) ContainerStorageReady(container Instance) bool {
+func (s *storageCeph) ContainerStorageReady(container instance.Instance) bool {
name := container.Name()
logger.Debugf(`Checking if RBD storage volume for container "%s" on storage pool "%s" is ready`, name, s.pool.Name)
@@ -782,7 +784,7 @@ func (s *storageCeph) ContainerStorageReady(container Instance) bool {
return true
}
-func (s *storageCeph) ContainerCreate(container Instance) error {
+func (s *storageCeph) ContainerCreate(container instance.Instance) error {
containerName := container.Name()
err := s.doContainerCreate(container.Project(), containerName, container.IsPrivileged())
if err != nil {
@@ -801,7 +803,7 @@ func (s *storageCeph) ContainerCreate(container Instance) error {
return nil
}
-func (s *storageCeph) ContainerCreateFromImage(container Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
+func (s *storageCeph) ContainerCreateFromImage(container instance.Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
logger.Debugf(`Creating RBD storage volume for container "%s" on storage pool "%s"`, s.volume.Name, s.pool.Name)
revert := true
@@ -953,7 +955,7 @@ func (s *storageCeph) ContainerCreateFromImage(container Instance, fingerprint s
return nil
}
-func (s *storageCeph) ContainerDelete(container Instance) error {
+func (s *storageCeph) ContainerDelete(container instance.Instance) error {
containerName := container.Name()
logger.Debugf(`Deleting RBD storage volume for container "%s" on storage pool "%s"`, containerName, s.pool.Name)
@@ -1002,7 +1004,7 @@ func (s *storageCeph) ContainerDelete(container Instance) error {
// - for each snapshot dump the contents into the empty storage volume and
// after each dump take a snapshot of the rbd storage volume
// - dump the container contents into the rbd storage volume.
-func (s *storageCeph) doCrossPoolContainerCopy(target Instance, source Instance, containerOnly bool, refresh bool, refreshSnapshots []Instance) error {
+func (s *storageCeph) doCrossPoolContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool, refresh bool, refreshSnapshots []instance.Instance) error {
sourcePool, err := source.StoragePool()
if err != nil {
return err
@@ -1027,7 +1029,7 @@ func (s *storageCeph) doCrossPoolContainerCopy(target Instance, source Instance,
return err
}
- var snapshots []Instance
+ var snapshots []instance.Instance
if refresh {
snapshots = refreshSnapshots
@@ -1097,13 +1099,24 @@ func (s *storageCeph) doCrossPoolContainerCopy(target Instance, source Instance,
return nil
}
-func (s *storageCeph) ContainerCopy(target Instance, source Instance, containerOnly bool) error {
+func (s *storageCeph) ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error {
sourceContainerName := source.Name()
logger.Debugf(`Copying RBD container storage %s to %s`, sourceContainerName, target.Name())
+ if source.Type() != instancetype.Container {
+ return fmt.Errorf("Source Instance type must be container")
+ }
+
+ if target.Type() != instancetype.Container {
+ return fmt.Errorf("Target Instance type must be container")
+ }
+
+ srcCt := source.(*containerLXC)
+ targetCt := target.(*containerLXC)
+
// Handle cross pool copies
- _, sourcePool, _ := source.Storage().GetContainerPoolInfo()
- _, targetPool, _ := target.Storage().GetContainerPoolInfo()
+ _, sourcePool, _ := srcCt.Storage().GetContainerPoolInfo()
+ _, targetPool, _ := targetCt.Storage().GetContainerPoolInfo()
if sourcePool != targetPool {
return s.doCrossPoolContainerCopy(target, source, containerOnly, false, nil)
}
@@ -1330,13 +1343,13 @@ func (s *storageCeph) ContainerCopy(target Instance, source Instance, containerO
return nil
}
-func (s *storageCeph) ContainerRefresh(target Instance, source Instance, snapshots []Instance) error {
+func (s *storageCeph) ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error {
logger.Debugf(`Refreshing RBD container storage for %s from %s`, target.Name(), source.Name())
return s.doCrossPoolContainerCopy(target, source, len(snapshots) == 0, true, snapshots)
}
-func (s *storageCeph) ContainerMount(c Instance) (bool, error) {
+func (s *storageCeph) ContainerMount(c instance.Instance) (bool, error) {
logger.Debugf("Mounting RBD storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
ourMount, err := s.doContainerMount(c.Project(), c.Name())
@@ -1348,7 +1361,7 @@ func (s *storageCeph) ContainerMount(c Instance) (bool, error) {
return ourMount, nil
}
-func (s *storageCeph) ContainerUmount(c Instance, path string) (bool, error) {
+func (s *storageCeph) ContainerUmount(c instance.Instance, path string) (bool, error) {
logger.Debugf("Unmounting RBD storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
name := c.Name()
@@ -1397,7 +1410,7 @@ func (s *storageCeph) ContainerUmount(c Instance, path string) (bool, error) {
return ourUmount, nil
}
-func (s *storageCeph) ContainerRename(c Instance, newName string) error {
+func (s *storageCeph) ContainerRename(c instance.Instance, newName string) error {
oldName := c.Name()
containerPath := c.Path()
@@ -1549,7 +1562,7 @@ func (s *storageCeph) ContainerRename(c Instance, newName string) error {
return nil
}
-func (s *storageCeph) ContainerRestore(target Instance, source Instance) error {
+func (s *storageCeph) ContainerRestore(target instance.Instance, source instance.Instance) error {
sourceName := source.Name()
targetName := target.Name()
@@ -1591,11 +1604,11 @@ func (s *storageCeph) ContainerRestore(target Instance, source Instance) error {
return nil
}
-func (s *storageCeph) ContainerGetUsage(container Instance) (int64, error) {
+func (s *storageCeph) ContainerGetUsage(container instance.Instance) (int64, error) {
return -1, fmt.Errorf("RBD quotas are currently not supported")
}
-func (s *storageCeph) ContainerSnapshotCreate(snapshotContainer Instance, sourceContainer Instance) error {
+func (s *storageCeph) ContainerSnapshotCreate(snapshotContainer instance.Instance, sourceContainer instance.Instance) error {
containerMntPoint := driver.GetContainerMountPoint(sourceContainer.Project(), s.pool.Name, sourceContainer.Name())
if shared.IsMountPoint(containerMntPoint) {
// This is costly but we need to ensure that all cached data has
@@ -1614,7 +1627,7 @@ func (s *storageCeph) ContainerSnapshotCreate(snapshotContainer Instance, source
return s.doContainerSnapshotCreate(sourceContainer.Project(), snapshotContainer.Name(), sourceContainer.Name())
}
-func (s *storageCeph) ContainerSnapshotDelete(snapshotContainer Instance) error {
+func (s *storageCeph) ContainerSnapshotDelete(snapshotContainer instance.Instance) error {
logger.Debugf(`Deleting RBD storage volume for snapshot "%s" on storage pool "%s"`, s.volume.Name, s.pool.Name)
snapshotContainerName := snapshotContainer.Name()
@@ -1680,7 +1693,7 @@ func (s *storageCeph) ContainerSnapshotDelete(snapshotContainer Instance) error
return nil
}
-func (s *storageCeph) ContainerSnapshotRename(c Instance, newName string) error {
+func (s *storageCeph) ContainerSnapshotRename(c instance.Instance, newName string) error {
oldName := c.Name()
logger.Debugf(`Renaming RBD storage volume for snapshot "%s" from "%s" to "%s"`, oldName, oldName, newName)
@@ -1728,7 +1741,7 @@ func (s *storageCeph) ContainerSnapshotRename(c Instance, newName string) error
return nil
}
-func (s *storageCeph) ContainerSnapshotStart(c Instance) (bool, error) {
+func (s *storageCeph) ContainerSnapshotStart(c instance.Instance) (bool, error) {
containerName := c.Name()
logger.Debugf(`Initializing RBD storage volume for snapshot "%s" on storage pool "%s"`, containerName, s.pool.Name)
@@ -1844,7 +1857,7 @@ func (s *storageCeph) ContainerSnapshotStart(c Instance) (bool, error) {
return true, nil
}
-func (s *storageCeph) ContainerSnapshotStop(c Instance) (bool, error) {
+func (s *storageCeph) ContainerSnapshotStop(c instance.Instance) (bool, error) {
logger.Debugf(`Stopping RBD storage volume for snapshot "%s" on storage pool "%s"`, c.Name(), s.pool.Name)
containerName := c.Name()
@@ -1891,14 +1904,14 @@ func (s *storageCeph) ContainerSnapshotStop(c Instance) (bool, error) {
return true, nil
}
-func (s *storageCeph) ContainerSnapshotCreateEmpty(c Instance) error {
+func (s *storageCeph) ContainerSnapshotCreateEmpty(c instance.Instance) error {
logger.Debugf(`Creating empty RBD storage volume for snapshot "%s" on storage pool "%s" (noop)`, c.Name(), s.pool.Name)
logger.Debugf(`Created empty RBD storage volume for snapshot "%s" on storage pool "%s" (noop)`, c.Name(), s.pool.Name)
return nil
}
-func (s *storageCeph) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
+func (s *storageCeph) ContainerBackupCreate(path string, backup backup.Backup, source instance.Instance) error {
// Generate the actual backup
if !backup.InstanceOnly() {
snapshots, err := source.Snapshots()
@@ -2814,7 +2827,7 @@ func (s *storageCeph) MigrationSource(args MigrationSourceArgs) (MigrationStorag
driver := rbdMigrationSourceDriver{
container: args.Instance,
- snapshots: []Instance{},
+ snapshots: []instance.Instance{},
rbdSnapshotNames: []string{},
ceph: s,
}
diff --git a/lxd/storage_ceph_utils.go b/lxd/storage_ceph_utils.go
index 3ab341ea39..00baa837d7 100644
--- a/lxd/storage_ceph_utils.go
+++ b/lxd/storage_ceph_utils.go
@@ -16,6 +16,7 @@ import (
"github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/rsync"
driver "github.com/lxc/lxd/lxd/storage"
@@ -745,7 +746,7 @@ func (s *storageCeph) getRBDMountOptions() string {
// copyWithoutSnapshotsFull creates a non-sparse copy of a container
// This does not introduce a dependency relation between the source RBD storage
// volume and the target RBD storage volume.
-func (s *storageCeph) copyWithoutSnapshotsFull(target Instance, source Instance) error {
+func (s *storageCeph) copyWithoutSnapshotsFull(target instance.Instance, source instance.Instance) error {
logger.Debugf(`Creating non-sparse copy of RBD storage volume for container "%s" to "%s" without snapshots`, source.Name(), target.Name())
sourceIsSnapshot := source.IsSnapshot()
@@ -813,7 +814,7 @@ func (s *storageCeph) copyWithoutSnapshotsFull(target Instance, source Instance)
// copyWithoutSnapshotsFull creates a sparse copy of a container
// This introduces a dependency relation between the source RBD storage volume
// and the target RBD storage volume.
-func (s *storageCeph) copyWithoutSnapshotsSparse(target Instance, source Instance) error {
+func (s *storageCeph) copyWithoutSnapshotsSparse(target instance.Instance, source instance.Instance) error {
logger.Debugf(`Creating sparse copy of RBD storage volume for container "%s" to "%s" without snapshots`, source.Name(),
target.Name())
@@ -1602,7 +1603,7 @@ func (s *storageCeph) cephRBDVolumeDumpToFile(sourceVolumeName string, file stri
}
// cephRBDVolumeBackupCreate creates a backup of a container or snapshot.
-func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup.Backup, source Instance) error {
+func (s *storageCeph) cephRBDVolumeBackupCreate(tmpPath string, backup backup.Backup, source instance.Instance) error {
sourceIsSnapshot := source.IsSnapshot()
sourceContainerName := source.Name()
sourceContainerOnlyName := project.Prefix(source.Project(), sourceContainerName)
diff --git a/lxd/storage_cephfs.go b/lxd/storage_cephfs.go
index 495165b75d..61de5d7284 100644
--- a/lxd/storage_cephfs.go
+++ b/lxd/storage_cephfs.go
@@ -14,6 +14,7 @@ import (
"github.com/pkg/errors"
"github.com/lxc/lxd/lxd/backup"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/rsync"
@@ -621,81 +622,81 @@ func (s *storageCephFs) StoragePoolVolumeRename(newName string) error {
return nil
}
-func (s *storageCephFs) ContainerStorageReady(container Instance) bool {
+func (s *storageCephFs) ContainerStorageReady(container instance.Instance) bool {
containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
ok, _ := shared.PathIsEmpty(containerMntPoint)
return !ok
}
-func (s *storageCephFs) ContainerCreate(container Instance) error {
+func (s *storageCephFs) ContainerCreate(container instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerCreateFromImage(container Instance, imageFingerprint string, tracker *ioprogress.ProgressTracker) error {
+func (s *storageCephFs) ContainerCreateFromImage(container instance.Instance, imageFingerprint string, tracker *ioprogress.ProgressTracker) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerCanRestore(container Instance, sourceContainer Instance) error {
+func (s *storageCephFs) ContainerCanRestore(container instance.Instance, sourceContainer instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerDelete(container Instance) error {
+func (s *storageCephFs) ContainerDelete(container instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerCopy(target Instance, source Instance, containerOnly bool) error {
+func (s *storageCephFs) ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerRefresh(target Instance, source Instance, snapshots []Instance) error {
+func (s *storageCephFs) ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerMount(c Instance) (bool, error) {
+func (s *storageCephFs) ContainerMount(c instance.Instance) (bool, error) {
return false, fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerUmount(c Instance, path string) (bool, error) {
+func (s *storageCephFs) ContainerUmount(c instance.Instance, path string) (bool, error) {
return false, fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerRename(container Instance, newName string) error {
+func (s *storageCephFs) ContainerRename(container instance.Instance, newName string) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerRestore(container Instance, sourceContainer Instance) error {
+func (s *storageCephFs) ContainerRestore(container instance.Instance, sourceContainer instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerGetUsage(c Instance) (int64, error) {
+func (s *storageCephFs) ContainerGetUsage(c instance.Instance) (int64, error) {
return -1, fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerSnapshotCreate(snapshotContainer Instance, sourceContainer Instance) error {
+func (s *storageCephFs) ContainerSnapshotCreate(snapshotContainer instance.Instance, sourceContainer instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerSnapshotCreateEmpty(snapshotContainer Instance) error {
+func (s *storageCephFs) ContainerSnapshotCreateEmpty(snapshotContainer instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerSnapshotDelete(snapshotContainer Instance) error {
+func (s *storageCephFs) ContainerSnapshotDelete(snapshotContainer instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerSnapshotRename(snapshotContainer Instance, newName string) error {
+func (s *storageCephFs) ContainerSnapshotRename(snapshotContainer instance.Instance, newName string) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerSnapshotStart(container Instance) (bool, error) {
+func (s *storageCephFs) ContainerSnapshotStart(container instance.Instance) (bool, error) {
return false, fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerSnapshotStop(container Instance) (bool, error) {
+func (s *storageCephFs) ContainerSnapshotStop(container instance.Instance) (bool, error) {
return false, fmt.Errorf("CEPHFS cannot be used for containers")
}
-func (s *storageCephFs) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
+func (s *storageCephFs) ContainerBackupCreate(path string, backup backup.Backup, source instance.Instance) error {
return fmt.Errorf("CEPHFS cannot be used for containers")
}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 71073bb63d..91cb164f98 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -12,6 +12,7 @@ import (
"golang.org/x/sys/unix"
"github.com/lxc/lxd/lxd/backup"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -491,13 +492,13 @@ func (s *storageDir) StoragePoolVolumeRename(newName string) error {
storagePoolVolumeTypeCustom, s.poolID)
}
-func (s *storageDir) ContainerStorageReady(container Instance) bool {
+func (s *storageDir) ContainerStorageReady(container instance.Instance) bool {
containerMntPoint := driver.GetContainerMountPoint(container.Project(), s.pool.Name, container.Name())
ok, _ := shared.PathIsEmpty(containerMntPoint)
return !ok
}
-func (s *storageDir) ContainerCreate(container Instance) error {
+func (s *storageDir) ContainerCreate(container instance.Instance) error {
logger.Debugf("Creating empty DIR storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -539,7 +540,7 @@ func (s *storageDir) ContainerCreate(container Instance) error {
return nil
}
-func (s *storageDir) ContainerCreateFromImage(container Instance, imageFingerprint string, tracker *ioprogress.ProgressTracker) error {
+func (s *storageDir) ContainerCreateFromImage(container instance.Instance, imageFingerprint string, tracker *ioprogress.ProgressTracker) error {
logger.Debugf("Creating DIR storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -589,7 +590,7 @@ func (s *storageDir) ContainerCreateFromImage(container Instance, imageFingerpri
return nil
}
-func (s *storageDir) ContainerDelete(container Instance) error {
+func (s *storageDir) ContainerDelete(container instance.Instance) error {
logger.Debugf("Deleting DIR storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
source := s.pool.Config["source"]
@@ -651,9 +652,20 @@ func (s *storageDir) ContainerDelete(container Instance) error {
return nil
}
-func (s *storageDir) copyContainer(target Instance, source Instance) error {
- _, sourcePool, _ := source.Storage().GetContainerPoolInfo()
- _, targetPool, _ := target.Storage().GetContainerPoolInfo()
+func (s *storageDir) copyContainer(target instance.Instance, source instance.Instance) error {
+ if source.Type() != instancetype.Container {
+ return fmt.Errorf("Source Instance type must be container")
+ }
+
+ if target.Type() != instancetype.Container {
+ return fmt.Errorf("Target Instance type must be container")
+ }
+
+ srcCt := source.(*containerLXC)
+ targetCt := target.(*containerLXC)
+
+ _, sourcePool, _ := srcCt.Storage().GetContainerPoolInfo()
+ _, targetPool, _ := targetCt.Storage().GetContainerPoolInfo()
sourceContainerMntPoint := driver.GetContainerMountPoint(source.Project(), sourcePool, source.Name())
if source.IsSnapshot() {
sourceContainerMntPoint = driver.GetSnapshotMountPoint(source.Project(), sourcePool, source.Name())
@@ -684,7 +696,7 @@ func (s *storageDir) copyContainer(target Instance, source Instance) error {
return nil
}
-func (s *storageDir) copySnapshot(target Instance, targetPool string, source Instance, sourcePool string) error {
+func (s *storageDir) copySnapshot(target instance.Instance, targetPool string, source instance.Instance, sourcePool string) error {
sourceName := source.Name()
targetName := target.Name()
sourceContainerMntPoint := driver.GetSnapshotMountPoint(source.Project(), sourcePool, sourceName)
@@ -708,7 +720,7 @@ func (s *storageDir) copySnapshot(target Instance, targetPool string, source Ins
return nil
}
-func (s *storageDir) ContainerCopy(target Instance, source Instance, containerOnly bool) error {
+func (s *storageDir) ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error {
logger.Debugf("Copying DIR container storage %s to %s", source.Name(), target.Name())
err := s.doContainerCopy(target, source, containerOnly, false, nil)
@@ -720,7 +732,7 @@ func (s *storageDir) ContainerCopy(target Instance, source Instance, containerOn
return nil
}
-func (s *storageDir) doContainerCopy(target Instance, source Instance, containerOnly bool, refresh bool, refreshSnapshots []Instance) error {
+func (s *storageDir) doContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool, refresh bool, refreshSnapshots []instance.Instance) error {
_, err := s.StoragePoolMount()
if err != nil {
return err
@@ -770,7 +782,7 @@ func (s *storageDir) doContainerCopy(target Instance, source Instance, container
return nil
}
- var snapshots []Instance
+ var snapshots []instance.Instance
if refresh {
snapshots = refreshSnapshots
@@ -807,7 +819,7 @@ func (s *storageDir) doContainerCopy(target Instance, source Instance, container
return nil
}
-func (s *storageDir) ContainerRefresh(target Instance, source Instance, snapshots []Instance) error {
+func (s *storageDir) ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error {
logger.Debugf("Refreshing DIR container storage for %s from %s", target.Name(), source.Name())
err := s.doContainerCopy(target, source, len(snapshots) == 0, true, snapshots)
@@ -819,15 +831,15 @@ func (s *storageDir) ContainerRefresh(target Instance, source Instance, snapshot
return nil
}
-func (s *storageDir) ContainerMount(c Instance) (bool, error) {
+func (s *storageDir) ContainerMount(c instance.Instance) (bool, error) {
return s.StoragePoolMount()
}
-func (s *storageDir) ContainerUmount(c Instance, path string) (bool, error) {
+func (s *storageDir) ContainerUmount(c instance.Instance, path string) (bool, error) {
return true, nil
}
-func (s *storageDir) ContainerRename(container Instance, newName string) error {
+func (s *storageDir) ContainerRename(container instance.Instance, newName string) error {
logger.Debugf("Renaming DIR storage volume for container \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newName)
_, err := s.StoragePoolMount()
@@ -882,7 +894,7 @@ func (s *storageDir) ContainerRename(container Instance, newName string) error {
return nil
}
-func (s *storageDir) ContainerRestore(container Instance, sourceContainer Instance) error {
+func (s *storageDir) ContainerRestore(container instance.Instance, sourceContainer instance.Instance) error {
logger.Debugf("Restoring DIR storage volume for container \"%s\" from %s to %s", s.volume.Name, sourceContainer.Name(), container.Name())
_, err := s.StoragePoolMount()
@@ -904,7 +916,7 @@ func (s *storageDir) ContainerRestore(container Instance, sourceContainer Instan
return nil
}
-func (s *storageDir) ContainerGetUsage(c Instance) (int64, error) {
+func (s *storageDir) ContainerGetUsage(c instance.Instance) (int64, error) {
path := driver.GetContainerMountPoint(c.Project(), s.pool.Name, c.Name())
ok, err := quota.Supported(path)
@@ -921,7 +933,7 @@ func (s *storageDir) ContainerGetUsage(c Instance) (int64, error) {
return size, nil
}
-func (s *storageDir) ContainerSnapshotCreate(snapshotContainer Instance, sourceContainer Instance) error {
+func (s *storageDir) ContainerSnapshotCreate(snapshotContainer instance.Instance, sourceContainer instance.Instance) error {
logger.Debugf("Creating DIR storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -937,7 +949,7 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer Instance, sourceC
return err
}
- rsync := func(snapshotContainer Instance, oldPath string, newPath string, bwlimit string) error {
+ rsync := func(snapshotContainer instance.Instance, oldPath string, newPath string, bwlimit string) error {
output, err := rsync.LocalCopy(oldPath, newPath, bwlimit, true)
if err != nil {
s.ContainerDelete(snapshotContainer)
@@ -954,7 +966,13 @@ func (s *storageDir) ContainerSnapshotCreate(snapshotContainer Instance, sourceC
defer sourceContainer.StorageStop()
}
- _, sourcePool, _ := sourceContainer.Storage().GetContainerPoolInfo()
+ if sourceContainer.Type() != instancetype.Container {
+ return fmt.Errorf("Source Instance type must be container")
+ }
+
+ srcCt := sourceContainer.(*containerLXC)
+
+ _, sourcePool, _ := srcCt.Storage().GetContainerPoolInfo()
sourceContainerName := sourceContainer.Name()
sourceContainerMntPoint := driver.GetContainerMountPoint(sourceContainer.Project(), sourcePool, sourceContainerName)
bwlimit := s.pool.Config["rsync.bwlimit"]
@@ -998,7 +1016,7 @@ onSuccess:
return nil
}
-func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer Instance) error {
+func (s *storageDir) ContainerSnapshotCreateEmpty(snapshotContainer instance.Instance) error {
logger.Debugf("Creating empty DIR storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -1072,7 +1090,7 @@ func dirSnapshotDeleteInternal(projectName, poolName string, snapshotName string
return nil
}
-func (s *storageDir) ContainerSnapshotDelete(snapshotContainer Instance) error {
+func (s *storageDir) ContainerSnapshotDelete(snapshotContainer instance.Instance) error {
logger.Debugf("Deleting DIR storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
_, err := s.StoragePoolMount()
@@ -1095,7 +1113,7 @@ func (s *storageDir) ContainerSnapshotDelete(snapshotContainer Instance) error {
return nil
}
-func (s *storageDir) ContainerSnapshotRename(snapshotContainer Instance, newName string) error {
+func (s *storageDir) ContainerSnapshotRename(snapshotContainer instance.Instance, newName string) error {
logger.Debugf("Renaming DIR storage volume for snapshot \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newName)
_, err := s.StoragePoolMount()
@@ -1116,15 +1134,15 @@ func (s *storageDir) ContainerSnapshotRename(snapshotContainer Instance, newName
return nil
}
-func (s *storageDir) ContainerSnapshotStart(container Instance) (bool, error) {
+func (s *storageDir) ContainerSnapshotStart(container instance.Instance) (bool, error) {
return s.StoragePoolMount()
}
-func (s *storageDir) ContainerSnapshotStop(container Instance) (bool, error) {
+func (s *storageDir) ContainerSnapshotStop(container instance.Instance) (bool, error) {
return true, nil
}
-func (s *storageDir) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
+func (s *storageDir) ContainerBackupCreate(path string, backup backup.Backup, source instance.Instance) error {
// Prepare for rsync
rsync := func(oldPath string, newPath string, bwlimit string) error {
output, err := rsync.LocalCopy(oldPath, newPath, bwlimit, true)
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 2f0166193d..a49fbac4c4 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -13,6 +13,8 @@ import (
"github.com/pkg/errors"
"github.com/lxc/lxd/lxd/backup"
+ "github.com/lxc/lxd/lxd/instance"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -923,7 +925,7 @@ func (s *storageLvm) StoragePoolVolumeRename(newName string) error {
storagePoolVolumeTypeCustom, s.poolID)
}
-func (s *storageLvm) ContainerStorageReady(container Instance) bool {
+func (s *storageLvm) ContainerStorageReady(container instance.Instance) bool {
containerLvmName := containerNameToLVName(container.Name())
poolName := s.getOnDiskPoolName()
containerLvmPath := getLvmDevPath(container.Project(), poolName, storagePoolVolumeAPIEndpointContainers, containerLvmName)
@@ -931,7 +933,7 @@ func (s *storageLvm) ContainerStorageReady(container Instance) bool {
return ok
}
-func (s *storageLvm) ContainerCreate(container Instance) error {
+func (s *storageLvm) ContainerCreate(container instance.Instance) error {
logger.Debugf("Creating empty LVM storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
tryUndo := true
@@ -995,7 +997,7 @@ func (s *storageLvm) ContainerCreate(container Instance) error {
return nil
}
-func (s *storageLvm) ContainerCreateFromImage(container Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
+func (s *storageLvm) ContainerCreateFromImage(container instance.Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
logger.Debugf("Creating LVM storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
tryUndo := true
@@ -1110,7 +1112,7 @@ func lvmContainerDeleteInternal(projectName, poolName string, ctName string, isS
return nil
}
-func (s *storageLvm) ContainerDelete(container Instance) error {
+func (s *storageLvm) ContainerDelete(container instance.Instance) error {
logger.Debugf("Deleting LVM storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
containerName := container.Name()
@@ -1124,7 +1126,7 @@ func (s *storageLvm) ContainerDelete(container Instance) error {
return nil
}
-func (s *storageLvm) ContainerCopy(target Instance, source Instance, containerOnly bool) error {
+func (s *storageLvm) ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error {
logger.Debugf("Copying LVM container storage for container %s to %s", source.Name(), target.Name())
err := s.doContainerCopy(target, source, containerOnly, false, nil)
@@ -1136,7 +1138,7 @@ func (s *storageLvm) ContainerCopy(target Instance, source Instance, containerOn
return nil
}
-func (s *storageLvm) doContainerCopy(target Instance, source Instance, containerOnly bool, refresh bool, refreshSnapshots []Instance) error {
+func (s *storageLvm) doContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool, refresh bool, refreshSnapshots []instance.Instance) error {
ourStart, err := source.StorageStart()
if err != nil {
return err
@@ -1180,7 +1182,7 @@ func (s *storageLvm) doContainerCopy(target Instance, source Instance, container
return nil
}
- var snapshots []Instance
+ var snapshots []instance.Instance
if refresh {
snapshots = refreshSnapshots
@@ -1222,7 +1224,7 @@ func (s *storageLvm) doContainerCopy(target Instance, source Instance, container
return nil
}
-func (s *storageLvm) ContainerRefresh(target Instance, source Instance, snapshots []Instance) error {
+func (s *storageLvm) ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error {
logger.Debugf("Refreshing LVM container storage for %s from %s", target.Name(), source.Name())
err := s.doContainerCopy(target, source, len(snapshots) == 0, true, snapshots)
@@ -1234,7 +1236,7 @@ func (s *storageLvm) ContainerRefresh(target Instance, source Instance, snapshot
return nil
}
-func (s *storageLvm) ContainerMount(c Instance) (bool, error) {
+func (s *storageLvm) ContainerMount(c instance.Instance) (bool, error) {
return s.doContainerMount(c.Project(), c.Name(), false)
}
@@ -1295,7 +1297,7 @@ func (s *storageLvm) doContainerMount(project, name string, snap bool) (bool, er
return ourMount, nil
}
-func (s *storageLvm) ContainerUmount(c Instance, path string) (bool, error) {
+func (s *storageLvm) ContainerUmount(c instance.Instance, path string) (bool, error) {
return s.umount(c.Project(), c.Name(), path)
}
@@ -1343,7 +1345,7 @@ func (s *storageLvm) umount(project, name string, path string) (bool, error) {
return ourUmount, nil
}
-func (s *storageLvm) ContainerRename(container Instance, newContainerName string) error {
+func (s *storageLvm) ContainerRename(container instance.Instance, newContainerName string) error {
logger.Debugf("Renaming LVM storage volume for container \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newContainerName)
tryUndo := true
@@ -1424,10 +1426,21 @@ func (s *storageLvm) ContainerRename(container Instance, newContainerName string
return nil
}
-func (s *storageLvm) ContainerRestore(target Instance, source Instance) error {
+func (s *storageLvm) ContainerRestore(target instance.Instance, source instance.Instance) error {
logger.Debugf("Restoring LVM storage volume for container \"%s\" from %s to %s", s.volume.Name, source.Name(), target.Name())
- _, sourcePool, _ := source.Storage().GetContainerPoolInfo()
+ if source.Type() != instancetype.Container {
+ return fmt.Errorf("Source Instance type must be container")
+ }
+
+ if target.Type() != instancetype.Container {
+ return fmt.Errorf("Target Instance type must be container")
+ }
+
+ srcCt := source.(*containerLXC)
+ targetCt := target.(*containerLXC)
+
+ _, sourcePool, _ := srcCt.Storage().GetContainerPoolInfo()
if s.pool.Name != sourcePool {
return fmt.Errorf("containers must be on the same pool to be restored")
}
@@ -1439,12 +1452,12 @@ func (s *storageLvm) ContainerRestore(target Instance, source Instance) error {
targetLvmName := containerNameToLVName(targetName)
targetPath := target.Path()
if s.useThinpool {
- ourUmount, err := target.Storage().ContainerUmount(target, targetPath)
+ ourUmount, err := targetCt.Storage().ContainerUmount(target, targetPath)
if err != nil {
return err
}
if ourUmount {
- defer target.Storage().ContainerMount(target)
+ defer targetCt.Storage().ContainerMount(target)
}
poolName := s.getOnDiskPoolName()
@@ -1503,11 +1516,11 @@ func (s *storageLvm) ContainerRestore(target Instance, source Instance) error {
return nil
}
-func (s *storageLvm) ContainerGetUsage(container Instance) (int64, error) {
+func (s *storageLvm) ContainerGetUsage(container instance.Instance) (int64, error) {
return -1, fmt.Errorf("the LVM container backend doesn't support quotas")
}
-func (s *storageLvm) ContainerSnapshotCreate(snapshotContainer Instance, sourceContainer Instance) error {
+func (s *storageLvm) ContainerSnapshotCreate(snapshotContainer instance.Instance, sourceContainer instance.Instance) error {
logger.Debugf("Creating LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
err := s.createSnapshotContainer(snapshotContainer, sourceContainer, true)
@@ -1519,7 +1532,7 @@ func (s *storageLvm) ContainerSnapshotCreate(snapshotContainer Instance, sourceC
return nil
}
-func (s *storageLvm) ContainerSnapshotDelete(snapshotContainer Instance) error {
+func (s *storageLvm) ContainerSnapshotDelete(snapshotContainer instance.Instance) error {
logger.Debugf("Deleting LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
err := s.ContainerDelete(snapshotContainer)
@@ -1531,7 +1544,7 @@ func (s *storageLvm) ContainerSnapshotDelete(snapshotContainer Instance) error {
return nil
}
-func (s *storageLvm) ContainerSnapshotRename(snapshotContainer Instance, newContainerName string) error {
+func (s *storageLvm) ContainerSnapshotRename(snapshotContainer instance.Instance, newContainerName string) error {
logger.Debugf("Renaming LVM storage volume for snapshot \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newContainerName)
tryUndo := true
@@ -1563,7 +1576,7 @@ func (s *storageLvm) ContainerSnapshotRename(snapshotContainer Instance, newCont
return nil
}
-func (s *storageLvm) ContainerSnapshotStart(container Instance) (bool, error) {
+func (s *storageLvm) ContainerSnapshotStart(container instance.Instance) (bool, error) {
logger.Debugf(`Initializing LVM storage volume for snapshot "%s" on storage pool "%s"`, s.volume.Name, s.pool.Name)
poolName := s.getOnDiskPoolName()
@@ -1613,7 +1626,7 @@ func (s *storageLvm) ContainerSnapshotStart(container Instance) (bool, error) {
return true, nil
}
-func (s *storageLvm) ContainerSnapshotStop(container Instance) (bool, error) {
+func (s *storageLvm) ContainerSnapshotStop(container instance.Instance) (bool, error) {
logger.Debugf("Stopping LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
containerName := container.Name()
@@ -1652,7 +1665,7 @@ func (s *storageLvm) ContainerSnapshotStop(container Instance) (bool, error) {
return true, nil
}
-func (s *storageLvm) ContainerSnapshotCreateEmpty(snapshotContainer Instance) error {
+func (s *storageLvm) ContainerSnapshotCreateEmpty(snapshotContainer instance.Instance) error {
logger.Debugf("Creating empty LVM storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
err := s.ContainerCreate(snapshotContainer)
@@ -1664,7 +1677,7 @@ func (s *storageLvm) ContainerSnapshotCreateEmpty(snapshotContainer Instance) er
return nil
}
-func (s *storageLvm) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
+func (s *storageLvm) ContainerBackupCreate(path string, backup backup.Backup, source instance.Instance) error {
poolName := s.getOnDiskPoolName()
// Prepare for rsync
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index 35b6333f7c..4362f09878 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -11,6 +11,7 @@ import (
"github.com/pkg/errors"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/rsync"
@@ -257,7 +258,7 @@ func (s *storageLvm) createSnapshotLV(project, vgName string, origLvName string,
return targetLvmVolumePath, nil
}
-func (s *storageLvm) createSnapshotContainer(snapshotContainer Instance, sourceContainer Instance, readonly bool) error {
+func (s *storageLvm) createSnapshotContainer(snapshotContainer instance.Instance, sourceContainer instance.Instance, readonly bool) error {
tryUndo := true
sourceContainerName := sourceContainer.Name()
@@ -304,7 +305,7 @@ func (s *storageLvm) createSnapshotContainer(snapshotContainer Instance, sourceC
}
// Copy a container on a storage pool that does use a thinpool.
-func (s *storageLvm) copyContainerThinpool(target Instance, source Instance, readonly bool) error {
+func (s *storageLvm) copyContainerThinpool(target instance.Instance, source instance.Instance, readonly bool) error {
err := s.createSnapshotContainer(target, source, readonly)
if err != nil {
logger.Errorf("Error creating snapshot LV for copy: %s", err)
@@ -342,7 +343,7 @@ func (s *storageLvm) copyContainerThinpool(target Instance, source Instance, rea
return nil
}
-func (s *storageLvm) copySnapshot(target Instance, source Instance, refresh bool) error {
+func (s *storageLvm) copySnapshot(target instance.Instance, source instance.Instance, refresh bool) error {
sourcePool, err := source.StoragePool()
if err != nil {
return err
@@ -371,7 +372,7 @@ func (s *storageLvm) copySnapshot(target Instance, source Instance, refresh bool
}
// Copy a container on a storage pool that does not use a thinpool.
-func (s *storageLvm) copyContainerLv(target Instance, source Instance, readonly bool, refresh bool) error {
+func (s *storageLvm) copyContainerLv(target instance.Instance, source instance.Instance, readonly bool, refresh bool) error {
exists, err := storageLVExists(getLvmDevPath(target.Project(), s.getOnDiskPoolName(),
storagePoolVolumeAPIEndpointContainers, containerNameToLVName(target.Name())))
if err != nil {
@@ -446,7 +447,7 @@ func (s *storageLvm) copyContainerLv(target Instance, source Instance, readonly
}
// Copy an lvm container.
-func (s *storageLvm) copyContainer(target Instance, source Instance, refresh bool) error {
+func (s *storageLvm) copyContainer(target instance.Instance, source instance.Instance, refresh bool) error {
targetPool, err := target.StoragePool()
if err != nil {
return err
@@ -484,7 +485,7 @@ func (s *storageLvm) copyContainer(target Instance, source Instance, refresh boo
return nil
}
-func (s *storageLvm) containerCreateFromImageLv(c Instance, fp string) error {
+func (s *storageLvm) containerCreateFromImageLv(c instance.Instance, fp string) error {
containerName := c.Name()
err := s.ContainerCreate(c)
@@ -516,7 +517,7 @@ func (s *storageLvm) containerCreateFromImageLv(c Instance, fp string) error {
return nil
}
-func (s *storageLvm) containerCreateFromImageThinLv(c Instance, fp string) error {
+func (s *storageLvm) containerCreateFromImageThinLv(c instance.Instance, fp string) error {
poolName := s.getOnDiskPoolName()
// Check if the image already exists.
imageLvmDevPath := getLvmDevPath("default", poolName, storagePoolVolumeAPIEndpointImages, fp)
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 6011f304ce..d8ef5561d9 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -8,6 +8,7 @@ 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/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -43,8 +44,8 @@ type MigrationStorageSourceDriver interface {
}
type rsyncStorageSourceDriver struct {
- container Instance
- snapshots []Instance
+ container instance.Instance
+ snapshots []instance.Instance
rsyncFeatures []string
}
@@ -147,7 +148,7 @@ func rsyncStorageMigrationSource(args MigrationSourceArgs) (MigrationStorageSour
}
func rsyncRefreshSource(refreshSnapshots []string, args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
- var snapshots = []Instance{}
+ var snapshots = []instance.Instance{}
if !args.InstanceOnly {
allSnapshots, err := args.Instance.Snapshots()
if err != nil {
@@ -169,7 +170,7 @@ func rsyncRefreshSource(refreshSnapshots []string, args MigrationSourceArgs) (Mi
func rsyncMigrationSource(args MigrationSourceArgs) (MigrationStorageSourceDriver, error) {
var err error
- var snapshots = []Instance{}
+ var snapshots = []instance.Instance{}
if !args.InstanceOnly {
snapshots, err = args.Instance.Snapshots()
if err != nil {
@@ -311,7 +312,13 @@ func rsyncMigrationSink(conn *websocket.Conn, op *operations.Operation, args Mig
return err
}
- isDirBackend := args.Instance.Storage().GetStorageType() == storageTypeDir
+ if args.Instance.Type() != instancetype.Container {
+ return fmt.Errorf("Instance type must be container")
+ }
+
+ ct := args.Instance.(*containerLXC)
+
+ isDirBackend := ct.Storage().GetStorageType() == storageTypeDir
if isDirBackend {
if !args.InstanceOnly {
for _, snap := range args.Snapshots {
diff --git a/lxd/storage_migration_btrfs.go b/lxd/storage_migration_btrfs.go
index 96286b1c24..3b95273e70 100644
--- a/lxd/storage_migration_btrfs.go
+++ b/lxd/storage_migration_btrfs.go
@@ -9,6 +9,8 @@ import (
"github.com/gorilla/websocket"
+ "github.com/lxc/lxd/lxd/instance"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
driver "github.com/lxc/lxd/lxd/storage"
@@ -17,8 +19,8 @@ import (
)
type btrfsMigrationSourceDriver struct {
- container Instance
- snapshots []Instance
+ container instance.Instance
+ snapshots []instance.Instance
btrfsSnapshotNames []string
btrfs *storageBtrfs
runningSnapName string
@@ -70,7 +72,13 @@ func (s *btrfsMigrationSourceDriver) send(conn *websocket.Conn, btrfsPath string
}
func (s *btrfsMigrationSourceDriver) SendWhileRunning(conn *websocket.Conn, op *operations.Operation, bwlimit string, containerOnly bool) error {
- _, containerPool, _ := s.container.Storage().GetContainerPoolInfo()
+ if s.container.Type() != instancetype.Container {
+ return fmt.Errorf("Instance type must be container")
+ }
+
+ ct := s.container.(*containerLXC)
+
+ _, containerPool, _ := ct.Storage().GetContainerPoolInfo()
containerName := s.container.Name()
containersPath := driver.GetContainerMountPoint("default", containerPool, "")
sourceName := containerName
diff --git a/lxd/storage_migration_ceph.go b/lxd/storage_migration_ceph.go
index 1817bfec07..851697c3e1 100644
--- a/lxd/storage_migration_ceph.go
+++ b/lxd/storage_migration_ceph.go
@@ -9,6 +9,7 @@ import (
"github.com/gorilla/websocket"
"github.com/pborman/uuid"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -17,15 +18,15 @@ import (
)
type rbdMigrationSourceDriver struct {
- container Instance
- snapshots []Instance
+ container instance.Instance
+ snapshots []instance.Instance
rbdSnapshotNames []string
ceph *storageCeph
runningSnapName string
stoppedSnapName string
}
-func (s *rbdMigrationSourceDriver) Snapshots() []Instance {
+func (s *rbdMigrationSourceDriver) Snapshots() []instance.Instance {
return s.snapshots
}
diff --git a/lxd/storage_migration_zfs.go b/lxd/storage_migration_zfs.go
index 72747a08a4..9568918208 100644
--- a/lxd/storage_migration_zfs.go
+++ b/lxd/storage_migration_zfs.go
@@ -9,6 +9,7 @@ import (
"github.com/gorilla/websocket"
"github.com/pborman/uuid"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/project"
@@ -17,8 +18,8 @@ import (
)
type zfsMigrationSourceDriver struct {
- instance Instance
- snapshots []Instance
+ instance instance.Instance
+ snapshots []instance.Instance
zfsSnapshotNames []string
zfs *storageZfs
runningSnapName string
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index 7b9c2d1d80..08fee51c8e 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -6,6 +6,7 @@ import (
"github.com/gorilla/websocket"
"github.com/lxc/lxd/lxd/backup"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/state"
@@ -111,73 +112,73 @@ func (s *storageMock) StoragePoolUpdate(writable *api.StoragePoolPut, changedCon
return nil
}
-func (s *storageMock) ContainerStorageReady(container Instance) bool {
+func (s *storageMock) ContainerStorageReady(container instance.Instance) bool {
return true
}
-func (s *storageMock) ContainerCreate(container Instance) error {
+func (s *storageMock) ContainerCreate(container instance.Instance) error {
return nil
}
-func (s *storageMock) ContainerCreateFromImage(container Instance, imageFingerprint string, tracker *ioprogress.ProgressTracker) error {
+func (s *storageMock) ContainerCreateFromImage(container instance.Instance, imageFingerprint string, tracker *ioprogress.ProgressTracker) error {
return nil
}
-func (s *storageMock) ContainerDelete(container Instance) error {
+func (s *storageMock) ContainerDelete(container instance.Instance) error {
return nil
}
-func (s *storageMock) ContainerCopy(target Instance, source Instance, containerOnly bool) error {
+func (s *storageMock) ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error {
return nil
}
-func (s *storageMock) ContainerRefresh(target Instance, source Instance, snapshots []Instance) error {
+func (s *storageMock) ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error {
return nil
}
-func (s *storageMock) ContainerMount(c Instance) (bool, error) {
+func (s *storageMock) ContainerMount(c instance.Instance) (bool, error) {
return true, nil
}
-func (s *storageMock) ContainerUmount(c Instance, path string) (bool, error) {
+func (s *storageMock) ContainerUmount(c instance.Instance, path string) (bool, error) {
return true, nil
}
-func (s *storageMock) ContainerRename(container Instance, newName string) error {
+func (s *storageMock) ContainerRename(container instance.Instance, newName string) error {
return nil
}
-func (s *storageMock) ContainerRestore(container Instance, sourceContainer Instance) error {
+func (s *storageMock) ContainerRestore(container instance.Instance, sourceContainer instance.Instance) error {
return nil
}
-func (s *storageMock) ContainerGetUsage(container Instance) (int64, error) {
+func (s *storageMock) ContainerGetUsage(container instance.Instance) (int64, error) {
return 0, nil
}
-func (s *storageMock) ContainerSnapshotCreate(snapshotContainer Instance, sourceContainer Instance) error {
+func (s *storageMock) ContainerSnapshotCreate(snapshotContainer instance.Instance, sourceContainer instance.Instance) error {
return nil
}
-func (s *storageMock) ContainerSnapshotDelete(snapshotContainer Instance) error {
+func (s *storageMock) ContainerSnapshotDelete(snapshotContainer instance.Instance) error {
return nil
}
-func (s *storageMock) ContainerSnapshotRename(snapshotContainer Instance, newName string) error {
+func (s *storageMock) ContainerSnapshotRename(snapshotContainer instance.Instance, newName string) error {
return nil
}
-func (s *storageMock) ContainerSnapshotStart(container Instance) (bool, error) {
+func (s *storageMock) ContainerSnapshotStart(container instance.Instance) (bool, error) {
return true, nil
}
-func (s *storageMock) ContainerSnapshotStop(container Instance) (bool, error) {
+func (s *storageMock) ContainerSnapshotStop(container instance.Instance) (bool, error) {
return true, nil
}
-func (s *storageMock) ContainerSnapshotCreateEmpty(snapshotContainer Instance) error {
+func (s *storageMock) ContainerSnapshotCreateEmpty(snapshotContainer instance.Instance) error {
return nil
}
-func (s *storageMock) ContainerBackupCreate(path string, backup backup.Backup, sourceContainer Instance) error {
+func (s *storageMock) ContainerBackupCreate(path string, backup backup.Backup, sourceContainer instance.Instance) error {
return nil
}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index be50dabb74..53caec7604 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -15,6 +15,7 @@ import (
"golang.org/x/sys/unix"
"github.com/lxc/lxd/lxd/backup"
+ "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -764,11 +765,11 @@ func (s *storageZfs) StoragePoolVolumeRename(newName string) error {
}
// Things we don't need to care about
-func (s *storageZfs) ContainerMount(c Instance) (bool, error) {
+func (s *storageZfs) ContainerMount(c instance.Instance) (bool, error) {
return s.doContainerMount(c.Project(), c.Name(), c.IsPrivileged())
}
-func (s *storageZfs) ContainerUmount(c Instance, path string) (bool, error) {
+func (s *storageZfs) ContainerUmount(c instance.Instance, path string) (bool, error) {
logger.Debugf("Unmounting ZFS storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
name := c.Name()
@@ -813,13 +814,13 @@ func (s *storageZfs) ContainerUmount(c Instance, path string) (bool, error) {
}
// Things we do have to care about
-func (s *storageZfs) ContainerStorageReady(container Instance) bool {
+func (s *storageZfs) ContainerStorageReady(container instance.Instance) bool {
volumeName := project.Prefix(container.Project(), container.Name())
fs := fmt.Sprintf("containers/%s", volumeName)
return zfsFilesystemEntityExists(s.getOnDiskPoolName(), fs)
}
-func (s *storageZfs) ContainerCreate(container Instance) error {
+func (s *storageZfs) ContainerCreate(container instance.Instance) error {
err := s.doContainerCreate(container.Project(), container.Name(), container.IsPrivileged())
if err != nil {
s.doContainerDelete(container.Project(), container.Name())
@@ -842,7 +843,7 @@ func (s *storageZfs) ContainerCreate(container Instance) error {
return nil
}
-func (s *storageZfs) ContainerCreateFromImage(container Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
+func (s *storageZfs) ContainerCreateFromImage(container instance.Instance, fingerprint string, tracker *ioprogress.ProgressTracker) error {
logger.Debugf("Creating ZFS storage volume for container \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
containerPath := container.Path()
@@ -920,7 +921,7 @@ func (s *storageZfs) ContainerCreateFromImage(container Instance, fingerprint st
return nil
}
-func (s *storageZfs) ContainerDelete(container Instance) error {
+func (s *storageZfs) ContainerDelete(container instance.Instance) error {
err := s.doContainerDelete(container.Project(), container.Name())
if err != nil {
return err
@@ -929,7 +930,7 @@ func (s *storageZfs) ContainerDelete(container Instance) error {
return nil
}
-func (s *storageZfs) copyWithoutSnapshotsSparse(target Instance, source Instance) error {
+func (s *storageZfs) copyWithoutSnapshotsSparse(target instance.Instance, source instance.Instance) error {
poolName := s.getOnDiskPoolName()
sourceContainerName := source.Name()
@@ -1031,7 +1032,7 @@ func (s *storageZfs) copyWithoutSnapshotsSparse(target Instance, source Instance
return nil
}
-func (s *storageZfs) copyWithoutSnapshotFull(target Instance, source Instance) error {
+func (s *storageZfs) copyWithoutSnapshotFull(target instance.Instance, source instance.Instance) error {
logger.Debugf("Creating full ZFS copy \"%s\" to \"%s\"", source.Name(), target.Name())
sourceIsSnapshot := source.IsSnapshot()
@@ -1132,7 +1133,7 @@ func (s *storageZfs) copyWithoutSnapshotFull(target Instance, source Instance) e
return nil
}
-func (s *storageZfs) copyWithSnapshots(target Instance, source Instance, parentSnapshot string) error {
+func (s *storageZfs) copyWithSnapshots(target instance.Instance, source instance.Instance, parentSnapshot string) error {
sourceName := source.Name()
targetParentName, targetSnapOnlyName, _ := shared.ContainerGetParentAndSnapshotName(target.Name())
containersPath := driver.GetSnapshotMountPoint(target.Project(), s.pool.Name, targetParentName)
@@ -1179,7 +1180,7 @@ func (s *storageZfs) copyWithSnapshots(target Instance, source Instance, parentS
return nil
}
-func (s *storageZfs) doCrossPoolContainerCopy(target Instance, source Instance, containerOnly bool, refresh bool, refreshSnapshots []Instance) error {
+func (s *storageZfs) doCrossPoolContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool, refresh bool, refreshSnapshots []instance.Instance) error {
sourcePool, err := source.StoragePool()
if err != nil {
return err
@@ -1204,7 +1205,7 @@ func (s *storageZfs) doCrossPoolContainerCopy(target Instance, source Instance,
return err
}
- var snapshots []Instance
+ var snapshots []instance.Instance
if refresh {
snapshots = refreshSnapshots
@@ -1257,7 +1258,7 @@ func (s *storageZfs) doCrossPoolContainerCopy(target Instance, source Instance,
return nil
}
-func (s *storageZfs) ContainerCopy(target Instance, source Instance, containerOnly bool) error {
+func (s *storageZfs) ContainerCopy(target instance.Instance, source instance.Instance, containerOnly bool) error {
logger.Debugf("Copying ZFS container storage %s to %s", source.Name(), target.Name())
ourStart, err := source.StorageStart()
@@ -1268,8 +1269,19 @@ func (s *storageZfs) ContainerCopy(target Instance, source Instance, containerOn
defer source.StorageStop()
}
- _, sourcePool, _ := source.Storage().GetContainerPoolInfo()
- _, targetPool, _ := target.Storage().GetContainerPoolInfo()
+ if source.Type() != instancetype.Container {
+ return fmt.Errorf("Source Instance type must be container")
+ }
+
+ if target.Type() != instancetype.Container {
+ return fmt.Errorf("Target Instance type must be container")
+ }
+
+ srcCt := source.(*containerLXC)
+ targetCt := target.(*containerLXC)
+
+ _, sourcePool, _ := srcCt.Storage().GetContainerPoolInfo()
+ _, targetPool, _ := targetCt.Storage().GetContainerPoolInfo()
if sourcePool != targetPool {
return s.doCrossPoolContainerCopy(target, source, containerOnly, false, nil)
}
@@ -1384,7 +1396,7 @@ func (s *storageZfs) ContainerCopy(target Instance, source Instance, containerOn
return nil
}
-func (s *storageZfs) ContainerRefresh(target Instance, source Instance, snapshots []Instance) error {
+func (s *storageZfs) ContainerRefresh(target instance.Instance, source instance.Instance, snapshots []instance.Instance) error {
logger.Debugf("Refreshing ZFS container storage for %s from %s", target.Name(), source.Name())
ourStart, err := source.StorageStart()
@@ -1398,7 +1410,7 @@ func (s *storageZfs) ContainerRefresh(target Instance, source Instance, snapshot
return s.doCrossPoolContainerCopy(target, source, len(snapshots) == 0, true, snapshots)
}
-func (s *storageZfs) ContainerRename(container Instance, newName string) error {
+func (s *storageZfs) ContainerRename(container instance.Instance, newName string) error {
logger.Debugf("Renaming ZFS storage volume for container \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newName)
poolName := s.getOnDiskPoolName()
@@ -1482,7 +1494,7 @@ func (s *storageZfs) ContainerRename(container Instance, newName string) error {
return nil
}
-func (s *storageZfs) ContainerRestore(target Instance, source Instance) error {
+func (s *storageZfs) ContainerRestore(target instance.Instance, source instance.Instance) error {
logger.Debugf("Restoring ZFS storage volume for container \"%s\" from %s to %s", s.volume.Name, source.Name(), target.Name())
snaps, err := target.Snapshots()
@@ -1546,7 +1558,7 @@ func (s *storageZfs) ContainerRestore(target Instance, source Instance) error {
return nil
}
-func (s *storageZfs) ContainerGetUsage(container Instance) (int64, error) {
+func (s *storageZfs) ContainerGetUsage(container instance.Instance) (int64, error) {
var err error
fs := fmt.Sprintf("containers/%s", project.Prefix(container.Project(), container.Name()))
@@ -1625,7 +1637,7 @@ func (s *storageZfs) doContainerSnapshotCreate(projectName, targetName string, s
return nil
}
-func (s *storageZfs) ContainerSnapshotCreate(snapshotContainer Instance, sourceContainer Instance) error {
+func (s *storageZfs) ContainerSnapshotCreate(snapshotContainer instance.Instance, sourceContainer instance.Instance) error {
err := s.doContainerSnapshotCreate(sourceContainer.Project(), snapshotContainer.Name(), sourceContainer.Name())
if err != nil {
s.ContainerSnapshotDelete(snapshotContainer)
@@ -1719,7 +1731,7 @@ func zfsSnapshotDeleteInternal(projectName, poolName string, ctName string, onDi
return nil
}
-func (s *storageZfs) ContainerSnapshotDelete(snapshotContainer Instance) error {
+func (s *storageZfs) ContainerSnapshotDelete(snapshotContainer instance.Instance) error {
logger.Debugf("Deleting ZFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
poolName := s.getOnDiskPoolName()
@@ -1733,7 +1745,7 @@ func (s *storageZfs) ContainerSnapshotDelete(snapshotContainer Instance) error {
return nil
}
-func (s *storageZfs) ContainerSnapshotRename(snapshotContainer Instance, newName string) error {
+func (s *storageZfs) ContainerSnapshotRename(snapshotContainer instance.Instance, newName string) error {
logger.Debugf("Renaming ZFS storage volume for snapshot \"%s\" from %s to %s", s.volume.Name, s.volume.Name, newName)
oldName := snapshotContainer.Name()
@@ -1798,7 +1810,7 @@ func (s *storageZfs) ContainerSnapshotRename(snapshotContainer Instance, newName
return nil
}
-func (s *storageZfs) ContainerSnapshotStart(container Instance) (bool, error) {
+func (s *storageZfs) ContainerSnapshotStart(container instance.Instance) (bool, error) {
logger.Debugf("Initializing ZFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
cName, sName, _ := shared.ContainerGetParentAndSnapshotName(container.Name())
@@ -1822,7 +1834,7 @@ func (s *storageZfs) ContainerSnapshotStart(container Instance) (bool, error) {
return true, nil
}
-func (s *storageZfs) ContainerSnapshotStop(container Instance) (bool, error) {
+func (s *storageZfs) ContainerSnapshotStop(container instance.Instance) (bool, error) {
logger.Debugf("Stopping ZFS storage volume for snapshot \"%s\" on storage pool \"%s\"", s.volume.Name, s.pool.Name)
cName, sName, _ := shared.ContainerGetParentAndSnapshotName(container.Name())
@@ -1837,12 +1849,12 @@ func (s *storageZfs) ContainerSnapshotStop(container Instance) (bool, error) {
return true, nil
}
-func (s *storageZfs) ContainerSnapshotCreateEmpty(snapshotContainer Instance) error {
+func (s *storageZfs) ContainerSnapshotCreateEmpty(snapshotContainer instance.Instance) error {
/* don't touch the fs yet, as migration will do that for us */
return nil
}
-func (s *storageZfs) doContainerOnlyBackup(tmpPath string, backup backup.Backup, source Instance) error {
+func (s *storageZfs) doContainerOnlyBackup(tmpPath string, backup backup.Backup, source instance.Instance) error {
sourceIsSnapshot := source.IsSnapshot()
poolName := s.getOnDiskPoolName()
@@ -1890,7 +1902,7 @@ func (s *storageZfs) doContainerOnlyBackup(tmpPath string, backup backup.Backup,
return nil
}
-func (s *storageZfs) doSnapshotBackup(tmpPath string, backup backup.Backup, source Instance, parentSnapshot string) error {
+func (s *storageZfs) doSnapshotBackup(tmpPath string, backup backup.Backup, source instance.Instance, parentSnapshot string) error {
sourceName := source.Name()
snapshotsPath := fmt.Sprintf("%s/snapshots", tmpPath)
@@ -1922,7 +1934,7 @@ func (s *storageZfs) doSnapshotBackup(tmpPath string, backup backup.Backup, sour
return zfsSendCmd.Run()
}
-func (s *storageZfs) doContainerBackupCreateOptimized(tmpPath string, backup backup.Backup, source Instance) error {
+func (s *storageZfs) doContainerBackupCreateOptimized(tmpPath string, backup backup.Backup, source instance.Instance) error {
// Handle snapshots
snapshots, err := source.Snapshots()
if err != nil {
@@ -1991,7 +2003,7 @@ func (s *storageZfs) doContainerBackupCreateOptimized(tmpPath string, backup bac
return nil
}
-func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backup.Backup, source Instance) error {
+func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backup.Backup, source instance.Instance) error {
// Prepare for rsync
rsync := func(oldPath string, newPath string, bwlimit string) error {
output, err := rsync.LocalCopy(oldPath, newPath, bwlimit, true)
@@ -2094,7 +2106,7 @@ func (s *storageZfs) doContainerBackupCreateVanilla(tmpPath string, backup backu
return nil
}
-func (s *storageZfs) ContainerBackupCreate(path string, backup backup.Backup, source Instance) error {
+func (s *storageZfs) ContainerBackupCreate(path string, backup backup.Backup, source instance.Instance) error {
// Generate the actual backup
if backup.OptimizedStorage() {
err := s.doContainerBackupCreateOptimized(path, backup, source)
@@ -2520,7 +2532,7 @@ func (s *storageZfs) MigrationSource(args MigrationSourceArgs) (MigrationStorage
driver := zfsMigrationSourceDriver{
instance: args.Instance,
- snapshots: []Instance{},
+ snapshots: []instance.Instance{},
zfsSnapshotNames: []string{},
zfs: s,
zfsFeatures: args.ZfsFeatures,
More information about the lxc-devel
mailing list