[lxc-devel] [lxd/master] Instance: Moves containerLXC to instance/drivers package as LXC
tomponline on Github
lxc-bot at linuxcontainers.org
Fri Feb 28 11:16:41 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200228/b3963c63/attachment-0001.bin>
-------------- next part --------------
From 47dcd2e1332fa81d7e7a4b9393684c35dfb2f929 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 15:52:50 +0000
Subject: [PATCH 01/50] lxd/instance/drivers/driver/lxc: Removes temporary lxc
placeholder
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 21 ---------------------
1 file changed, 21 deletions(-)
delete mode 100644 lxd/instance/drivers/driver_lxc.go
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
deleted file mode 100644
index 2e067a435c..0000000000
--- a/lxd/instance/drivers/driver_lxc.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package drivers
-
-import (
- "github.com/lxc/lxd/lxd/db"
- deviceConfig "github.com/lxc/lxd/lxd/device/config"
- "github.com/lxc/lxd/lxd/instance"
- "github.com/lxc/lxd/lxd/state"
- "github.com/lxc/lxd/shared/api"
-)
-
-// LXCLoad is used to link containerLXCLoad from main package, it is temporary export until such time
-// as containerLXC can be moved into this package.
-var LXCLoad func(s *state.State, args db.InstanceArgs, profiles []api.Profile) (instance.Instance, error)
-
-// LXCInstantiate is used to link containerLXCInstantiate from main package, it is temporary export until such
-// time as containerLXC can be moved into this package.
-var LXCInstantiate func(s *state.State, args db.InstanceArgs, expandedDevices deviceConfig.Devices) instance.Instance
-
-// LXCCreate is used to link containerLXCCreate from main package, it is temporary export until such time
-// as containerLXC can be moved into this package.
-var LXCCreate func(s *state.State, args db.InstanceArgs) (instance.Instance, error)
From dfa57b846f873353ea76829b5928e2716b1e16ae Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 15:53:25 +0000
Subject: [PATCH 02/50] lxd/container/lxc: Moves to instance/drivers package
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/{container_lxc.go => instance/drivers/driver_lxc.go} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename lxd/{container_lxc.go => instance/drivers/driver_lxc.go} (100%)
diff --git a/lxd/container_lxc.go b/lxd/instance/drivers/driver_lxc.go
similarity index 100%
rename from lxd/container_lxc.go
rename to lxd/instance/drivers/driver_lxc.go
From 3a1c543427738f94a5451b968126554525bc6c56 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 16:08:15 +0000
Subject: [PATCH 03/50] lxd/container/lxc/exec/cmd: Moves to instance/drivers
package
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
.../drivers/driver_lxc_cmd.go} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename lxd/{container_lxc_exec_cmd.go => instance/drivers/driver_lxc_cmd.go} (100%)
diff --git a/lxd/container_lxc_exec_cmd.go b/lxd/instance/drivers/driver_lxc_cmd.go
similarity index 100%
rename from lxd/container_lxc_exec_cmd.go
rename to lxd/instance/drivers/driver_lxc_cmd.go
From 9d82b17a2775186ff6dea270442b010808005946 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:39:30 +0000
Subject: [PATCH 04/50] lxd/instance/drivers/driver/utils: Adds
SetupSharedMounts function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_utils.go | 46 ++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 lxd/instance/drivers/driver_utils.go
diff --git a/lxd/instance/drivers/driver_utils.go b/lxd/instance/drivers/driver_utils.go
new file mode 100644
index 0000000000..283fd24b10
--- /dev/null
+++ b/lxd/instance/drivers/driver_utils.go
@@ -0,0 +1,46 @@
+package drivers
+
+import (
+ "sync"
+
+ "golang.org/x/sys/unix"
+
+ "github.com/lxc/lxd/shared"
+)
+
+// have we setup shared mounts?
+var sharedMounted bool
+var sharedMountsLock sync.Mutex
+
+// SetupSharedMounts sets up shared mounts.
+func SetupSharedMounts() error {
+ // Check if we already went through this
+ if sharedMounted {
+ return nil
+ }
+
+ // Get a lock to prevent races
+ sharedMountsLock.Lock()
+ defer sharedMountsLock.Unlock()
+
+ // Check if already setup
+ path := shared.VarPath("shmounts")
+ if shared.IsMountPoint(path) {
+ sharedMounted = true
+ return nil
+ }
+
+ // Mount a new tmpfs
+ if err := unix.Mount("tmpfs", path, "tmpfs", 0, "size=100k,mode=0711"); err != nil {
+ return err
+ }
+
+ // Mark as MS_SHARED and MS_REC
+ var flags uintptr = unix.MS_SHARED | unix.MS_REC
+ if err := unix.Mount(path, path, "none", flags, ""); err != nil {
+ return err
+ }
+
+ sharedMounted = true
+ return nil
+}
From 29c6701690cc448199904fb100fa1bf48bb13ba3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:39:52 +0000
Subject: [PATCH 05/50] lxd/api/internal: instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/api_internal.go | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 9d1dab7c1a..a8a9a04bf5 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -22,6 +22,7 @@ import (
"github.com/lxc/lxd/lxd/db/query"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/response"
@@ -135,7 +136,7 @@ func internalContainerOnStart(d *Daemon, r *http.Request) response.Response {
return response.SmartError(fmt.Errorf("Instance is not container type"))
}
- c := inst.(*containerLXC)
+ c := inst.(*instanceDrivers.LXC)
err = c.OnStart()
if err != nil {
logger.Error("The start hook failed", log.Ctx{"container": c.Name(), "err": err})
@@ -166,7 +167,7 @@ func internalContainerOnStopNS(d *Daemon, r *http.Request) response.Response {
return response.SmartError(fmt.Errorf("Instance is not container type"))
}
- c := inst.(*containerLXC)
+ c := inst.(*instanceDrivers.LXC)
err = c.OnStopNS(target, netns)
if err != nil {
logger.Error("The stopns hook failed", log.Ctx{"container": c.Name(), "err": err})
@@ -196,7 +197,7 @@ func internalContainerOnStop(d *Daemon, r *http.Request) response.Response {
return response.SmartError(fmt.Errorf("Instance is not container type"))
}
- c := inst.(*containerLXC)
+ c := inst.(*instanceDrivers.LXC)
err = c.OnStop(target)
if err != nil {
logger.Error("The stop hook failed", log.Ctx{"container": c.Name(), "err": err})
From efec58877bfcd643dcf98492dbdab84fba10c354 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:40:23 +0000
Subject: [PATCH 06/50] lxd/container: instanceDrivers.CriuMigrationArgs usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container.go | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/lxd/container.go b/lxd/container.go
index 4b521fbef0..68c3cce7e7 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -21,6 +21,7 @@ import (
"github.com/lxc/lxd/lxd/db"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/state"
@@ -384,14 +385,14 @@ func instanceCreateAsSnapshot(s *state.State, args db.InstanceArgs, sourceInstan
* after snapshotting will fail.
*/
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_DUMP,
- stateDir: stateDir,
- function: "snapshot",
- stop: false,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
+ criuMigrationArgs := instanceDrivers.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_DUMP,
+ StateDir: stateDir,
+ Function: "snapshot",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
c := sourceInstance.(*containerLXC)
From a52ffbfa83f4698065080e4102efaad603db378b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:40:33 +0000
Subject: [PATCH 07/50] lxd/container: instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/container.go b/lxd/container.go
index 68c3cce7e7..e02d4d1138 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -395,7 +395,7 @@ func instanceCreateAsSnapshot(s *state.State, args db.InstanceArgs, sourceInstan
PreDumpDir: "",
}
- c := sourceInstance.(*containerLXC)
+ c := sourceInstance.(*instanceDrivers.LXC)
err = c.Migrate(&criuMigrationArgs)
if err != nil {
os.RemoveAll(sourceInstance.StatePath())
From 611098665d306c4a79671649f826bdeb30d589f3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:41:00 +0000
Subject: [PATCH 08/50] lxd/container/console: instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_console.go | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lxd/container_console.go b/lxd/container_console.go
index e461a9f7ff..a3648eb099 100644
--- a/lxd/container_console.go
+++ b/lxd/container_console.go
@@ -17,6 +17,7 @@ import (
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/response"
@@ -354,7 +355,7 @@ func containerConsoleLogGet(d *Daemon, r *http.Request) response.Response {
return response.SmartError(fmt.Errorf("Instance is not container type"))
}
- c := inst.(*containerLXC)
+ c := inst.(*instanceDrivers.LXC)
ent := response.FileResponseEntry{}
if !c.IsRunning() {
// Hand back the contents of the console ringbuffer logfile.
@@ -408,7 +409,7 @@ func containerConsoleLogDelete(d *Daemon, r *http.Request) response.Response {
return response.SmartError(fmt.Errorf("Instance is not container type"))
}
- c := inst.(*containerLXC)
+ c := inst.(*instanceDrivers.LXC)
truncateConsoleLogFile := func(path string) error {
// Check that this is a regular file. We don't want to try and unlink
From 14ba261f1cdd90e819b8dd20016e5d7e2bf0c287 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:41:18 +0000
Subject: [PATCH 09/50] lxd/container/exec: instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_exec.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index 2302ee54b3..161ace4958 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -18,6 +18,7 @@ import (
"github.com/lxc/lxd/lxd/cluster"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/response"
@@ -426,7 +427,7 @@ func containerExecPost(d *Daemon, r *http.Request) response.Response {
ws.fds = map[int]string{}
if inst.Type() == instancetype.Container {
- c := inst.(*containerLXC)
+ c := inst.(*instanceDrivers.LXC)
idmapset, err := c.CurrentIdmap()
if err != nil {
return response.InternalError(err)
From a6fafdbdada5c7d92d6317064106bfd9b21c997d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:41:40 +0000
Subject: [PATCH 10/50] lxd/container/lxc/utils: Removes idmapsetFromString
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_lxc_utils.go | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/lxd/container_lxc_utils.go b/lxd/container_lxc_utils.go
index 9da660f398..7ea2afea2b 100644
--- a/lxd/container_lxc_utils.go
+++ b/lxd/container_lxc_utils.go
@@ -6,20 +6,6 @@ import (
"github.com/lxc/lxd/shared/idmap"
)
-func idmapsetFromString(idmapString string) (*idmap.IdmapSet, error) {
- lastIdmap := new(idmap.IdmapSet)
- err := json.Unmarshal([]byte(idmapString), &lastIdmap.Idmap)
- if err != nil {
- return nil, err
- }
-
- if len(lastIdmap.Idmap) == 0 {
- return nil, nil
- }
-
- return lastIdmap, nil
-}
-
func idmapsetToJSON(idmapSet *idmap.IdmapSet) (string, error) {
idmapBytes, err := json.Marshal(idmapSet.Idmap)
if err != nil {
From 28a7035c11407ea4ef50909152eb84d3806e9737 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:42:04 +0000
Subject: [PATCH 11/50] lxd/container/test: instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_test.go | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/lxd/container_test.go b/lxd/container_test.go
index 5fbfd96403..41335c5d90 100644
--- a/lxd/container_test.go
+++ b/lxd/container_test.go
@@ -142,10 +142,10 @@ func (suite *containerTestSuite) TestContainer_LoadFromDB() {
suite.Req.Nil(err)
// When loading from DB, we won't have a full LXC config
- c.(*containerLXC).c = nil
- c.(*containerLXC).cConfig = false
- c2.(*containerLXC).c = nil
- c2.(*containerLXC).cConfig = false
+ c.(*instanceDrivers.LXC).c = nil
+ c.(*instanceDrivers.LXC).cConfig = false
+ c2.(*instanceDrivers.LXC).c = nil
+ c2.(*instanceDrivers.LXC).cConfig = false
suite.Exactly(
c,
@@ -250,9 +250,9 @@ func (suite *containerTestSuite) TestContainer_findIdmap_isolated() {
suite.Req.Nil(err)
defer c2.Delete()
- map1, err := c1.(*containerLXC).NextIdmap()
+ map1, err := c1.(*instanceDrivers.LXC).NextIdmap()
suite.Req.Nil(err)
- map2, err := c2.(*containerLXC).NextIdmap()
+ map2, err := c2.(*instanceDrivers.LXC).NextIdmap()
suite.Req.Nil(err)
host := suite.d.os.IdmapSet.Idmap[0]
@@ -291,9 +291,9 @@ func (suite *containerTestSuite) TestContainer_findIdmap_mixed() {
suite.Req.Nil(err)
defer c2.Delete()
- map1, err := c1.(*containerLXC).NextIdmap()
+ map1, err := c1.(*instanceDrivers.LXC).NextIdmap()
suite.Req.Nil(err)
- map2, err := c2.(*containerLXC).NextIdmap()
+ map2, err := c2.(*instanceDrivers.LXC).NextIdmap()
suite.Req.Nil(err)
host := suite.d.os.IdmapSet.Idmap[0]
@@ -323,7 +323,7 @@ func (suite *containerTestSuite) TestContainer_findIdmap_raw() {
suite.Req.Nil(err)
defer c1.Delete()
- map1, err := c1.(*containerLXC).NextIdmap()
+ map1, err := c1.(*instanceDrivers.LXC).NextIdmap()
suite.Req.Nil(err)
host := suite.d.os.IdmapSet.Idmap[0]
@@ -369,7 +369,7 @@ func (suite *containerTestSuite) TestContainer_findIdmap_maxed() {
defer c.Delete()
- m, err := c.(*containerLXC).NextIdmap()
+ m, err := c.(*instanceDrivers.LXC).NextIdmap()
suite.Req.Nil(err)
maps = append(maps, m)
From 1dc48f2bf3958401de6c3210880e8f82ef73a22d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:42:30 +0000
Subject: [PATCH 12/50] lxd/daemon: instanceDrivers.SetupSharedMounts usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/daemon.go | 39 ++-------------------------------------
1 file changed, 2 insertions(+), 37 deletions(-)
diff --git a/lxd/daemon.go b/lxd/daemon.go
index acb1e4eb8e..414133db0a 100644
--- a/lxd/daemon.go
+++ b/lxd/daemon.go
@@ -36,6 +36,7 @@ import (
"github.com/lxc/lxd/lxd/events"
"github.com/lxc/lxd/lxd/firewall"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/maas"
"github.com/lxc/lxd/lxd/node"
@@ -483,42 +484,6 @@ func (d *Daemon) createCmd(restAPI *mux.Router, version string, c APIEndpoint) {
}
}
-// have we setup shared mounts?
-var sharedMounted bool
-var sharedMountsLock sync.Mutex
-
-func setupSharedMounts() error {
- // Check if we already went through this
- if sharedMounted {
- return nil
- }
-
- // Get a lock to prevent races
- sharedMountsLock.Lock()
- defer sharedMountsLock.Unlock()
-
- // Check if already setup
- path := shared.VarPath("shmounts")
- if shared.IsMountPoint(path) {
- sharedMounted = true
- return nil
- }
-
- // Mount a new tmpfs
- if err := unix.Mount("tmpfs", path, "tmpfs", 0, "size=100k,mode=0711"); err != nil {
- return err
- }
-
- // Mark as MS_SHARED and MS_REC
- var flags uintptr = unix.MS_SHARED | unix.MS_REC
- if err := unix.Mount(path, path, "none", flags, ""); err != nil {
- return err
- }
-
- sharedMounted = true
- return nil
-}
-
func (d *Daemon) Init() error {
err := d.init()
@@ -687,7 +652,7 @@ func (d *Daemon) init() error {
/* Setup some mounts (nice to have) */
if !d.os.MockMode {
// Attempt to mount the shmounts tmpfs
- setupSharedMounts()
+ instanceDrivers.SetupSharedMounts()
// Attempt to Mount the devlxd tmpfs
devlxd := filepath.Join(d.os.VarDir, "devlxd")
From 99fcc06b826d4f904cf330a3e35552db09262411 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:42:47 +0000
Subject: [PATCH 13/50] lxd/devices: inst.RegisterDevices usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/devices.go | 32 ++++----------------------------
1 file changed, 4 insertions(+), 28 deletions(-)
diff --git a/lxd/devices.go b/lxd/devices.go
index 4ce79fa9ae..dd7c523bab 100644
--- a/lxd/devices.go
+++ b/lxd/devices.go
@@ -560,40 +560,16 @@ func deviceEventListener(s *state.State) {
func devicesRegister(s *state.State) {
instances, err := instance.LoadNodeAll(s, instancetype.Container)
if err != nil {
- logger.Error("Problem loading containers list", log.Ctx{"err": err})
+ logger.Error("Problem loading instances list", log.Ctx{"err": err})
return
}
- for _, instanceIf := range instances {
- c, ok := instanceIf.(*containerLXC)
- if !ok {
- logger.Errorf("Instance is not container type")
+ for _, inst := range instances {
+ if !inst.IsRunning() {
continue
}
- if !c.IsRunning() {
- continue
- }
-
- devices := c.ExpandedDevices()
- for _, dev := range devices.Sorted() {
- d, _, err := c.deviceLoad(dev.Name, dev.Config)
- if err == device.ErrUnsupportedDevType {
- continue
- }
-
- if err != nil {
- logger.Error("Failed to load device to register", log.Ctx{"err": err, "container": c.Name(), "device": dev.Name})
- continue
- }
-
- // Check whether device wants to register for any events.
- err = d.Register()
- if err != nil {
- logger.Error("Failed to register device", log.Ctx{"err": err, "container": c.Name(), "device": dev.Name})
- continue
- }
- }
+ inst.RegisterDevices()
}
}
From 9cfccd7c99b45c4ca92cf86855b7a544a4f61b0f Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:43:10 +0000
Subject: [PATCH 14/50] lxd/devlxd: Removes devlxdEventSend
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/devlxd.go | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/lxd/devlxd.go b/lxd/devlxd.go
index f56c2e234c..7eb41c9e98 100644
--- a/lxd/devlxd.go
+++ b/lxd/devlxd.go
@@ -12,7 +12,6 @@ import (
"strconv"
"strings"
"sync"
- "time"
"unsafe"
"github.com/gorilla/mux"
@@ -151,15 +150,6 @@ var devlxdEventsGet = devLxdHandler{"/1.0/events", func(d *Daemon, c instance.In
return &devLxdResponse{"websocket", http.StatusOK, "websocket"}
}}
-func devlxdEventSend(c instance.Instance, eventType string, eventMessage interface{}) error {
- event := shared.Jmap{}
- event["type"] = eventType
- event["timestamp"] = time.Now()
- event["metadata"] = eventMessage
-
- return c.DaemonState().DevlxdEvents.Send(strconv.Itoa(c.ID()), eventType, eventMessage)
-}
-
var handlers = []devLxdHandler{
{"/", func(d *Daemon, c instance.Instance, w http.ResponseWriter, r *http.Request) *devLxdResponse {
return okResponse([]string{"/1.0"}, "json")
From 6739a63289f25c13d3cb98eeccf5040b91000bd3 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:43:28 +0000
Subject: [PATCH 15/50] lxd/devlxd: instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/devlxd.go | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lxd/devlxd.go b/lxd/devlxd.go
index 7eb41c9e98..11f67e8a63 100644
--- a/lxd/devlxd.go
+++ b/lxd/devlxd.go
@@ -18,6 +18,7 @@ import (
"github.com/lxc/lxd/lxd/daemon"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/state"
@@ -308,7 +309,7 @@ func extractUnderlyingConn(w http.ResponseWriter) *net.UnixConn {
var pidNotInContainerErr = fmt.Errorf("pid not in container?")
-func findContainerForPid(pid int32, s *state.State) (*containerLXC, error) {
+func findContainerForPid(pid int32, s *state.State) (*instanceDrivers.LXC, error) {
/*
* Try and figure out which container a pid is in. There is probably a
* better way to do this. Based on rharper's initial performance
@@ -355,7 +356,7 @@ func findContainerForPid(pid int32, s *state.State) (*containerLXC, error) {
return nil, fmt.Errorf("Instance is not container type")
}
- c := inst.(*containerLXC)
+ c := inst.(*instanceDrivers.LXC)
return c, nil
}
@@ -405,7 +406,7 @@ func findContainerForPid(pid int32, s *state.State) (*containerLXC, error) {
}
if origPidNs == pidNs {
- return inst.(*containerLXC), nil
+ return inst.(*instanceDrivers.LXC), nil
}
}
From b7d9644237a663408f6abb1a7d9e78674298576d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:49:40 +0000
Subject: [PATCH 16/50] lxd/instance/drivers/driver/lxc: Renames containerLXC
to LXC
Requires uppercase LXC so it is exported as some other parts of the codebase still need to access this type directly.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 300 ++++++++++++++---------------
1 file changed, 144 insertions(+), 156 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 032dfca40d..174cbd16e4 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -1,4 +1,4 @@
-package main
+package drivers
import (
"bufio"
@@ -34,7 +34,6 @@ import (
"github.com/lxc/lxd/lxd/device"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
- instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/instance/operationlock"
"github.com/lxc/lxd/lxd/maas"
@@ -147,9 +146,9 @@ func lxcStatusCode(state lxc.State) api.StatusCode {
}
// Loader functions
-func containerLXCCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
+func lxcCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
// Create the container struct
- c := &containerLXC{
+ c := &LXC{
state: s,
id: args.ID,
project: args.Project,
@@ -354,20 +353,20 @@ func containerLXCCreate(s *state.State, args db.InstanceArgs) (instance.Instance
return c, nil
}
-func containerLXCLoad(s *state.State, args db.InstanceArgs, profiles []api.Profile) (instance.Instance, error) {
+func lxcLoad(s *state.State, args db.InstanceArgs, profiles []api.Profile) (instance.Instance, error) {
// Create the container struct
- c := containerLXCInstantiate(s, args, nil)
+ c := lxcInstantiate(s, args, nil)
// Setup finalizer
- runtime.SetFinalizer(c, containerLXCUnload)
+ runtime.SetFinalizer(c, lxcUnload)
// Expand config and devices
- err := c.(*containerLXC).expandConfig(profiles)
+ err := c.(*LXC).expandConfig(profiles)
if err != nil {
return nil, err
}
- err = c.(*containerLXC).expandDevices(profiles)
+ err = c.(*LXC).expandDevices(profiles)
if err != nil {
return nil, err
}
@@ -376,7 +375,7 @@ func containerLXCLoad(s *state.State, args db.InstanceArgs, profiles []api.Profi
}
// Unload is called by the garbage collector
-func containerLXCUnload(c *containerLXC) {
+func lxcUnload(c *LXC) {
runtime.SetFinalizer(c, nil)
if c.c != nil {
c.c.Release()
@@ -385,8 +384,8 @@ func containerLXCUnload(c *containerLXC) {
}
// Create a container struct without initializing it.
-func containerLXCInstantiate(s *state.State, args db.InstanceArgs, expandedDevices deviceConfig.Devices) instance.Instance {
- c := &containerLXC{
+func lxcInstantiate(s *state.State, args db.InstanceArgs, expandedDevices deviceConfig.Devices) instance.Instance {
+ c := &LXC{
state: s,
id: args.ID,
project: args.Project,
@@ -428,7 +427,7 @@ func containerLXCInstantiate(s *state.State, args db.InstanceArgs, expandedDevic
}
// The LXC container driver
-type containerLXC struct {
+type LXC struct {
// Properties
architecture int
dbType instancetype.Type
@@ -471,7 +470,7 @@ type containerLXC struct {
expiryDate time.Time
}
-func (c *containerLXC) Type() instancetype.Type {
+func (c *LXC) Type() instancetype.Type {
return c.dbType
}
@@ -659,7 +658,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
return nil, 0, fmt.Errorf("Not enough uid/gid available for the container")
}
-func (c *containerLXC) init() error {
+func (c *LXC) init() error {
// Compute the expanded config and device list
err := c.expandConfig(nil)
if err != nil {
@@ -674,7 +673,7 @@ func (c *containerLXC) init() error {
return nil
}
-func (c *containerLXC) initLXC(config bool) error {
+func (c *LXC) initLXC(config bool) error {
// No need to go through all that for snapshots
if c.IsSnapshot() {
return nil
@@ -1273,7 +1272,7 @@ func (c *containerLXC) initLXC(config bool) error {
}
// runHooks executes the callback functions returned from a function.
-func (c *containerLXC) runHooks(hooks []func() error) error {
+func (c *LXC) runHooks(hooks []func() error) error {
// Run any post start hooks.
if len(hooks) > 0 {
for _, hook := range hooks {
@@ -1288,7 +1287,7 @@ func (c *containerLXC) runHooks(hooks []func() error) error {
}
// deviceLoad instantiates and validates a new device and returns it along with enriched config.
-func (c *containerLXC) deviceLoad(deviceName string, rawConfig deviceConfig.Device) (device.Device, deviceConfig.Device, error) {
+func (c *LXC) deviceLoad(deviceName string, rawConfig deviceConfig.Device) (device.Device, deviceConfig.Device, error) {
var configCopy deviceConfig.Device
var err error
@@ -1310,7 +1309,7 @@ func (c *containerLXC) deviceLoad(deviceName string, rawConfig deviceConfig.Devi
}
// deviceAdd loads a new device and calls its Add() function.
-func (c *containerLXC) deviceAdd(deviceName string, rawConfig deviceConfig.Device) error {
+func (c *LXC) deviceAdd(deviceName string, rawConfig deviceConfig.Device) error {
d, _, err := c.deviceLoad(deviceName, rawConfig)
if err != nil {
return err
@@ -1322,7 +1321,7 @@ func (c *containerLXC) deviceAdd(deviceName string, rawConfig deviceConfig.Devic
// deviceStart loads a new device and calls its Start() function. After processing the runtime
// config returned from Start(), it also runs the device's Register() function irrespective of
// whether the container is running or not.
-func (c *containerLXC) deviceStart(deviceName string, rawConfig deviceConfig.Device, isRunning bool) (*deviceConfig.RunConfig, error) {
+func (c *LXC) deviceStart(deviceName string, rawConfig deviceConfig.Device, isRunning bool) (*deviceConfig.RunConfig, error) {
d, configCopy, err := c.deviceLoad(deviceName, rawConfig)
if err != nil {
return nil, err
@@ -1387,7 +1386,7 @@ func (c *containerLXC) deviceStart(deviceName string, rawConfig deviceConfig.Dev
}
// deviceStaticShiftMounts statically shift device mount files ownership to active idmap if needed.
-func (c *containerLXC) deviceStaticShiftMounts(mounts []deviceConfig.MountEntryItem) error {
+func (c *LXC) deviceStaticShiftMounts(mounts []deviceConfig.MountEntryItem) error {
idmapSet, err := c.CurrentIdmap()
if err != nil {
return fmt.Errorf("Failed to get idmap for device: %s", err)
@@ -1415,7 +1414,7 @@ func (c *containerLXC) deviceStaticShiftMounts(mounts []deviceConfig.MountEntryI
}
// deviceAddCgroupRules live adds cgroup rules to a container.
-func (c *containerLXC) deviceAddCgroupRules(cgroups []deviceConfig.RunConfigItem) error {
+func (c *LXC) deviceAddCgroupRules(cgroups []deviceConfig.RunConfigItem) error {
cg, err := c.cgroup(nil)
if err != nil {
return err
@@ -1438,7 +1437,7 @@ func (c *containerLXC) deviceAddCgroupRules(cgroups []deviceConfig.RunConfigItem
}
// deviceAttachNIC live attaches a NIC device to a container.
-func (c *containerLXC) deviceAttachNIC(configCopy map[string]string, netIF []deviceConfig.RunConfigItem) error {
+func (c *LXC) deviceAttachNIC(configCopy map[string]string, netIF []deviceConfig.RunConfigItem) error {
devName := ""
for _, dev := range netIF {
if dev.Key == "link" {
@@ -1467,7 +1466,7 @@ func (c *containerLXC) deviceAttachNIC(configCopy map[string]string, netIF []dev
}
// deviceUpdate loads a new device and calls its Update() function.
-func (c *containerLXC) deviceUpdate(deviceName string, rawConfig deviceConfig.Device, oldDevices deviceConfig.Devices, isRunning bool) error {
+func (c *LXC) deviceUpdate(deviceName string, rawConfig deviceConfig.Device, oldDevices deviceConfig.Devices, isRunning bool) error {
d, _, err := c.deviceLoad(deviceName, rawConfig)
if err != nil {
return err
@@ -1482,7 +1481,7 @@ func (c *containerLXC) deviceUpdate(deviceName string, rawConfig deviceConfig.De
}
// deviceStop loads a new device and calls its Stop() function.
-func (c *containerLXC) deviceStop(deviceName string, rawConfig deviceConfig.Device, stopHookNetnsPath string) error {
+func (c *LXC) deviceStop(deviceName string, rawConfig deviceConfig.Device, stopHookNetnsPath string) error {
d, configCopy, err := c.deviceLoad(deviceName, rawConfig)
// If deviceLoad fails with unsupported device type then return.
@@ -1551,7 +1550,7 @@ func (c *containerLXC) deviceStop(deviceName string, rawConfig deviceConfig.Devi
}
// deviceDetachNIC detaches a NIC device from a container.
-func (c *containerLXC) deviceDetachNIC(configCopy map[string]string, netIF []deviceConfig.RunConfigItem, stopHookNetnsPath string) error {
+func (c *LXC) deviceDetachNIC(configCopy map[string]string, netIF []deviceConfig.RunConfigItem, stopHookNetnsPath string) error {
// Get requested device name to detach interface back to on the host.
devName := ""
for _, dev := range netIF {
@@ -1612,7 +1611,7 @@ func (c *containerLXC) deviceDetachNIC(configCopy map[string]string, netIF []dev
// deviceHandleMounts live attaches or detaches mounts on a container.
// If the mount DevPath is empty the mount action is treated as unmount.
-func (c *containerLXC) deviceHandleMounts(mounts []deviceConfig.MountEntryItem) error {
+func (c *LXC) deviceHandleMounts(mounts []deviceConfig.MountEntryItem) error {
for _, mount := range mounts {
if mount.DevPath != "" {
flags := 0
@@ -1659,7 +1658,7 @@ func (c *containerLXC) deviceHandleMounts(mounts []deviceConfig.MountEntryItem)
}
// deviceRemove loads a new device and calls its Remove() function.
-func (c *containerLXC) deviceRemove(deviceName string, rawConfig deviceConfig.Device) error {
+func (c *LXC) deviceRemove(deviceName string, rawConfig deviceConfig.Device) error {
d, _, err := c.deviceLoad(deviceName, rawConfig)
// If deviceLoad fails with unsupported device type then return.
@@ -1679,7 +1678,7 @@ func (c *containerLXC) deviceRemove(deviceName string, rawConfig deviceConfig.De
// deviceVolatileGetFunc returns a function that retrieves a named device's volatile config and
// removes its device prefix from the keys.
-func (c *containerLXC) deviceVolatileGetFunc(devName string) func() map[string]string {
+func (c *LXC) deviceVolatileGetFunc(devName string) func() map[string]string {
return func() map[string]string {
volatile := make(map[string]string)
prefix := fmt.Sprintf("volatile.%s.", devName)
@@ -1694,7 +1693,7 @@ func (c *containerLXC) deviceVolatileGetFunc(devName string) func() map[string]s
// deviceVolatileSetFunc returns a function that can be called to save a named device's volatile
// config using keys that do not have the device's name prefixed.
-func (c *containerLXC) deviceVolatileSetFunc(devName string) func(save map[string]string) error {
+func (c *LXC) deviceVolatileSetFunc(devName string) func(save map[string]string) error {
return func(save map[string]string) error {
volatileSave := make(map[string]string)
for k, v := range save {
@@ -1707,7 +1706,7 @@ func (c *containerLXC) deviceVolatileSetFunc(devName string) func(save map[strin
// deviceResetVolatile resets a device's volatile data when its removed or updated in such a way
// that it is removed then added immediately afterwards.
-func (c *containerLXC) deviceResetVolatile(devName string, oldConfig, newConfig deviceConfig.Device) error {
+func (c *LXC) deviceResetVolatile(devName string, oldConfig, newConfig deviceConfig.Device) error {
volatileClear := make(map[string]string)
devicePrefix := fmt.Sprintf("volatile.%s.", devName)
@@ -1744,7 +1743,7 @@ func (c *containerLXC) deviceResetVolatile(devName string, oldConfig, newConfig
}
// DeviceEventHandler actions the results of a RunConfig after an event has occurred on a device.
-func (c *containerLXC) DeviceEventHandler(runConf *deviceConfig.RunConfig) error {
+func (c *LXC) DeviceEventHandler(runConf *deviceConfig.RunConfig) error {
// Device events can only be processed when the container is running.
if !c.IsRunning() {
return nil
@@ -1805,7 +1804,7 @@ func (c *containerLXC) DeviceEventHandler(runConf *deviceConfig.RunConfig) error
}
// Config handling
-func (c *containerLXC) expandConfig(profiles []api.Profile) error {
+func (c *LXC) expandConfig(profiles []api.Profile) error {
if profiles == nil && len(c.profiles) > 0 {
var err error
profiles, err = c.state.Cluster.ProfilesGet(c.project, c.profiles)
@@ -1819,7 +1818,7 @@ func (c *containerLXC) expandConfig(profiles []api.Profile) error {
return nil
}
-func (c *containerLXC) expandDevices(profiles []api.Profile) error {
+func (c *LXC) expandDevices(profiles []api.Profile) error {
if profiles == nil && len(c.profiles) > 0 {
var err error
profiles, err = c.state.Cluster.ProfilesGet(c.project, c.profiles)
@@ -1884,7 +1883,7 @@ func UnshiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
}
// Start functions
-func (c *containerLXC) startCommon() (string, []func() error, error) {
+func (c *LXC) startCommon() (string, []func() error, error) {
var ourStart bool
postStartHooks := []func() error{}
@@ -2245,7 +2244,7 @@ func (c *containerLXC) startCommon() (string, []func() error, error) {
// detachInterfaceRename enters the container's network namespace and moves the named interface
// in ifName back to the network namespace of the running process as the name specified in hostName.
-func (c *containerLXC) detachInterfaceRename(netns string, ifName string, hostName string) error {
+func (c *LXC) detachInterfaceRename(netns string, ifName string, hostName string) error {
lxdPID := os.Getpid()
// Run forknet detach
@@ -2267,7 +2266,7 @@ func (c *containerLXC) detachInterfaceRename(netns string, ifName string, hostNa
return nil
}
-func (c *containerLXC) Start(stateful bool) error {
+func (c *LXC) Start(stateful bool) error {
var ctxMap log.Ctx
// Setup a new operation
@@ -2419,7 +2418,7 @@ func (c *containerLXC) Start(stateful bool) error {
return nil
}
-func (c *containerLXC) OnStart() error {
+func (c *LXC) OnStart() error {
// Make sure we can't call go-lxc functions by mistake
c.fromHook = true
@@ -2476,7 +2475,7 @@ func (c *containerLXC) OnStart() error {
// Apply network priority
if c.expandedConfig["limits.network.priority"] != "" {
- go func(c *containerLXC) {
+ go func(c *LXC) {
c.fromHook = false
err := c.setNetworkPriority()
if err != nil {
@@ -2509,7 +2508,7 @@ func (c *containerLXC) OnStart() error {
}
// Stop functions
-func (c *containerLXC) Stop(stateful bool) error {
+func (c *LXC) Stop(stateful bool) error {
var ctxMap log.Ctx
// Check that we're not already stopped
@@ -2650,7 +2649,7 @@ func (c *containerLXC) Stop(stateful bool) error {
return nil
}
-func (c *containerLXC) Shutdown(timeout time.Duration) error {
+func (c *LXC) Shutdown(timeout time.Duration) error {
var ctxMap log.Ctx
// Check that we're not already stopped
@@ -2713,7 +2712,7 @@ func (c *containerLXC) Shutdown(timeout time.Duration) error {
// OnStopNS is triggered by LXC's stop hook once a container is shutdown but before the container's
// namespaces have been closed. The netns path of the stopped container is provided.
-func (c *containerLXC) OnStopNS(target string, netns string) error {
+func (c *LXC) OnStopNS(target string, netns string) error {
// Validate target
if !shared.StringInSlice(target, []string{"stop", "reboot"}) {
logger.Error("Container sent invalid target to OnStopNS", log.Ctx{"container": c.Name(), "target": target})
@@ -2728,7 +2727,7 @@ func (c *containerLXC) OnStopNS(target string, netns string) error {
// OnStop is triggered by LXC's post-stop hook once a container is shutdown and after the
// container's namespaces have been closed.
-func (c *containerLXC) OnStop(target string) error {
+func (c *LXC) OnStop(target string) error {
// Validate target
if !shared.StringInSlice(target, []string{"stop", "reboot"}) {
logger.Error("Container sent invalid target to OnStop", log.Ctx{"container": c.Name(), "target": target})
@@ -2793,7 +2792,7 @@ func (c *containerLXC) OnStop(target string) error {
logger.Error("Failed to set container state", log.Ctx{"container": c.Name(), "err": err})
}
- go func(c *containerLXC, target string, op *operationlock.InstanceOperation) {
+ go func(c *LXC, target string, op *operationlock.InstanceOperation) {
c.fromHook = false
err = nil
@@ -2843,7 +2842,7 @@ func (c *containerLXC) OnStop(target string) error {
}
// cleanupDevices performs any needed device cleanup steps when container is stopped.
-func (c *containerLXC) cleanupDevices(netns string) {
+func (c *LXC) cleanupDevices(netns string) {
for _, dev := range c.expandedDevices.Sorted() {
// Use the device interface if device supports it.
err := c.deviceStop(dev.Name, dev.Config, netns)
@@ -2856,7 +2855,7 @@ func (c *containerLXC) cleanupDevices(netns string) {
}
// Freezer functions
-func (c *containerLXC) Freeze() error {
+func (c *LXC) Freeze() error {
ctxMap := log.Ctx{
"project": c.project,
"name": c.name,
@@ -2909,7 +2908,7 @@ func (c *containerLXC) Freeze() error {
return err
}
-func (c *containerLXC) Unfreeze() error {
+func (c *LXC) Unfreeze() error {
ctxMap := log.Ctx{
"project": c.project,
"name": c.name,
@@ -2963,7 +2962,7 @@ var LxcMonitorStateError = fmt.Errorf("Monitor is hung")
// Get lxc container state, with 1 second timeout
// If we don't get a reply, assume the lxc monitor is hung
-func (c *containerLXC) getLxcState() (lxc.State, error) {
+func (c *LXC) getLxcState() (liblxc.State, error) {
if c.IsSnapshot() {
return lxc.StateMap["STOPPED"], nil
}
@@ -2984,11 +2983,11 @@ func (c *containerLXC) getLxcState() (lxc.State, error) {
case state := <-monitor:
return state, nil
case <-time.After(5 * time.Second):
- return lxc.StateMap["FROZEN"], LxcMonitorStateError
+ return liblxc.StateMap["FROZEN"], LxcMonitorStateError
}
}
-func (c *containerLXC) Render() (interface{}, interface{}, error) {
+func (c *LXC) Render() (interface{}, interface{}, error) {
// Ignore err as the arch string on error is correct (unknown)
architectureName, _ := osarch.ArchitectureName(c.architecture)
@@ -3047,7 +3046,7 @@ func (c *containerLXC) Render() (interface{}, interface{}, error) {
return &ct, etag, nil
}
-func (c *containerLXC) RenderFull() (*api.InstanceFull, interface{}, error) {
+func (c *LXC) RenderFull() (*api.InstanceFull, interface{}, error) {
if c.IsSnapshot() {
return nil, nil, fmt.Errorf("RenderFull only works with containers")
}
@@ -3105,7 +3104,7 @@ func (c *containerLXC) RenderFull() (*api.InstanceFull, interface{}, error) {
return &ct, etag, nil
}
-func (c *containerLXC) RenderState() (*api.InstanceState, error) {
+func (c *LXC) RenderState() (*api.InstanceState, error) {
cState, err := c.getLxcState()
if err != nil {
return nil, err
@@ -3129,7 +3128,7 @@ func (c *containerLXC) RenderState() (*api.InstanceState, error) {
return &status, nil
}
-func (c *containerLXC) Snapshots() ([]instance.Instance, error) {
+func (c *LXC) Snapshots() ([]instance.Instance, error) {
var snaps []db.Instance
if c.IsSnapshot() {
@@ -3164,7 +3163,7 @@ func (c *containerLXC) Snapshots() ([]instance.Instance, error) {
return instances, nil
}
-func (c *containerLXC) Backups() ([]backup.Backup, error) {
+func (c *LXC) Backups() ([]backup.Backup, error) {
// Get all the backups
backupNames, err := c.state.Cluster.ContainerGetBackups(c.project, c.name)
if err != nil {
@@ -3186,7 +3185,7 @@ func (c *containerLXC) Backups() ([]backup.Backup, error) {
}
// Restore restores a snapshot.
-func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool) error {
+func (c *LXC) Restore(sourceContainer instance.Instance, stateful bool) error {
var ctxMap log.Ctx
// Initialize storage interface for the container and mount the rootfs for criu state check.
@@ -3358,7 +3357,7 @@ func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool)
return nil
}
-func (c *containerLXC) cleanup() {
+func (c *LXC) cleanup() {
// Unmount any leftovers
c.removeUnixDevices()
c.removeDiskDevices()
@@ -3374,7 +3373,7 @@ func (c *containerLXC) cleanup() {
os.RemoveAll(c.ShmountsPath())
}
-func (c *containerLXC) Delete() error {
+func (c *LXC) Delete() error {
ctxMap := log.Ctx{
"project": c.project,
"name": c.name,
@@ -3488,7 +3487,7 @@ func (c *containerLXC) Delete() error {
return nil
}
-func (c *containerLXC) Rename(newName string) error {
+func (c *LXC) Rename(newName string) error {
oldName := c.Name()
ctxMap := log.Ctx{
"project": c.project,
@@ -3634,7 +3633,7 @@ func (c *containerLXC) Rename(newName string) error {
return nil
}
-func (c *containerLXC) CGroupGet(key string) (string, error) {
+func (c *LXC) CGroupGet(key string) (string, error) {
// Load the go-lxc struct
err := c.initLXC(false)
if err != nil {
@@ -3650,7 +3649,7 @@ func (c *containerLXC) CGroupGet(key string) (string, error) {
return strings.Join(value, "\n"), nil
}
-func (c *containerLXC) CGroupSet(key string, value string) error {
+func (c *LXC) CGroupSet(key string, value string) error {
// Load the go-lxc struct
err := c.initLXC(false)
if err != nil {
@@ -3670,7 +3669,7 @@ func (c *containerLXC) CGroupSet(key string, value string) error {
return nil
}
-func (c *containerLXC) VolatileSet(changes map[string]string) error {
+func (c *LXC) VolatileSet(changes map[string]string) error {
// Sanity check
for key := range changes {
if !strings.HasPrefix(key, "volatile.") {
@@ -3708,7 +3707,7 @@ func (c *containerLXC) VolatileSet(changes map[string]string) error {
return nil
}
-func (c *containerLXC) Update(args db.InstanceArgs, userRequested bool) error {
+func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
// Set sane defaults for unset keys
if args.Project == "" {
args.Project = "default"
@@ -4431,7 +4430,7 @@ func (c *containerLXC) Update(args db.InstanceArgs, userRequested bool) error {
return nil
}
-func (c *containerLXC) updateDevices(removeDevices deviceConfig.Devices, addDevices deviceConfig.Devices, updateDevices deviceConfig.Devices, oldExpandedDevices deviceConfig.Devices) error {
+func (c *LXC) updateDevices(removeDevices deviceConfig.Devices, addDevices deviceConfig.Devices, updateDevices deviceConfig.Devices, oldExpandedDevices deviceConfig.Devices) error {
isRunning := c.IsRunning()
// Remove devices in reverse order to how they were added.
@@ -4486,7 +4485,7 @@ func (c *containerLXC) updateDevices(removeDevices deviceConfig.Devices, addDevi
return nil
}
-func (c *containerLXC) Export(w io.Writer, properties map[string]string) error {
+func (c *LXC) Export(w io.Writer, properties map[string]string) error {
ctxMap := log.Ctx{
"project": c.project,
"name": c.name,
@@ -4733,18 +4732,7 @@ func getCRIULogErrors(imagesDir string, method string) (string, error) {
return strings.Join(ret, "\n"), nil
}
-type CriuMigrationArgs struct {
- cmd uint
- stateDir string
- function string
- stop bool
- actionScript bool
- dumpDir string
- preDumpDir string
- features lxc.CriuFeatures
-}
-
-func (c *containerLXC) Migrate(args *CriuMigrationArgs) error {
+func (c *LXC) Migrate(args *CriuMigrationArgs) error {
ctxMap := log.Ctx{
"project": c.project,
"name": c.name,
@@ -4952,7 +4940,7 @@ func (c *containerLXC) Migrate(args *CriuMigrationArgs) error {
// DeferTemplateApply sets volatile key to apply template on next start. Used when instance's
// volume isn't mounted.
-func (c *containerLXC) DeferTemplateApply(trigger string) error {
+func (c *LXC) DeferTemplateApply(trigger string) error {
err := c.VolatileSet(map[string]string{"volatile.apply_template": trigger})
if err != nil {
return errors.Wrap(err, "Failed to set apply_template volatile key")
@@ -4961,7 +4949,7 @@ func (c *containerLXC) DeferTemplateApply(trigger string) error {
return nil
}
-func (c *containerLXC) templateApplyNow(trigger string) error {
+func (c *LXC) templateApplyNow(trigger string) error {
// If there's no metadata, just return
fname := filepath.Join(c.Path(), "metadata.yaml")
if !shared.PathExists(fname) {
@@ -5103,7 +5091,7 @@ func (c *containerLXC) templateApplyNow(trigger string) error {
return nil
}
-func (c *containerLXC) FileExists(path string) error {
+func (c *LXC) FileExists(path string) error {
// Setup container storage if needed
var ourStart bool
var err error
@@ -5151,7 +5139,7 @@ func (c *containerLXC) FileExists(path string) error {
return nil
}
-func (c *containerLXC) FilePull(srcpath string, dstpath string) (int64, int64, os.FileMode, string, []string, error) {
+func (c *LXC) FilePull(srcpath string, dstpath string) (int64, int64, os.FileMode, string, []string, error) {
// Check for ongoing operations (that may involve shifting).
op := operationlock.Get(c.id)
if op != nil {
@@ -5280,7 +5268,7 @@ func (c *containerLXC) FilePull(srcpath string, dstpath string) (int64, int64, o
return uid, gid, os.FileMode(mode), type_, dirEnts, nil
}
-func (c *containerLXC) FilePush(type_ string, srcpath string, dstpath string, uid int64, gid int64, mode int, write string) error {
+func (c *LXC) FilePush(type_ string, srcpath string, dstpath string, uid int64, gid int64, mode int, write string) error {
// Check for ongoing operations (that may involve shifting).
op := operationlock.Get(c.id)
if op != nil {
@@ -5376,7 +5364,7 @@ func (c *containerLXC) FilePush(type_ string, srcpath string, dstpath string, ui
return nil
}
-func (c *containerLXC) FileRemove(path string) error {
+func (c *LXC) FileRemove(path string) error {
var errStr string
var ourStart bool
var err error
@@ -5437,7 +5425,7 @@ func (c *containerLXC) FileRemove(path string) error {
return nil
}
-func (c *containerLXC) Console() (*os.File, chan error, error) {
+func (c *LXC) Console() (*os.File, chan error, error) {
chDisconnect := make(chan error, 1)
args := []string{
@@ -5490,7 +5478,7 @@ func (c *containerLXC) Console() (*os.File, chan error, error) {
return master, chDisconnect, nil
}
-func (c *containerLXC) ConsoleLog(opts lxc.ConsoleLogOptions) (string, error) {
+func (c *LXC) ConsoleLog(opts liblxc.ConsoleLogOptions) (string, error) {
msg, err := c.c.ConsoleLog(opts)
if err != nil {
return "", err
@@ -5499,7 +5487,7 @@ func (c *containerLXC) ConsoleLog(opts lxc.ConsoleLogOptions) (string, error) {
return string(msg), nil
}
-func (c *containerLXC) Exec(req api.InstanceExecPost, stdin *os.File, stdout *os.File, stderr *os.File) (instance.Cmd, error) {
+func (c *LXC) Exec(req api.InstanceExecPost, stdin *os.File, stdout *os.File, stderr *os.File) (instance.Cmd, error) {
// Prepare the environment
envSlice := []string{}
@@ -5581,7 +5569,7 @@ func (c *containerLXC) Exec(req api.InstanceExecPost, stdin *os.File, stdout *os
return nil, err
}
- instCmd := &ContainerLXCCmd{
+ instCmd := &lxcCmd{
cmd: &cmd,
attachedChildPid: attachedPid,
}
@@ -5589,7 +5577,7 @@ func (c *containerLXC) Exec(req api.InstanceExecPost, stdin *os.File, stdout *os
return instCmd, nil
}
-func (c *containerLXC) cpuState() api.InstanceStateCPU {
+func (c *LXC) cpuState() api.InstanceStateCPU {
cpu := api.InstanceStateCPU{}
// CPU usage in seconds
@@ -5619,7 +5607,7 @@ func (c *containerLXC) cpuState() api.InstanceStateCPU {
return cpu
}
-func (c *containerLXC) diskState() map[string]api.InstanceStateDisk {
+func (c *LXC) diskState() map[string]api.InstanceStateDisk {
disk := map[string]api.InstanceStateDisk{}
for _, dev := range c.expandedDevices.Sorted() {
@@ -5653,7 +5641,7 @@ func (c *containerLXC) diskState() map[string]api.InstanceStateDisk {
return disk
}
-func (c *containerLXC) memoryState() api.InstanceStateMemory {
+func (c *LXC) memoryState() api.InstanceStateMemory {
memory := api.InstanceStateMemory{}
cg, err := c.cgroup(nil)
if err != nil {
@@ -5703,7 +5691,7 @@ func (c *containerLXC) memoryState() api.InstanceStateMemory {
return memory
}
-func (c *containerLXC) networkState() map[string]api.InstanceStateNetwork {
+func (c *LXC) networkState() map[string]api.InstanceStateNetwork {
result := map[string]api.InstanceStateNetwork{}
pid := c.InitPID()
@@ -5761,7 +5749,7 @@ func (c *containerLXC) networkState() map[string]api.InstanceStateNetwork {
return result
}
-func (c *containerLXC) processesState() int64 {
+func (c *LXC) processesState() int64 {
// Return 0 if not running
pid := c.InitPID()
if pid == -1 {
@@ -5811,8 +5799,8 @@ func (c *containerLXC) processesState() int64 {
}
// getStoragePool returns the current storage pool handle. To avoid a DB lookup each time this
-// function is called, the handle is cached internally in the containerLXC struct.
-func (c *containerLXC) getStoragePool() (storagePools.Pool, error) {
+// function is called, the handle is cached internally in the lxc struct.
+func (c *LXC) getStoragePool() (storagePools.Pool, error) {
if c.storagePool != nil {
return c.storagePool, nil
}
@@ -5827,7 +5815,7 @@ func (c *containerLXC) getStoragePool() (storagePools.Pool, error) {
}
// getStorageType returns the storage type of the instance's storage pool.
-func (c *containerLXC) getStorageType() (string, error) {
+func (c *LXC) getStorageType() (string, error) {
pool, err := c.getStoragePool()
if err != nil {
return "", err
@@ -5837,12 +5825,12 @@ func (c *containerLXC) getStorageType() (string, error) {
}
// StorageStart mounts the instance's rootfs volume. Deprecated.
-func (c *containerLXC) StorageStart() (bool, error) {
+func (c *LXC) StorageStart() (bool, error) {
return c.mount()
}
// mount the instance's rootfs volume if needed.
-func (c *containerLXC) mount() (bool, error) {
+func (c *LXC) mount() (bool, error) {
pool, err := c.getStoragePool()
if err != nil {
return false, err
@@ -5866,12 +5854,12 @@ func (c *containerLXC) mount() (bool, error) {
}
// StorageStop unmounts the instance's rootfs volume. Deprecated.
-func (c *containerLXC) StorageStop() (bool, error) {
+func (c *LXC) StorageStop() (bool, error) {
return c.unmount()
}
// unmount the instance's rootfs volume if needed.
-func (c *containerLXC) unmount() (bool, error) {
+func (c *LXC) unmount() (bool, error) {
pool, err := c.getStoragePool()
if err != nil {
return false, err
@@ -5895,7 +5883,7 @@ func (c *containerLXC) unmount() (bool, error) {
}
// Mount handling
-func (c *containerLXC) insertMountLXD(source, target, fstype string, flags int, mntnsPID int, shiftfs bool) error {
+func (c *LXC) insertMountLXD(source, target, fstype string, flags int, mntnsPID int, shiftfs bool) error {
pid := mntnsPID
if pid <= 0 {
// Get the init PID
@@ -5953,7 +5941,7 @@ func (c *containerLXC) insertMountLXD(source, target, fstype string, flags int,
return nil
}
-func (c *containerLXC) insertMountLXC(source, target, fstype string, flags int) error {
+func (c *LXC) insertMountLXC(source, target, fstype string, flags int) error {
cname := project.Prefix(c.Project(), c.Name())
configPath := filepath.Join(c.LogPath(), "lxc.conf")
if fstype == "" {
@@ -5972,7 +5960,7 @@ func (c *containerLXC) insertMountLXC(source, target, fstype string, flags int)
return nil
}
-func (c *containerLXC) insertMount(source, target, fstype string, flags int, shiftfs bool) error {
+func (c *LXC) insertMount(source, target, fstype string, flags int, shiftfs bool) error {
if c.state.OS.LXCFeatures["mount_injection_file"] && !shiftfs {
return c.insertMountLXC(source, target, fstype, flags)
}
@@ -5980,7 +5968,7 @@ func (c *containerLXC) insertMount(source, target, fstype string, flags int, shi
return c.insertMountLXD(source, target, fstype, flags, -1, shiftfs)
}
-func (c *containerLXC) removeMount(mount string) error {
+func (c *LXC) removeMount(mount string) error {
// Get the init PID
pid := c.InitPID()
if pid == -1 {
@@ -6012,7 +6000,7 @@ func (c *containerLXC) removeMount(mount string) error {
return nil
}
-func (c *containerLXC) InsertSeccompUnixDevice(prefix string, m deviceConfig.Device, pid int) error {
+func (c *LXC) InsertSeccompUnixDevice(prefix string, m deviceConfig.Device, pid int) error {
if pid < 0 {
return fmt.Errorf("Invalid request PID specified")
}
@@ -6067,7 +6055,7 @@ func (c *containerLXC) InsertSeccompUnixDevice(prefix string, m deviceConfig.Dev
return c.insertMountLXD(devPath, tgtPath, "none", unix.MS_BIND, pid, false)
}
-func (c *containerLXC) removeUnixDevices() error {
+func (c *LXC) removeUnixDevices() error {
// Check that we indeed have devices to remove
if !shared.PathExists(c.DevicesPath()) {
return nil
@@ -6099,7 +6087,7 @@ func (c *containerLXC) removeUnixDevices() error {
// FillNetworkDevice takes a nic or infiniband device type and enriches it with automatically
// generated name and hwaddr properties if these are missing from the device.
-func (c *containerLXC) FillNetworkDevice(name string, m deviceConfig.Device) (deviceConfig.Device, error) {
+func (c *LXC) FillNetworkDevice(name string, m deviceConfig.Device) (deviceConfig.Device, error) {
var err error
newDevice := m.Clone()
@@ -6258,7 +6246,7 @@ func (c *containerLXC) FillNetworkDevice(name string, m deviceConfig.Device) (de
return newDevice, nil
}
-func (c *containerLXC) removeDiskDevices() error {
+func (c *LXC) removeDiskDevices() error {
// Check that we indeed have devices to remove
if !shared.PathExists(c.DevicesPath()) {
return nil
@@ -6292,7 +6280,7 @@ func (c *containerLXC) removeDiskDevices() error {
}
// Network I/O limits
-func (c *containerLXC) setNetworkPriority() error {
+func (c *LXC) setNetworkPriority() error {
cg, err := c.cgroup(nil)
if err != nil {
return err
@@ -6345,23 +6333,23 @@ func (c *containerLXC) setNetworkPriority() error {
}
// Various state query functions
-func (c *containerLXC) IsStateful() bool {
+func (c *LXC) IsStateful() bool {
return c.stateful
}
-func (c *containerLXC) IsEphemeral() bool {
+func (c *LXC) IsEphemeral() bool {
return c.ephemeral
}
-func (c *containerLXC) IsFrozen() bool {
+func (c *LXC) IsFrozen() bool {
return c.State() == "FROZEN"
}
-func (c *containerLXC) IsNesting() bool {
+func (c *LXC) IsNesting() bool {
return shared.IsTrue(c.expandedConfig["security.nesting"])
}
-func (c *containerLXC) isCurrentlyPrivileged() bool {
+func (c *LXC) isCurrentlyPrivileged() bool {
if !c.IsRunning() {
return c.IsPrivileged()
}
@@ -6374,44 +6362,44 @@ func (c *containerLXC) isCurrentlyPrivileged() bool {
return idmap == nil
}
-func (c *containerLXC) IsPrivileged() bool {
+func (c *LXC) IsPrivileged() bool {
return shared.IsTrue(c.expandedConfig["security.privileged"])
}
-func (c *containerLXC) IsRunning() bool {
+func (c *LXC) IsRunning() bool {
state := c.State()
return state != "BROKEN" && state != "STOPPED"
}
-func (c *containerLXC) IsSnapshot() bool {
+func (c *LXC) IsSnapshot() bool {
return c.snapshot
}
// Various property query functions
-func (c *containerLXC) Architecture() int {
+func (c *LXC) Architecture() int {
return c.architecture
}
-func (c *containerLXC) CreationDate() time.Time {
+func (c *LXC) CreationDate() time.Time {
return c.creationDate
}
-func (c *containerLXC) LastUsedDate() time.Time {
+func (c *LXC) LastUsedDate() time.Time {
return c.lastUsedDate
}
-func (c *containerLXC) ExpandedConfig() map[string]string {
+func (c *LXC) ExpandedConfig() map[string]string {
return c.expandedConfig
}
-func (c *containerLXC) ExpandedDevices() deviceConfig.Devices {
+func (c *LXC) ExpandedDevices() deviceConfig.Devices {
return c.expandedDevices
}
// ID gets container's ID.
-func (c *containerLXC) ID() int {
+func (c *LXC) ID() int {
return c.id
}
-func (c *containerLXC) InitPID() int {
+func (c *LXC) InitPID() int {
// Load the go-lxc struct
err := c.initLXC(false)
if err != nil {
@@ -6421,42 +6409,42 @@ func (c *containerLXC) InitPID() int {
return c.c.InitPid()
}
-func (c *containerLXC) LocalConfig() map[string]string {
+func (c *LXC) LocalConfig() map[string]string {
return c.localConfig
}
-func (c *containerLXC) LocalDevices() deviceConfig.Devices {
+func (c *LXC) LocalDevices() deviceConfig.Devices {
return c.localDevices
}
-func (c *containerLXC) CurrentIdmap() (*idmap.IdmapSet, error) {
+func (c *LXC) CurrentIdmap() (*idmap.IdmapSet, error) {
jsonIdmap, ok := c.LocalConfig()["volatile.idmap.current"]
if !ok {
return c.DiskIdmap()
}
- return idmapsetFromString(jsonIdmap)
+ return storageDrivers.IDMapsetFromString(jsonIdmap)
}
-func (c *containerLXC) DiskIdmap() (*idmap.IdmapSet, error) {
+func (c *LXC) DiskIdmap() (*idmap.IdmapSet, error) {
jsonIdmap, ok := c.LocalConfig()["volatile.last_state.idmap"]
if !ok {
return nil, nil
}
- return idmapsetFromString(jsonIdmap)
+ return storageDrivers.IDMapsetFromString(jsonIdmap)
}
-func (c *containerLXC) NextIdmap() (*idmap.IdmapSet, error) {
+func (c *LXC) NextIdmap() (*idmap.IdmapSet, error) {
jsonIdmap, ok := c.LocalConfig()["volatile.idmap.next"]
if !ok {
return c.CurrentIdmap()
}
- return idmapsetFromString(jsonIdmap)
+ return storageDrivers.IDMapsetFromString(jsonIdmap)
}
-func (c *containerLXC) DaemonState() *state.State {
+func (c *LXC) DaemonState() *state.State {
// FIXME: This function should go away, since the abstract container
// interface should not be coupled with internal state details.
// However this is not currently possible, because many
@@ -6466,27 +6454,27 @@ func (c *containerLXC) DaemonState() *state.State {
return c.state
}
-func (c *containerLXC) Location() string {
+func (c *LXC) Location() string {
return c.node
}
-func (c *containerLXC) Project() string {
+func (c *LXC) Project() string {
return c.project
}
-func (c *containerLXC) Name() string {
+func (c *LXC) Name() string {
return c.name
}
-func (c *containerLXC) Description() string {
+func (c *LXC) Description() string {
return c.description
}
-func (c *containerLXC) Profiles() []string {
+func (c *LXC) Profiles() []string {
return c.profiles
}
-func (c *containerLXC) State() string {
+func (c *LXC) State() string {
state, err := c.getLxcState()
if err != nil {
return api.Error.String()
@@ -6495,42 +6483,42 @@ func (c *containerLXC) State() string {
}
// Various container paths
-func (c *containerLXC) Path() string {
+func (c *LXC) Path() string {
return storagePools.InstancePath(c.Type(), c.Project(), c.Name(), c.IsSnapshot())
}
-func (c *containerLXC) DevicesPath() string {
+func (c *LXC) DevicesPath() string {
name := project.Prefix(c.Project(), c.Name())
return shared.VarPath("devices", name)
}
-func (c *containerLXC) ShmountsPath() string {
+func (c *LXC) ShmountsPath() string {
name := project.Prefix(c.Project(), c.Name())
return shared.VarPath("shmounts", name)
}
-func (c *containerLXC) LogPath() string {
+func (c *LXC) LogPath() string {
name := project.Prefix(c.Project(), c.Name())
return shared.LogPath(name)
}
-func (c *containerLXC) LogFilePath() string {
+func (c *LXC) LogFilePath() string {
return filepath.Join(c.LogPath(), "lxc.log")
}
-func (c *containerLXC) ConsoleBufferLogPath() string {
+func (c *LXC) ConsoleBufferLogPath() string {
return filepath.Join(c.LogPath(), "console.log")
}
-func (c *containerLXC) RootfsPath() string {
+func (c *LXC) RootfsPath() string {
return filepath.Join(c.Path(), "rootfs")
}
-func (c *containerLXC) TemplatesPath() string {
+func (c *LXC) TemplatesPath() string {
return filepath.Join(c.Path(), "templates")
}
-func (c *containerLXC) StatePath() string {
+func (c *LXC) StatePath() string {
/* FIXME: backwards compatibility: we used to use Join(RootfsPath(),
* "state"), which was bad. Let's just check to see if that directory
* exists.
@@ -6542,7 +6530,7 @@ func (c *containerLXC) StatePath() string {
return filepath.Join(c.Path(), "state")
}
-func (c *containerLXC) StoragePool() (string, error) {
+func (c *LXC) StoragePool() (string, error) {
poolName, err := c.state.Cluster.InstancePool(c.Project(), c.Name())
if err != nil {
return "", err
@@ -6552,11 +6540,11 @@ func (c *containerLXC) StoragePool() (string, error) {
}
// Progress tracking
-func (c *containerLXC) SetOperation(op *operations.Operation) {
+func (c *LXC) SetOperation(op *operations.Operation) {
c.op = op
}
-func (c *containerLXC) ExpiryDate() time.Time {
+func (c *LXC) ExpiryDate() time.Time {
if c.IsSnapshot() {
return c.expiryDate
}
@@ -6565,7 +6553,7 @@ func (c *containerLXC) ExpiryDate() time.Time {
return time.Time{}
}
-func (c *containerLXC) updateProgress(progress string) {
+func (c *LXC) updateProgress(progress string) {
if c.op == nil {
return
}
@@ -6582,7 +6570,7 @@ func (c *containerLXC) updateProgress(progress string) {
}
// Internal MAAS handling
-func (c *containerLXC) maasInterfaces(devices map[string]map[string]string) ([]maas.ContainerInterface, error) {
+func (c *LXC) maasInterfaces(devices map[string]map[string]string) ([]maas.ContainerInterface, error) {
interfaces := []maas.ContainerInterface{}
for k, m := range devices {
if m["type"] != "nic" {
@@ -6632,7 +6620,7 @@ func (c *containerLXC) maasInterfaces(devices map[string]map[string]string) ([]m
return interfaces, nil
}
-func (c *containerLXC) maasUpdate(oldDevices map[string]map[string]string) error {
+func (c *LXC) maasUpdate(oldDevices map[string]map[string]string) error {
// Check if MAAS is configured
maasURL, err := cluster.ConfigGetString(c.state.Cluster, "maas.api.url")
if err != nil {
@@ -6682,7 +6670,7 @@ func (c *containerLXC) maasUpdate(oldDevices map[string]map[string]string) error
return c.state.MAAS.CreateContainer(project.Prefix(c.project, c.name), interfaces)
}
-func (c *containerLXC) maasRename(newName string) error {
+func (c *LXC) maasRename(newName string) error {
maasURL, err := cluster.ConfigGetString(c.state.Cluster, "maas.api.url")
if err != nil {
return err
@@ -6717,7 +6705,7 @@ func (c *containerLXC) maasRename(newName string) error {
return c.state.MAAS.RenameContainer(project.Prefix(c.project, c.name), project.Prefix(c.project, newName))
}
-func (c *containerLXC) maasDelete() error {
+func (c *LXC) maasDelete() error {
maasURL, err := cluster.ConfigGetString(c.state.Cluster, "maas.api.url")
if err != nil {
return err
@@ -6752,7 +6740,7 @@ func (c *containerLXC) maasDelete() error {
return c.state.MAAS.DeleteContainer(project.Prefix(c.project, c.name))
}
-func (c *containerLXC) cgroup(cc *lxc.Container) (*cgroup.CGroup, error) {
+func (c *LXC) cgroup(cc *liblxc.Container) (*cgroup.CGroup, error) {
rw := lxcCgroupReadWriter{}
if cc != nil {
rw.cc = cc
@@ -6803,7 +6791,7 @@ func (rw *lxcCgroupReadWriter) Set(version cgroup.Backend, controller string, ke
}
// UpdateBackupFile writes the instance's backup.yaml file to storage.
-func (c *containerLXC) UpdateBackupFile() error {
+func (c *LXC) UpdateBackupFile() error {
pool, err := c.getStoragePool()
if err != nil {
return err
From 1742f3980d7f74431466933446dc9a1d4b479561 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:50:36 +0000
Subject: [PATCH 17/50] lxd/instance/drivers/driver/lxc: Removes temporary
loader placeholders
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 174cbd16e4..da39ab875d 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -57,15 +57,6 @@ import (
"github.com/lxc/lxd/shared/units"
)
-func init() {
- // Temporarily link containerLXC load functions to instanceDrivers package so it can be used by the
- // internal loader functions. These can be removed once containerLXC type is moved into the
- // instance/drivers package.
- instanceDrivers.LXCLoad = containerLXCLoad
- instanceDrivers.LXCInstantiate = containerLXCInstantiate
- instanceDrivers.LXCCreate = containerLXCCreate
-}
-
// Helper functions
func lxcSetConfigItem(c *lxc.Container, key string, value string) error {
if c == nil {
From 47193669aae5feccfb174d21d3e12e75c14a9bbe Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:52:05 +0000
Subject: [PATCH 18/50] lxd/instance/drivers/driver/lxc: Renames lxc to liblxc
For clarity that this is the external lxc package (with the view that eventually LXC type will be renamed to lxc).
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index da39ab875d..e819bb72c1 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -21,7 +21,7 @@ import (
"github.com/flosch/pongo2"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
- lxc "gopkg.in/lxc/go-lxc.v2"
+ liblxc "gopkg.in/lxc/go-lxc.v2"
yaml "gopkg.in/yaml.v2"
"github.com/lxc/lxd/lxd/apparmor"
@@ -58,7 +58,7 @@ import (
)
// Helper functions
-func lxcSetConfigItem(c *lxc.Container, key string, value string) error {
+func lxcSetConfigItem(c *liblxc.Container, key string, value string) error {
if c == nil {
return fmt.Errorf("Uninitialized go-lxc struct")
}
@@ -122,7 +122,7 @@ func lxcSetConfigItem(c *lxc.Container, key string, value string) error {
return nil
}
-func lxcStatusCode(state lxc.State) api.StatusCode {
+func lxcStatusCode(state liblxc.State) api.StatusCode {
return map[int]api.StatusCode{
1: api.Stopped,
2: api.Starting,
@@ -441,7 +441,7 @@ type LXC struct {
profiles []string
// Cache
- c *lxc.Container
+ c *liblxc.Container
cConfig bool
state *state.State
@@ -684,7 +684,7 @@ func (c *LXC) initLXC(config bool) error {
// Load the go-lxc struct
cname := project.Prefix(c.Project(), c.Name())
- cc, err := lxc.NewContainer(cname, c.state.OS.LxcPath)
+ cc, err := liblxc.NewContainer(cname, c.state.OS.LxcPath)
if err != nil {
return err
}
@@ -1559,7 +1559,7 @@ func (c *LXC) deviceDetachNIC(configCopy map[string]string, netIF []deviceConfig
if stopHookNetnsPath == "" {
// For some reason, having network config confuses detach, so get our own go-lxc struct.
cname := project.Prefix(c.Project(), c.Name())
- cc, err := lxc.NewContainer(cname, c.state.OS.LxcPath)
+ cc, err := liblxc.NewContainer(cname, c.state.OS.LxcPath)
if err != nil {
return err
}
@@ -2955,18 +2955,18 @@ var LxcMonitorStateError = fmt.Errorf("Monitor is hung")
// If we don't get a reply, assume the lxc monitor is hung
func (c *LXC) getLxcState() (liblxc.State, error) {
if c.IsSnapshot() {
- return lxc.StateMap["STOPPED"], nil
+ return liblxc.StateMap["STOPPED"], nil
}
// Load the go-lxc struct
err := c.initLXC(false)
if err != nil {
- return lxc.StateMap["STOPPED"], err
+ return liblxc.StateMap["STOPPED"], err
}
- monitor := make(chan lxc.State, 1)
+ monitor := make(chan liblxc.State, 1)
- go func(c *lxc.Container) {
+ go func(c *liblxc.Container) {
monitor <- c.State()
}(c.c)
@@ -6113,7 +6113,7 @@ func (c *LXC) FillNetworkDevice(name string, m deviceConfig.Device) (deviceConfi
// Attempt to include all existing interfaces
cname := project.Prefix(c.Project(), c.Name())
- cc, err := lxc.NewContainer(cname, c.state.OS.LxcPath)
+ cc, err := liblxc.NewContainer(cname, c.state.OS.LxcPath)
if err == nil {
defer cc.Release()
@@ -6745,12 +6745,12 @@ func (c *LXC) cgroup(cc *liblxc.Container) (*cgroup.CGroup, error) {
return nil, err
}
- cg.UnifiedCapable = lxc.HasApiExtension("cgroup2")
+ cg.UnifiedCapable = liblxc.HasApiExtension("cgroup2")
return cg, nil
}
type lxcCgroupReadWriter struct {
- cc *lxc.Container
+ cc *liblxc.Container
conf bool
cgroup2 bool
}
From 112dd9119901b7254bb8cb8e03239310d3ca9b0b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:53:37 +0000
Subject: [PATCH 19/50] lxd/instance/drivers/driver/lxc:
db.StoragePoolVolumeTypeContainer usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index e819bb72c1..daae22b716 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -233,7 +233,7 @@ func lxcCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error)
}
// Create a new database entry for the container's storage volume
- _, err = s.Cluster.StoragePoolVolumeCreate(args.Project, args.Name, "", storagePoolVolumeTypeContainer, c.IsSnapshot(), poolID, volumeConfig)
+ _, err = s.Cluster.StoragePoolVolumeCreate(args.Project, args.Name, "", db.StoragePoolVolumeTypeContainer, c.IsSnapshot(), poolID, volumeConfig)
if err != nil {
c.Delete()
return nil, err
@@ -243,7 +243,7 @@ func lxcCreate(s *state.State, args db.InstanceArgs) (instance.Instance, error)
pool, err := storagePools.GetPoolByInstance(c.state, c)
if err != nil {
c.Delete()
- s.Cluster.StoragePoolVolumeDelete(args.Project, args.Name, storagePoolVolumeTypeContainer, poolID)
+ s.Cluster.StoragePoolVolumeDelete(args.Project, args.Name, db.StoragePoolVolumeTypeContainer, poolID)
logger.Error("Failed to initialize container storage", ctxMap)
return nil, err
}
From 356d0eafc1f9f3debba0ff4b1a611492c13265f6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:54:52 +0000
Subject: [PATCH 20/50] lxd/instance/drivers/driver/lxc: Adds CriuMigrationArgs
and devLxdSendEvent
Updates usage.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 139 +++++++++++++++++------------
1 file changed, 80 insertions(+), 59 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index daae22b716..46a6891196 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -417,6 +417,18 @@ func lxcInstantiate(s *state.State, args db.InstanceArgs, expandedDevices device
return c
}
+// CriuMigrationArgs arguments for CRIU migration.
+type CriuMigrationArgs struct {
+ Cmd uint
+ StateDir string
+ Function string
+ Stop bool
+ ActionScript bool
+ DumpDir string
+ PreDumpDir string
+ Features liblxc.CriuFeatures
+}
+
// The LXC container driver
type LXC struct {
// Properties
@@ -1262,6 +1274,15 @@ func (c *LXC) initLXC(config bool) error {
return nil
}
+func (c *LXC) devlxdEventSend(eventType string, eventMessage interface{}) error {
+ event := shared.Jmap{}
+ event["type"] = eventType
+ event["timestamp"] = time.Now()
+ event["metadata"] = eventMessage
+
+ return c.state.DevlxdEvents.Send(strconv.Itoa(c.ID()), eventType, eventMessage)
+}
+
// runHooks executes the callback functions returned from a function.
func (c *LXC) runHooks(hooks []func() error) error {
// Run any post start hooks.
@@ -2302,13 +2323,13 @@ func (c *LXC) Start(stateful bool) error {
}
criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_RESTORE,
- stateDir: c.StatePath(),
- function: "snapshot",
- stop: false,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
+ Cmd: liblxc.MIGRATE_RESTORE,
+ StateDir: c.StatePath(),
+ Function: "snapshot",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
err := c.Migrate(&criuMigrationArgs)
@@ -2538,13 +2559,13 @@ func (c *LXC) Stop(stateful bool) error {
}
criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_DUMP,
- stateDir: stateDir,
- function: "snapshot",
- stop: true,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
+ Cmd: liblxc.MIGRATE_DUMP,
+ StateDir: stateDir,
+ Function: "snapshot",
+ Stop: true,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
// Checkpoint
@@ -3302,13 +3323,13 @@ func (c *LXC) Restore(sourceContainer instance.Instance, stateful bool) error {
c.stateful = true
criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_RESTORE,
- stateDir: c.StatePath(),
- function: "snapshot",
- stop: false,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
+ Cmd: liblxc.MIGRATE_RESTORE,
+ StateDir: c.StatePath(),
+ Function: "snapshot",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
// Checkpoint.
@@ -4357,7 +4378,7 @@ func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
"value": c.expandedConfig[key],
}
- err = devlxdEventSend(c, "config", msg)
+ err = c.devlxdEventSend("config", msg)
if err != nil {
return err
}
@@ -4371,7 +4392,7 @@ func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
"config": m,
}
- err = devlxdEventSend(c, "device", msg)
+ err = c.devlxdEventSend("device", msg)
if err != nil {
return err
}
@@ -4384,7 +4405,7 @@ func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
"config": m,
}
- err = devlxdEventSend(c, "device", msg)
+ err = c.devlxdEventSend("device", msg)
if err != nil {
return err
}
@@ -4397,7 +4418,7 @@ func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
"config": m,
}
- err = devlxdEventSend(c, "device", msg)
+ err = c.devlxdEventSend("device", msg)
if err != nil {
return err
}
@@ -4730,11 +4751,11 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
"created": c.creationDate,
"ephemeral": c.ephemeral,
"used": c.lastUsedDate,
- "statedir": args.stateDir,
- "actionscript": args.actionScript,
- "predumpdir": args.preDumpDir,
- "features": args.features,
- "stop": args.stop}
+ "statedir": args.StateDir,
+ "actionscript": args.ActionScript,
+ "predumpdir": args.PreDumpDir,
+ "features": args.Features,
+ "stop": args.Stop}
_, err := exec.LookPath("criu")
if err != nil {
@@ -4744,18 +4765,18 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
logger.Info("Migrating container", ctxMap)
prettyCmd := ""
- switch args.cmd {
- case lxc.MIGRATE_PRE_DUMP:
+ switch args.Cmd {
+ case liblxc.MIGRATE_PRE_DUMP:
prettyCmd = "pre-dump"
- case lxc.MIGRATE_DUMP:
+ case liblxc.MIGRATE_DUMP:
prettyCmd = "dump"
- case lxc.MIGRATE_RESTORE:
+ case liblxc.MIGRATE_RESTORE:
prettyCmd = "restore"
- case lxc.MIGRATE_FEATURE_CHECK:
+ case liblxc.MIGRATE_FEATURE_CHECK:
prettyCmd = "feature-check"
default:
prettyCmd = "unknown"
- logger.Warn("Unknown migrate call", log.Ctx{"cmd": args.cmd})
+ logger.Warn("Unknown migrate call", log.Ctx{"cmd": args.Cmd})
}
pool, err := c.getStoragePool()
@@ -4772,14 +4793,14 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
preservesInodes = false
}
- finalStateDir := args.stateDir
+ finalStateDir := args.StateDir
var migrateErr error
/* For restore, we need an extra fork so that we daemonize monitor
* instead of having it be a child of LXD, so let's hijack the command
* here and do the extra fork.
*/
- if args.cmd == lxc.MIGRATE_RESTORE {
+ if args.Cmd == liblxc.MIGRATE_RESTORE {
// Run the shared start
_, postStartHooks, err := c.startCommon()
if err != nil {
@@ -4809,11 +4830,11 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
}
if storageType == "zfs" {
- err = idmapset.ShiftRootfs(args.stateDir, shiftZfsSkipper)
+ err = idmapset.ShiftRootfs(args.StateDir, storageDrivers.ShiftZFSSkipper)
} else if storageType == "btrfs" {
- err = ShiftBtrfsRootfs(args.stateDir, idmapset)
+ err = storageDrivers.ShiftBtrfsRootfs(args.StateDir, idmapset)
} else {
- err = idmapset.ShiftRootfs(args.stateDir, nil)
+ err = idmapset.ShiftRootfs(args.StateDir, nil)
}
if ourStart {
_, err2 := c.unmount()
@@ -4829,8 +4850,8 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
configPath := filepath.Join(c.LogPath(), "lxc.conf")
- if args.dumpDir != "" {
- finalStateDir = fmt.Sprintf("%s/%s", args.stateDir, args.dumpDir)
+ if args.DumpDir != "" {
+ finalStateDir = fmt.Sprintf("%s/%s", args.StateDir, args.DumpDir)
}
_, migrateErr = shared.RunCommand(
@@ -4851,16 +4872,16 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
return err
}
}
- } else if args.cmd == lxc.MIGRATE_FEATURE_CHECK {
+ } else if args.Cmd == liblxc.MIGRATE_FEATURE_CHECK {
err := c.initLXC(true)
if err != nil {
return err
}
- opts := lxc.MigrateOptions{
- FeaturesToCheck: args.features,
+ opts := liblxc.MigrateOptions{
+ FeaturesToCheck: args.Features,
}
- migrateErr = c.c.Migrate(args.cmd, opts)
+ migrateErr = c.c.Migrate(args.Cmd, opts)
if migrateErr != nil {
logger.Info("CRIU feature check failed", ctxMap)
return migrateErr
@@ -4873,12 +4894,12 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
}
script := ""
- if args.actionScript {
- script = filepath.Join(args.stateDir, "action.sh")
+ if args.ActionScript {
+ script = filepath.Join(args.StateDir, "action.sh")
}
- if args.dumpDir != "" {
- finalStateDir = fmt.Sprintf("%s/%s", args.stateDir, args.dumpDir)
+ if args.DumpDir != "" {
+ finalStateDir = fmt.Sprintf("%s/%s", args.StateDir, args.DumpDir)
}
// TODO: make this configurable? Ultimately I think we don't
@@ -4889,27 +4910,27 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
// slow.
ghostLimit := uint64(256 * 1024 * 1024)
- opts := lxc.MigrateOptions{
- Stop: args.stop,
+ opts := liblxc.MigrateOptions{
+ Stop: args.Stop,
Directory: finalStateDir,
Verbose: true,
PreservesInodes: preservesInodes,
ActionScript: script,
GhostLimit: ghostLimit,
}
- if args.preDumpDir != "" {
- opts.PredumpDir = fmt.Sprintf("../%s", args.preDumpDir)
+ if args.PreDumpDir != "" {
+ opts.PredumpDir = fmt.Sprintf("../%s", args.PreDumpDir)
}
if !c.IsRunning() {
// otherwise the migration will needlessly fail
- args.stop = false
+ args.Stop = false
}
- migrateErr = c.c.Migrate(args.cmd, opts)
+ migrateErr = c.c.Migrate(args.Cmd, opts)
}
- collectErr := collectCRIULogFile(c, finalStateDir, args.function, prettyCmd)
+ collectErr := collectCRIULogFile(c, finalStateDir, args.Function, prettyCmd)
if collectErr != nil {
logger.Error("Error collecting checkpoint log file", log.Ctx{"err": collectErr})
}
@@ -4918,7 +4939,7 @@ func (c *LXC) Migrate(args *CriuMigrationArgs) error {
log, err2 := getCRIULogErrors(finalStateDir, prettyCmd)
if err2 == nil {
logger.Info("Failed migrating container", ctxMap)
- migrateErr = fmt.Errorf("%s %s failed\n%s", args.function, prettyCmd, log)
+ migrateErr = fmt.Errorf("%s %s failed\n%s", args.Function, prettyCmd, log)
}
return migrateErr
From b25dc0108418f80d335147ba63ac4eb0d3b9b750 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:55:32 +0000
Subject: [PATCH 21/50] lxd/instance/drivers/driver/lxc: Adds RegisterDevices
function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 46a6891196..61312b8b5f 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -1298,6 +1298,29 @@ func (c *LXC) runHooks(hooks []func() error) error {
return nil
}
+// RegisterDevices calls the Register() function on all of the instance's devices.
+func (c *LXC) RegisterDevices() {
+ devices := c.ExpandedDevices()
+ for _, dev := range devices.Sorted() {
+ d, _, err := c.deviceLoad(dev.Name, dev.Config)
+ if err == device.ErrUnsupportedDevType {
+ continue
+ }
+
+ if err != nil {
+ logger.Error("Failed to load device to register", log.Ctx{"err": err, "instance": c.Name(), "device": dev.Name})
+ continue
+ }
+
+ // Check whether device wants to register for any events.
+ err = d.Register()
+ if err != nil {
+ logger.Error("Failed to register device", log.Ctx{"err": err, "instance": c.Name(), "device": dev.Name})
+ continue
+ }
+ }
+}
+
// deviceLoad instantiates and validates a new device and returns it along with enriched config.
func (c *LXC) deviceLoad(deviceName string, rawConfig deviceConfig.Device) (device.Device, deviceConfig.Device, error) {
var configCopy deviceConfig.Device
From d232d9c50f72a9d8dd9709075ec26fdfd7e874e8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:56:08 +0000
Subject: [PATCH 22/50] lxd/instance/drivers/driver/lxc: Moves storage util
functions and updates usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 58 +++---------------------------
1 file changed, 4 insertions(+), 54 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 61312b8b5f..46a036bd2e 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -1867,56 +1867,6 @@ func (c *LXC) expandDevices(profiles []api.Profile) error {
return nil
}
-func shiftZfsSkipper(dir string, absPath string, fi os.FileInfo) bool {
- strippedPath := absPath
- if dir != "" {
- strippedPath = absPath[len(dir):]
- }
-
- if fi.IsDir() && strippedPath == "/.zfs/snapshot" {
- return true
- }
-
- return false
-}
-
-func shiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet, shift bool) error {
- var err error
- roSubvols := []string{}
- subvols, _ := btrfsSubVolumesGet(path)
- sort.Sort(sort.StringSlice(subvols))
- for _, subvol := range subvols {
- subvol = filepath.Join(path, subvol)
-
- if !btrfsSubVolumeIsRo(subvol) {
- continue
- }
-
- roSubvols = append(roSubvols, subvol)
- btrfsSubVolumeMakeRw(subvol)
- }
-
- if shift {
- err = diskIdmap.ShiftRootfs(path, nil)
- } else {
- err = diskIdmap.UnshiftRootfs(path, nil)
- }
-
- for _, subvol := range roSubvols {
- btrfsSubVolumeMakeRo(subvol)
- }
-
- return err
-}
-
-func ShiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
- return shiftBtrfsRootfs(path, diskIdmap, true)
-}
-
-func UnshiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
- return shiftBtrfsRootfs(path, diskIdmap, false)
-}
-
// Start functions
func (c *LXC) startCommon() (string, []func() error, error) {
var ourStart bool
@@ -1976,9 +1926,9 @@ func (c *LXC) startCommon() (string, []func() error, error) {
if diskIdmap != nil {
if storageType == "zfs" {
- err = diskIdmap.UnshiftRootfs(c.RootfsPath(), shiftZfsSkipper)
+ err = diskIdmap.UnshiftRootfs(c.RootfsPath(), storageDrivers.ShiftZFSSkipper)
} else if storageType == "btrfs" {
- err = UnshiftBtrfsRootfs(c.RootfsPath(), diskIdmap)
+ err = storageDrivers.UnshiftBtrfsRootfs(c.RootfsPath(), diskIdmap)
} else {
err = diskIdmap.UnshiftRootfs(c.RootfsPath(), nil)
}
@@ -1992,9 +1942,9 @@ func (c *LXC) startCommon() (string, []func() error, error) {
if nextIdmap != nil && !c.state.OS.Shiftfs {
if storageType == "zfs" {
- err = nextIdmap.ShiftRootfs(c.RootfsPath(), shiftZfsSkipper)
+ err = nextIdmap.ShiftRootfs(c.RootfsPath(), storageDrivers.ShiftZFSSkipper)
} else if storageType == "btrfs" {
- err = ShiftBtrfsRootfs(c.RootfsPath(), nextIdmap)
+ err = storageDrivers.ShiftBtrfsRootfs(c.RootfsPath(), nextIdmap)
} else {
err = nextIdmap.ShiftRootfs(c.RootfsPath(), nil)
}
From 155dbc2c2f167d4a8e1dee18fd30641d290b1766 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:56:26 +0000
Subject: [PATCH 23/50] lxd/instance/drivers/driver/lxc: SetupSharedMounts
usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 46a036bd2e..1c22228d5d 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -2261,7 +2261,7 @@ func (c *LXC) Start(stateful bool) error {
}
defer op.Done(nil)
- err = setupSharedMounts()
+ err = SetupSharedMounts()
if err != nil {
return fmt.Errorf("Daemon failed to setup shared mounts base: %s.\nDoes security.nesting need to be turned on?", err)
}
From 7366db5a0cc31a5b65279797cc86af82e3a806b8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:56:47 +0000
Subject: [PATCH 24/50] lxd/instance/drivers/driver/lxc: Adds SaveConfigFile
function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 1c22228d5d..7054d2cb92 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -6784,3 +6784,21 @@ func (c *LXC) UpdateBackupFile() error {
return pool.UpdateInstanceBackupFile(c, nil)
}
+
+// SaveConfigFile generates the LXC config file on disk.
+func (c *LXC) SaveConfigFile() error {
+ err := c.initLXC(true)
+ if err != nil {
+ return errors.Wrapf(err, "Failed to generate LXC config")
+ }
+
+ // Generate the LXC config.
+ configPath := filepath.Join(c.LogPath(), "lxc.conf")
+ err = c.c.SaveConfigFile(configPath)
+ if err != nil {
+ os.Remove(configPath)
+ return fmt.Errorf("Failed to save LXC config to file %q", configPath, err)
+ }
+
+ return nil
+}
From 2c89a608304dd1b4e6733fbf79f2fa90960cd90b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 17:59:56 +0000
Subject: [PATCH 25/50] lxd/instance/drivers/driver/lxc/cmd: Renames
ContainerLXCCmd to lxcCmd
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc_cmd.go | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc_cmd.go b/lxd/instance/drivers/driver_lxc_cmd.go
index ea9543022a..7d80898e47 100644
--- a/lxd/instance/drivers/driver_lxc_cmd.go
+++ b/lxd/instance/drivers/driver_lxc_cmd.go
@@ -1,4 +1,4 @@
-package main
+package drivers
import (
"os/exec"
@@ -10,19 +10,19 @@ import (
"github.com/lxc/lxd/shared/logger"
)
-// ContainerLXCCmd represents a running command for an LXC container.
-type ContainerLXCCmd struct {
+// lxcCmd represents a running command for an LXC container.
+type lxcCmd struct {
attachedChildPid int
cmd *exec.Cmd
}
// PID returns the attached child's process ID.
-func (c *ContainerLXCCmd) PID() int {
+func (c *lxcCmd) PID() int {
return c.attachedChildPid
}
// Signal sends a signal to the command.
-func (c *ContainerLXCCmd) Signal(sig unix.Signal) error {
+func (c *lxcCmd) Signal(sig unix.Signal) error {
err := unix.Kill(c.attachedChildPid, sig)
if err != nil {
return err
@@ -33,7 +33,7 @@ func (c *ContainerLXCCmd) Signal(sig unix.Signal) error {
}
// Wait for the command to end and returns its exit code and any error.
-func (c *ContainerLXCCmd) Wait() (int, error) {
+func (c *lxcCmd) Wait() (int, error) {
err := c.cmd.Wait()
if err != nil {
exitErr, ok := err.(*exec.ExitError)
@@ -56,7 +56,7 @@ func (c *ContainerLXCCmd) Wait() (int, error) {
}
// WindowResize resizes the running command's window.
-func (c *ContainerLXCCmd) WindowResize(fd, winchWidth, winchHeight int) error {
+func (c *lxcCmd) WindowResize(fd, winchWidth, winchHeight int) error {
err := shared.SetSize(fd, winchWidth, winchHeight)
if err != nil {
return err
From 116eca7e38310187176a84567f1937d083f44dcf Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:00:17 +0000
Subject: [PATCH 26/50] lxd/instance/drivers/driver/qemu: Adds RegisterDevices
as a no-op
Just satifies the Instance interface.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_qemu.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index a8f0e41006..ca97f5ccc6 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -970,6 +970,11 @@ func (vm *qemu) deviceVolatileSetFunc(devName string) func(save map[string]strin
}
}
+// RegisterDevices is not used by VMs.
+func (vm *qemu) RegisterDevices() {
+ return
+}
+
// deviceLoad instantiates and validates a new device and returns it along with enriched config.
func (vm *qemu) deviceLoad(deviceName string, rawConfig deviceConfig.Device) (device.Device, deviceConfig.Device, error) {
var configCopy deviceConfig.Device
From c6a8320241a52b08c7bc4cd9caa9cc822a0598c2 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:00:52 +0000
Subject: [PATCH 27/50] lxd/instance/instance/interface: Adds RegisterDevices
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/instance_interface.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
index 1018ddf780..8b2a532343 100644
--- a/lxd/instance/instance_interface.go
+++ b/lxd/instance/instance_interface.go
@@ -33,6 +33,7 @@ type Instance interface {
Start(stateful bool) error
Stop(stateful bool) error
Unfreeze() error
+ RegisterDevices()
IsPrivileged() bool
From 1c9b9d0ef5f2a2e3456ec6f0bdc2016288f01958 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:01:06 +0000
Subject: [PATCH 28/50] lxd/instance/drivers/load: LXC loader functions renamed
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/load.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lxd/instance/drivers/load.go b/lxd/instance/drivers/load.go
index 548112c7b2..b534365fd0 100644
--- a/lxd/instance/drivers/load.go
+++ b/lxd/instance/drivers/load.go
@@ -32,7 +32,7 @@ func load(s *state.State, args db.InstanceArgs, profiles []api.Profile) (instanc
var err error
if args.Type == instancetype.Container {
- inst, err = LXCLoad(s, args, profiles)
+ inst, err = lxcLoad(s, args, profiles)
} else if args.Type == instancetype.VM {
inst, err = qemuLoad(s, args, profiles)
} else {
@@ -88,7 +88,7 @@ func validDevices(state *state.State, cluster *db.Cluster, instanceType instance
func create(s *state.State, args db.InstanceArgs) (instance.Instance, error) {
if args.Type == instancetype.Container {
- return LXCCreate(s, args)
+ return lxcCreate(s, args)
} else if args.Type == instancetype.VM {
return qemuCreate(s, args)
}
From 08456eb3c131d5257d2ed4c048758ca3ba5b3fc7 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:10:44 +0000
Subject: [PATCH 29/50] lxd/migrate/container:
instanceDrivers.CriuMigrationArgs and instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/migrate_container.go | 93 ++++++++++++++++++++--------------------
1 file changed, 47 insertions(+), 46 deletions(-)
diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index 70751a70a7..dba04e7d9b 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -17,6 +17,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
@@ -129,22 +130,22 @@ func snapshotToProtobuf(c instance.Instance) *migration.Snapshot {
func (s *migrationSourceWs) checkForPreDumpSupport() (bool, int) {
// Ask CRIU if this architecture/kernel/criu combination
// supports pre-copy (dirty memory tracking)
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_FEATURE_CHECK,
- stateDir: "",
- function: "feature-check",
- stop: false,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
- features: lxc.FEATURE_MEM_TRACK,
+ criuMigrationArgs := instanceDrivers.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_FEATURE_CHECK,
+ StateDir: "",
+ Function: "feature-check",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
+ Features: lxc.FEATURE_MEM_TRACK,
}
if s.instance.Type() != instancetype.Container {
return false, 0
}
- c := s.instance.(*containerLXC)
+ c := s.instance.(*instanceDrivers.LXC)
err := c.Migrate(&criuMigrationArgs)
if err != nil {
@@ -241,14 +242,14 @@ type preDumpLoopArgs struct {
// of memory pages transferred by pre-dumping has been reached.
func (s *migrationSourceWs) preDumpLoop(args *preDumpLoopArgs) (bool, error) {
// Do a CRIU pre-dump
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_PRE_DUMP,
- stop: false,
- actionScript: false,
- preDumpDir: args.preDumpDir,
- dumpDir: args.dumpDir,
- stateDir: args.checkpointDir,
- function: "migration",
+ criuMigrationArgs := instanceDrivers.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_PRE_DUMP,
+ Stop: false,
+ ActionScript: false,
+ PreDumpDir: args.preDumpDir,
+ DumpDir: args.dumpDir,
+ StateDir: args.checkpointDir,
+ Function: "migration",
}
logger.Debugf("Doing another pre-dump in %s", args.preDumpDir)
@@ -259,7 +260,7 @@ func (s *migrationSourceWs) preDumpLoop(args *preDumpLoopArgs) (bool, error) {
return false, fmt.Errorf("Instance is not container type")
}
- c := s.instance.(*containerLXC)
+ c := s.instance.(*instanceDrivers.LXC)
err := c.Migrate(&criuMigrationArgs)
if err != nil {
return final, err
@@ -337,7 +338,7 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
return fmt.Errorf("Instance is not container type")
}
- ct := s.instance.(*containerLXC)
+ ct := s.instance.(*instanceDrivers.LXC)
var offerHeader migration.MigrationHeader
var poolMigrationTypes []migration.Type
@@ -609,14 +610,14 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
}
go func() {
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_DUMP,
- stop: true,
- actionScript: true,
- preDumpDir: preDumpDir,
- dumpDir: "final",
- stateDir: checkpointDir,
- function: "migration",
+ criuMigrationArgs := instanceDrivers.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_DUMP,
+ Stop: true,
+ ActionScript: true,
+ PreDumpDir: preDumpDir,
+ DumpDir: "final",
+ StateDir: checkpointDir,
+ Function: "migration",
}
// Do the final CRIU dump. This is needs no special handling if
@@ -636,14 +637,14 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
} else {
logger.Debugf("The version of liblxc is older than 2.0.4 and the live migration will probably fail")
defer os.RemoveAll(checkpointDir)
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_DUMP,
- stateDir: checkpointDir,
- function: "migration",
- stop: true,
- actionScript: false,
- dumpDir: "final",
- preDumpDir: "",
+ criuMigrationArgs := instanceDrivers.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_DUMP,
+ StateDir: checkpointDir,
+ Function: "migration",
+ Stop: true,
+ ActionScript: false,
+ DumpDir: "final",
+ PreDumpDir: "",
}
err = ct.Migrate(&criuMigrationArgs)
@@ -1044,7 +1045,7 @@ func (c *migrationSink) Do(state *state.State, migrateOp *operations.Operation)
// stream, then at the end we need to record that map as last_state so that
// LXD can shift on startup if needed.
if c.src.instance.Type() == instancetype.Container {
- ct := c.src.instance.(*containerLXC)
+ ct := c.src.instance.(*instanceDrivers.LXC)
err = resetContainerDiskIdmap(ct, srcIdmap)
if err != nil {
fsTransfer <- err
@@ -1122,20 +1123,20 @@ func (c *migrationSink) Do(state *state.State, migrateOp *operations.Operation)
}
if live {
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_RESTORE,
- stateDir: imagesDir,
- function: "migration",
- stop: false,
- actionScript: false,
- dumpDir: "final",
- preDumpDir: "",
+ criuMigrationArgs := instanceDrivers.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_RESTORE,
+ StateDir: imagesDir,
+ Function: "migration",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "final",
+ PreDumpDir: "",
}
// Currently we only do a single CRIU pre-dump so we can hardcode "final"
// here since we know that "final" is the folder for CRIU's final dump.
if c.src.instance.Type() == instancetype.Container {
- ct := c.src.instance.(*containerLXC)
+ ct := c.src.instance.(*instanceDrivers.LXC)
err = ct.Migrate(&criuMigrationArgs)
if err != nil {
restore <- err
From 97f6c1b99a561d8d6bca4df007eddf91bf23a436 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:11:53 +0000
Subject: [PATCH 30/50] lxd/patches: Updates patchContainerConfigRegen to use
LXC.SaveConfigFile()
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/patches.go | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/lxd/patches.go b/lxd/patches.go
index bd13a029eb..beb4c0c0a4 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -19,6 +19,7 @@ import (
"github.com/lxc/lxd/lxd/db/query"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/rsync"
driver "github.com/lxc/lxd/lxd/storage"
storagePools "github.com/lxc/lxd/lxd/storage"
@@ -2068,34 +2069,24 @@ func patchContainerConfigRegen(name string, d *Daemon) error {
for _, ct := range cts {
// Load the container from the database.
- c, err := instance.LoadByProjectAndName(d.State(), "default", ct)
+ inst, err := instance.LoadByProjectAndName(d.State(), "default", ct)
if err != nil {
logger.Errorf("Failed to open container '%s': %v", ct, err)
continue
}
- if !c.IsRunning() {
+ if !inst.IsRunning() {
continue
}
- lxcCt, ok := c.(*containerLXC)
+ c, ok := inst.(*instanceDrivers.LXC)
if !ok {
continue
}
- err = lxcCt.initLXC(true)
+ err = c.SaveConfigFile()
if err != nil {
- logger.Errorf("Failed to generate LXC config for '%s': %v", ct, err)
- continue
- }
-
- // Generate the LXC config
- configPath := filepath.Join(lxcCt.LogPath(), "lxc.conf")
- err = lxcCt.c.SaveConfigFile(configPath)
- if err != nil {
- os.Remove(configPath)
- logger.Errorf("Failed to save LXC config for '%s': %v", ct, err)
- continue
+ logger.Errorf("Failed to save LXC config for %q: %v", c.Name(), err)
}
}
From 40dad27633a2ae4299528fad90d55e0ff48c2fe1 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:12:17 +0000
Subject: [PATCH 31/50] lxd/patches: BTRFS storage functions usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/patches.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lxd/patches.go b/lxd/patches.go
index beb4c0c0a4..b4a7fbca5f 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -3321,17 +3321,17 @@ func patchStorageApiRenameContainerSnapshotsDir(name string, d *Daemon) error {
// Disable the read-only properties
if hasBtrfs {
path := snapshotsDir.Name()
- subvols, _ := btrfsSubVolumesGet(path)
+ subvols, _ := storageDrivers.BTRFSSubVolumesGet(path)
for _, subvol := range subvols {
subvol = filepath.Join(path, subvol)
newSubvol := filepath.Join(shared.VarPath("storage-pools", poolName, "containers-snapshots", entry), subvol)
- if !btrfsSubVolumeIsRo(subvol) {
+ if !storageDrivers.BTRFSSubVolumeIsRo(subvol) {
continue
}
- btrfsSubVolumeMakeRw(subvol)
- defer btrfsSubVolumeMakeRo(newSubvol)
+ storageDrivers.BTRFSSubVolumeMakeRw(subvol)
+ defer storageDrivers.BTRFSSubVolumeMakeRo(newSubvol)
}
}
From 2d7f17eba1aecaf42bafa828308077df44fb9d72 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:12:47 +0000
Subject: [PATCH 32/50] lxd/patches/utils: storageDrivers.BTRFSSubVolumesGet
and removes unused functions
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/patches_utils.go | 74 ++------------------------------------------
1 file changed, 2 insertions(+), 72 deletions(-)
diff --git a/lxd/patches_utils.go b/lxd/patches_utils.go
index c58f4b2007..41182c8016 100644
--- a/lxd/patches_utils.go
+++ b/lxd/patches_utils.go
@@ -11,10 +11,9 @@ import (
"strings"
"syscall"
- "golang.org/x/sys/unix"
-
"github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/state"
+ storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/units"
)
@@ -102,7 +101,7 @@ func btrfsSubVolumeDelete(subvol string) error {
func btrfsSubVolumesDelete(subvol string) error {
// Delete subsubvols.
- subsubvols, err := btrfsSubVolumesGet(subvol)
+ subsubvols, err := storageDrivers.BTRFSSubVolumesGet(subvol)
if err != nil {
return err
}
@@ -155,75 +154,6 @@ func btrfsSnapshot(s *state.State, source string, dest string, readonly bool) er
return err
}
-func btrfsIsSubVolume(subvolPath string) bool {
- fs := unix.Stat_t{}
- err := unix.Lstat(subvolPath, &fs)
- if err != nil {
- return false
- }
-
- // Check if BTRFS_FIRST_FREE_OBJECTID
- if fs.Ino != 256 {
- return false
- }
-
- return true
-}
-
-func btrfsSubVolumeIsRo(path string) bool {
- output, err := shared.RunCommand("btrfs", "property", "get", "-ts", path)
- if err != nil {
- return false
- }
-
- return strings.HasPrefix(string(output), "ro=true")
-}
-
-func btrfsSubVolumeMakeRo(path string) error {
- _, err := shared.RunCommand("btrfs", "property", "set", "-ts", path, "ro", "true")
- return err
-}
-
-func btrfsSubVolumeMakeRw(path string) error {
- _, err := shared.RunCommand("btrfs", "property", "set", "-ts", path, "ro", "false")
- return err
-}
-
-func btrfsSubVolumesGet(path string) ([]string, error) {
- result := []string{}
-
- if !strings.HasSuffix(path, "/") {
- path = path + "/"
- }
-
- // Unprivileged users can't get to fs internals
- filepath.Walk(path, func(fpath string, fi os.FileInfo, err error) error {
- // Skip walk errors
- if err != nil {
- return nil
- }
-
- // Ignore the base path
- if strings.TrimRight(fpath, "/") == strings.TrimRight(path, "/") {
- return nil
- }
-
- // Subvolumes can only be directories
- if !fi.IsDir() {
- return nil
- }
-
- // Check if a btrfs subvolume
- if btrfsIsSubVolume(fpath) {
- result = append(result, strings.TrimPrefix(fpath, path))
- }
-
- return nil
- })
-
- return result, nil
-}
-
// For 'lvm' storage backend.
func lvmLVRename(vgName string, oldName string, newName string) error {
_, err := shared.TryRunCommand("lvrename", vgName, oldName, newName)
From 468c7d6e56af0ee7b9bac2769d2ceb3760f37ffe Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:13:35 +0000
Subject: [PATCH 33/50] lxd/storage: instanceDrivers.LXC usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage.go | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/lxd/storage.go b/lxd/storage.go
index e0c848e8ac..3bf0a5d3df 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -11,6 +11,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/state"
storagePools "github.com/lxc/lxd/lxd/storage"
@@ -46,7 +47,7 @@ func readStoragePoolDriversCache() map[string]string {
return drivers.(map[string]string)
}
-func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName string, volumeType int, c *containerLXC) error {
+func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName string, volumeType int, c *instanceDrivers.LXC) error {
// Load the DB records
poolID, pool, err := s.Cluster.StoragePoolGet(poolName)
if err != nil {
@@ -121,7 +122,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName
continue
}
- ct := instt.(*containerLXC)
+ ct := instt.(*instanceDrivers.LXC)
var ctNextIdmap *idmap.IdmapSet
if ct.IsRunning() {
@@ -206,7 +207,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName
return nil
}
-func resetContainerDiskIdmap(container *containerLXC, srcIdmap *idmap.IdmapSet) error {
+func resetContainerDiskIdmap(container *instanceDrivers.LXC, srcIdmap *idmap.IdmapSet) error {
dstIdmap, err := container.DiskIdmap()
if err != nil {
return err
@@ -332,7 +333,7 @@ func storagePoolDriversCacheUpdate(s *state.State) {
// storageVolumeMount initialises a new storage interface and checks the pool and volume are
// mounted. If they are not then they are mounted.
func storageVolumeMount(state *state.State, poolName string, volumeName string, volumeTypeName string, inst instance.Instance) error {
- c, ok := inst.(*containerLXC)
+ c, ok := inst.(*instanceDrivers.LXC)
if !ok {
return fmt.Errorf("Received non-LXC container instance")
}
From 44b7fcbb26dce5b3bf1780f33b0a7804679a2d1e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:14:02 +0000
Subject: [PATCH 34/50] lxd/storage: storageDrivers util functions usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/storage.go b/lxd/storage.go
index 3bf0a5d3df..50ccee93ab 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -70,7 +70,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName
// Get the on-disk idmap for the volume
var lastIdmap *idmap.IdmapSet
if poolVolumePut.Config["volatile.idmap.last"] != "" {
- lastIdmap, err = idmapsetFromString(poolVolumePut.Config["volatile.idmap.last"])
+ lastIdmap, err = storageDrivers.IDMapsetFromString(poolVolumePut.Config["volatile.idmap.last"])
if err != nil {
logger.Errorf("Failed to unmarshal last idmapping: %s", poolVolumePut.Config["volatile.idmap.last"])
return err
@@ -153,7 +153,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName
var err error
if pool.Driver == "zfs" {
- err = lastIdmap.UnshiftRootfs(remapPath, shiftZfsSkipper)
+ err = lastIdmap.UnshiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
} else {
err = lastIdmap.UnshiftRootfs(remapPath, nil)
}
@@ -171,7 +171,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName
var err error
if pool.Driver == "zfs" {
- err = nextIdmap.ShiftRootfs(remapPath, shiftZfsSkipper)
+ err = nextIdmap.ShiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
} else {
err = nextIdmap.ShiftRootfs(remapPath, nil)
}
From 18db5b9da6aed737ede3bf153832a41ab3557b51 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Thu, 27 Feb 2020 18:14:21 +0000
Subject: [PATCH 35/50] lxd/storage/drivers/utils: Adds util functions moved
from main pkg
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/drivers/utils.go | 140 +++++++++++++++++++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index cae780a036..66b85d81f5 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -1,11 +1,13 @@
package drivers
import (
+ "encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
+ "sort"
"strings"
"time"
@@ -14,6 +16,7 @@ import (
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/units"
)
@@ -581,3 +584,140 @@ func copyDevice(inputPath, outputPath string) error {
func loopFilePath(poolName string) string {
return filepath.Join(shared.VarPath("disks"), fmt.Sprintf("%s.img", poolName))
}
+
+func ShiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
+ return shiftBtrfsRootfs(path, diskIdmap, true)
+}
+
+func UnshiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
+ return shiftBtrfsRootfs(path, diskIdmap, false)
+}
+
+func shiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet, shift bool) error {
+ var err error
+ roSubvols := []string{}
+ subvols, _ := BTRFSSubVolumesGet(path)
+ sort.Sort(sort.StringSlice(subvols))
+ for _, subvol := range subvols {
+ subvol = filepath.Join(path, subvol)
+
+ if !BTRFSSubVolumeIsRo(subvol) {
+ continue
+ }
+
+ roSubvols = append(roSubvols, subvol)
+ BTRFSSubVolumeMakeRw(subvol)
+ }
+
+ if shift {
+ err = diskIdmap.ShiftRootfs(path, nil)
+ } else {
+ err = diskIdmap.UnshiftRootfs(path, nil)
+ }
+
+ for _, subvol := range roSubvols {
+ BTRFSSubVolumeMakeRo(subvol)
+ }
+
+ return err
+}
+
+// BTRFSSubVolumesGet gets subvolumes.
+func BTRFSSubVolumesGet(path string) ([]string, error) {
+ result := []string{}
+
+ if !strings.HasSuffix(path, "/") {
+ path = path + "/"
+ }
+
+ // Unprivileged users can't get to fs internals
+ filepath.Walk(path, func(fpath string, fi os.FileInfo, err error) error {
+ // Skip walk errors
+ if err != nil {
+ return nil
+ }
+
+ // Ignore the base path
+ if strings.TrimRight(fpath, "/") == strings.TrimRight(path, "/") {
+ return nil
+ }
+
+ // Subvolumes can only be directories
+ if !fi.IsDir() {
+ return nil
+ }
+
+ // Check if a btrfs subvolume
+ if btrfsIsSubVolume(fpath) {
+ result = append(result, strings.TrimPrefix(fpath, path))
+ }
+
+ return nil
+ })
+
+ return result, nil
+}
+
+func btrfsIsSubVolume(subvolPath string) bool {
+ fs := unix.Stat_t{}
+ err := unix.Lstat(subvolPath, &fs)
+ if err != nil {
+ return false
+ }
+
+ // Check if BTRFS_FIRST_FREE_OBJECTID
+ if fs.Ino != 256 {
+ return false
+ }
+
+ return true
+}
+
+// BTRFSSubVolumeIsRo returns if subvolume is read only.
+func BTRFSSubVolumeIsRo(path string) bool {
+ output, err := shared.RunCommand("btrfs", "property", "get", "-ts", path)
+ if err != nil {
+ return false
+ }
+
+ return strings.HasPrefix(string(output), "ro=true")
+}
+
+// BTRFSSubVolumeMakeRo makes a subvolume read only.
+func BTRFSSubVolumeMakeRo(path string) error {
+ _, err := shared.RunCommand("btrfs", "property", "set", "-ts", path, "ro", "true")
+ return err
+}
+
+// BTRFSSubVolumeMakeRw makes a sub volume read/write.
+func BTRFSSubVolumeMakeRw(path string) error {
+ _, err := shared.RunCommand("btrfs", "property", "set", "-ts", path, "ro", "false")
+ return err
+}
+
+func IDMapsetFromString(idmapString string) (*idmap.IdmapSet, error) {
+ lastIdmap := new(idmap.IdmapSet)
+ err := json.Unmarshal([]byte(idmapString), &lastIdmap.Idmap)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(lastIdmap.Idmap) == 0 {
+ return nil, nil
+ }
+
+ return lastIdmap, nil
+}
+
+func ShiftZFSSkipper(dir string, absPath string, fi os.FileInfo) bool {
+ strippedPath := absPath
+ if dir != "" {
+ strippedPath = absPath[len(dir):]
+ }
+
+ if fi.IsDir() && strippedPath == "/.zfs/snapshot" {
+ return true
+ }
+
+ return false
+}
From df98227c3661cab94e53c2670ad827e3c2b3434d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:04:27 +0000
Subject: [PATCH 36/50] lxd/apparmor/apparmor: Removes dependency on
c.DaemonState()
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/apparmor/apparmor.go | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/lxd/apparmor/apparmor.go b/lxd/apparmor/apparmor.go
index e7119d3cc1..54533e325f 100644
--- a/lxd/apparmor/apparmor.go
+++ b/lxd/apparmor/apparmor.go
@@ -503,7 +503,6 @@ type instance interface {
Project() string
Name() string
IsNesting() bool
- DaemonState() *state.State
IsPrivileged() bool
ExpandedConfig() map[string]string
}
@@ -544,7 +543,7 @@ func profileShort(c instance) string {
// getProfileContent generates the apparmor profile template from the given container.
// This includes the stock lxc includes as well as stuff from raw.apparmor.
-func getAAProfileContent(c instance) string {
+func getAAProfileContent(state *state.State, c instance) string {
profile := strings.TrimLeft(profileBase, "\n")
// Apply new features
@@ -566,7 +565,6 @@ func getAAProfileContent(c instance) string {
profile += " mount fstype=cgroup2 -> /sys/fs/cgroup/**,\n"
}
- state := c.DaemonState()
if state.OS.AppArmorStacking && !state.OS.AppArmorStacked {
profile += "\n ### Feature: apparmor stacking\n"
profile += ` ### Configuration: apparmor profile loading (in namespace)
@@ -633,8 +631,7 @@ profile "%s" flags=(attach_disconnected,mediate_deleted) {
`, ProfileFull(c), strings.Trim(profile, "\n"))
}
-func runApparmor(command string, c instance) error {
- state := c.DaemonState()
+func runApparmor(state *state.State, command string, c instance) error {
if !state.OS.AppArmorAvailable {
return nil
}
@@ -674,8 +671,7 @@ func getCacheDir() string {
return strings.TrimSpace(output)
}
-func mkApparmorNamespace(c instance, namespace string) error {
- state := c.DaemonState()
+func mkApparmorNamespace(state *state.State, c instance, namespace string) error {
if !state.OS.AppArmorStacking || state.OS.AppArmorStacked {
return nil
}
@@ -689,13 +685,12 @@ func mkApparmorNamespace(c instance, namespace string) error {
}
// LoadProfile ensures that the instances's policy is loaded into the kernel so the it can boot.
-func LoadProfile(c instance) error {
- state := c.DaemonState()
+func LoadProfile(state *state.State, c instance) error {
if !state.OS.AppArmorAdmin {
return nil
}
- if err := mkApparmorNamespace(c, Namespace(c)); err != nil {
+ if err := mkApparmorNamespace(state, c, Namespace(c)); err != nil {
return err
}
@@ -716,7 +711,7 @@ func LoadProfile(c instance) error {
return err
}
- updated := getAAProfileContent(c)
+ updated := getAAProfileContent(state, c)
if string(content) != string(updated) {
if err := os.MkdirAll(path.Join(aaPath, "cache"), 0700); err != nil {
@@ -732,13 +727,12 @@ func LoadProfile(c instance) error {
}
}
- return runApparmor(cmdLoad, c)
+ return runApparmor(state, cmdLoad, c)
}
// Destroy ensures that the instances's policy namespace is unloaded to free kernel memory.
// This does not delete the policy from disk or cache.
-func Destroy(c instance) error {
- state := c.DaemonState()
+func Destroy(state *state.State, c instance) error {
if !state.OS.AppArmorAdmin {
return nil
}
@@ -750,22 +744,20 @@ func Destroy(c instance) error {
}
}
- return runApparmor(cmdUnload, c)
+ return runApparmor(state, cmdUnload, c)
}
// ParseProfile parses the profile without loading it into the kernel.
-func ParseProfile(c instance) error {
- state := c.DaemonState()
+func ParseProfile(state *state.State, c instance) error {
if !state.OS.AppArmorAvailable {
return nil
}
- return runApparmor(cmdParse, c)
+ return runApparmor(state, cmdParse, c)
}
// DeleteProfile removes the policy from cache/disk.
-func DeleteProfile(c instance) {
- state := c.DaemonState()
+func DeleteProfile(state *state.State, c instance) {
if !state.OS.AppArmorAdmin {
return
}
From d1a11dce1a6084f29afad85015998cc0608bee85 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:05:00 +0000
Subject: [PATCH 37/50] lxd/container/snapshot: Removes dependency on
sc.DaemonState()
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_snapshot.go | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lxd/container_snapshot.go b/lxd/container_snapshot.go
index 78b817b6dc..313f928bd5 100644
--- a/lxd/container_snapshot.go
+++ b/lxd/container_snapshot.go
@@ -16,6 +16,7 @@ import (
"github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/response"
+ "github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
@@ -220,7 +221,7 @@ func containerSnapshotHandler(d *Daemon, r *http.Request) response.Response {
case "POST":
return snapshotPost(d, r, inst, containerName)
case "DELETE":
- return snapshotDelete(inst, snapshotName)
+ return snapshotDelete(d.State(), inst, snapshotName)
case "PUT":
return snapshotPut(d, r, inst, snapshotName)
default:
@@ -425,7 +426,7 @@ func snapshotPost(d *Daemon, r *http.Request, sc instance.Instance, containerNam
return operations.OperationResponse(op)
}
-func snapshotDelete(sc instance.Instance, name string) response.Response {
+func snapshotDelete(s *state.State, sc instance.Instance, name string) response.Response {
remove := func(op *operations.Operation) error {
return sc.Delete()
}
@@ -433,7 +434,7 @@ func snapshotDelete(sc instance.Instance, name string) response.Response {
resources := map[string][]string{}
resources["containers"] = []string{sc.Name()}
- op, err := operations.OperationCreate(sc.DaemonState(), sc.Project(), operations.OperationClassTask, db.OperationSnapshotDelete, resources, nil, remove, nil, nil)
+ op, err := operations.OperationCreate(s, sc.Project(), operations.OperationClassTask, db.OperationSnapshotDelete, resources, nil, remove, nil, nil)
if err != nil {
return response.InternalError(err)
}
From 450eb972d802e3aa5e14653296be75728fcc743d Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:05:20 +0000
Subject: [PATCH 38/50] lxd/container/test: instanceDrivers.PrepareEqualTest
usage to fix crash
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_test.go | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/lxd/container_test.go b/lxd/container_test.go
index 41335c5d90..8804213f77 100644
--- a/lxd/container_test.go
+++ b/lxd/container_test.go
@@ -9,6 +9,7 @@ import (
"github.com/lxc/lxd/lxd/db"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
+ instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
"github.com/lxc/lxd/lxd/instance/instancetype"
driver "github.com/lxc/lxd/lxd/storage"
"github.com/lxc/lxd/shared"
@@ -141,12 +142,7 @@ func (suite *containerTestSuite) TestContainer_LoadFromDB() {
_, err = c2.StorageStart()
suite.Req.Nil(err)
- // When loading from DB, we won't have a full LXC config
- c.(*instanceDrivers.LXC).c = nil
- c.(*instanceDrivers.LXC).cConfig = false
- c2.(*instanceDrivers.LXC).c = nil
- c2.(*instanceDrivers.LXC).cConfig = false
-
+ instanceDrivers.PrepareEqualTest(c, c2)
suite.Exactly(
c,
c2,
From 6335777e6dcf49a727c657ebd822ee035ba9b5fc Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:08:06 +0000
Subject: [PATCH 39/50] lxd/instance/drivers/driver/lxc: golint fixes
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 132 ++++++++++++++++++++---------
1 file changed, 90 insertions(+), 42 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 7054d2cb92..48175d9148 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -429,7 +429,7 @@ type CriuMigrationArgs struct {
Features liblxc.CriuFeatures
}
-// The LXC container driver
+// The LXC container driver.
type LXC struct {
// Properties
architecture int
@@ -473,6 +473,7 @@ type LXC struct {
expiryDate time.Time
}
+// Type returns the instance type.
func (c *LXC) Type() instancetype.Type {
return c.dbType
}
@@ -2251,6 +2252,7 @@ func (c *LXC) detachInterfaceRename(netns string, ifName string, hostName string
return nil
}
+// Start starts the instance.
func (c *LXC) Start(stateful bool) error {
var ctxMap log.Ctx
@@ -2403,6 +2405,7 @@ func (c *LXC) Start(stateful bool) error {
return nil
}
+// OnStart implements the start hook.
func (c *LXC) OnStart() error {
// Make sure we can't call go-lxc functions by mistake
c.fromHook = true
@@ -2634,6 +2637,7 @@ func (c *LXC) Stop(stateful bool) error {
return nil
}
+// Shutdown stops the instance.
func (c *LXC) Shutdown(timeout time.Duration) error {
var ctxMap log.Ctx
@@ -2839,7 +2843,7 @@ func (c *LXC) cleanupDevices(netns string) {
}
}
-// Freezer functions
+// Freeze functions.
func (c *LXC) Freeze() error {
ctxMap := log.Ctx{
"project": c.project,
@@ -2893,6 +2897,7 @@ func (c *LXC) Freeze() error {
return err
}
+// Unfreeze unfreezes the instance.
func (c *LXC) Unfreeze() error {
ctxMap := log.Ctx{
"project": c.project,
@@ -2943,8 +2948,6 @@ func (c *LXC) Unfreeze() error {
return err
}
-var LxcMonitorStateError = fmt.Errorf("Monitor is hung")
-
// Get lxc container state, with 1 second timeout
// If we don't get a reply, assume the lxc monitor is hung
func (c *LXC) getLxcState() (liblxc.State, error) {
@@ -2968,10 +2971,11 @@ func (c *LXC) getLxcState() (liblxc.State, error) {
case state := <-monitor:
return state, nil
case <-time.After(5 * time.Second):
- return liblxc.StateMap["FROZEN"], LxcMonitorStateError
+ return liblxc.StateMap["FROZEN"], fmt.Errorf("Monitor is hung")
}
}
+// Render renders the state of the instance.
func (c *LXC) Render() (interface{}, interface{}, error) {
// Ignore err as the arch string on error is correct (unknown)
architectureName, _ := osarch.ArchitectureName(c.architecture)
@@ -3031,6 +3035,7 @@ func (c *LXC) Render() (interface{}, interface{}, error) {
return &ct, etag, nil
}
+// RenderFull renders the full state of the instance.
func (c *LXC) RenderFull() (*api.InstanceFull, interface{}, error) {
if c.IsSnapshot() {
return nil, nil, fmt.Errorf("RenderFull only works with containers")
@@ -3089,6 +3094,7 @@ func (c *LXC) RenderFull() (*api.InstanceFull, interface{}, error) {
return &ct, etag, nil
}
+// RenderState renders just the running state of the instance.
func (c *LXC) RenderState() (*api.InstanceState, error) {
cState, err := c.getLxcState()
if err != nil {
@@ -3113,6 +3119,7 @@ func (c *LXC) RenderState() (*api.InstanceState, error) {
return &status, nil
}
+// Snapshots returns the snapshots of the instance.
func (c *LXC) Snapshots() ([]instance.Instance, error) {
var snaps []db.Instance
@@ -3148,6 +3155,7 @@ func (c *LXC) Snapshots() ([]instance.Instance, error) {
return instances, nil
}
+// Backups returns the backups of the instance.
func (c *LXC) Backups() ([]backup.Backup, error) {
// Get all the backups
backupNames, err := c.state.Cluster.ContainerGetBackups(c.project, c.name)
@@ -3358,6 +3366,7 @@ func (c *LXC) cleanup() {
os.RemoveAll(c.ShmountsPath())
}
+// Delete deletes the instance.
func (c *LXC) Delete() error {
ctxMap := log.Ctx{
"project": c.project,
@@ -3472,6 +3481,7 @@ func (c *LXC) Delete() error {
return nil
}
+// Rename renames the instance.
func (c *LXC) Rename(newName string) error {
oldName := c.Name()
ctxMap := log.Ctx{
@@ -3618,6 +3628,7 @@ func (c *LXC) Rename(newName string) error {
return nil
}
+// CGroupGet gets a cgroup value for the instance.
func (c *LXC) CGroupGet(key string) (string, error) {
// Load the go-lxc struct
err := c.initLXC(false)
@@ -3634,6 +3645,7 @@ func (c *LXC) CGroupGet(key string) (string, error) {
return strings.Join(value, "\n"), nil
}
+// CGroupSet sets a cgroup value for the instance.
func (c *LXC) CGroupSet(key string, value string) error {
// Load the go-lxc struct
err := c.initLXC(false)
@@ -3654,6 +3666,7 @@ func (c *LXC) CGroupSet(key string, value string) error {
return nil
}
+// VolatileSet sets volatile config.
func (c *LXC) VolatileSet(changes map[string]string) error {
// Sanity check
for key := range changes {
@@ -3692,6 +3705,7 @@ func (c *LXC) VolatileSet(changes map[string]string) error {
return nil
}
+// Update applies updated config.
func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
// Set sane defaults for unset keys
if args.Project == "" {
@@ -4470,6 +4484,7 @@ func (c *LXC) updateDevices(removeDevices deviceConfig.Devices, addDevices devic
return nil
}
+// Export backs up the instance.
func (c *LXC) Export(w io.Writer, properties map[string]string) error {
ctxMap := log.Ctx{
"project": c.project,
@@ -4717,6 +4732,7 @@ func getCRIULogErrors(imagesDir string, method string) (string, error) {
return strings.Join(ret, "\n"), nil
}
+// Migrate migrates the instance to another node.
func (c *LXC) Migrate(args *CriuMigrationArgs) error {
ctxMap := log.Ctx{
"project": c.project,
@@ -4954,18 +4970,18 @@ func (c *LXC) templateApplyNow(trigger string) error {
return errors.Wrapf(err, "Could not parse %s", fname)
}
- // Find rootUid and rootGid
+ // Find rootUID and rootGID
idmapset, err := c.DiskIdmap()
if err != nil {
return errors.Wrap(err, "Failed to set ID map")
}
- rootUid := int64(0)
- rootGid := int64(0)
+ rootUID := int64(0)
+ rootGID := int64(0)
// Get the right uid and gid for the container
if idmapset != nil {
- rootUid, rootGid = idmapset.ShiftIntoNs(0, 0)
+ rootUID, rootGID = idmapset.ShiftIntoNs(0, 0)
}
// Figure out the container architecture
@@ -5025,7 +5041,7 @@ func (c *LXC) templateApplyNow(trigger string) error {
}
} else {
// Create the directories leading to the file
- shared.MkdirAllOwner(path.Dir(fullpath), 0755, int(rootUid), int(rootGid))
+ shared.MkdirAllOwner(path.Dir(fullpath), 0755, int(rootUID), int(rootGID))
// Create the file itself
w, err = os.Create(fullpath)
@@ -5034,7 +5050,7 @@ func (c *LXC) templateApplyNow(trigger string) error {
}
// Fix ownership and mode
- w.Chown(int(rootUid), int(rootGid))
+ w.Chown(int(rootUID), int(rootGID))
w.Chmod(0644)
}
defer w.Close()
@@ -5076,6 +5092,7 @@ func (c *LXC) templateApplyNow(trigger string) error {
return nil
}
+// FileExists returns whether file exists inside instance.
func (c *LXC) FileExists(path string) error {
// Setup container storage if needed
var ourStart bool
@@ -5124,6 +5141,7 @@ func (c *LXC) FileExists(path string) error {
return nil
}
+// FilePull gets a file from the instance.
func (c *LXC) FilePull(srcpath string, dstpath string) (int64, int64, os.FileMode, string, []string, error) {
// Check for ongoing operations (that may involve shifting).
op := operationlock.Get(c.id)
@@ -5164,7 +5182,7 @@ func (c *LXC) FilePull(srcpath string, dstpath string) (int64, int64, os.FileMod
uid := int64(-1)
gid := int64(-1)
mode := -1
- type_ := "unknown"
+ fileType := "unknown"
var dirEnts []string
var errStr string
@@ -5220,7 +5238,7 @@ func (c *LXC) FilePull(srcpath string, dstpath string) (int64, int64, os.FileMod
}
if strings.HasPrefix(line, "type: ") {
- type_ = strings.TrimPrefix(line, "type: ")
+ fileType = strings.TrimPrefix(line, "type: ")
continue
}
@@ -5250,18 +5268,19 @@ func (c *LXC) FilePull(srcpath string, dstpath string) (int64, int64, os.FileMod
}
}
- return uid, gid, os.FileMode(mode), type_, dirEnts, nil
+ return uid, gid, os.FileMode(mode), fileType, dirEnts, nil
}
-func (c *LXC) FilePush(type_ string, srcpath string, dstpath string, uid int64, gid int64, mode int, write string) error {
+// FilePush sends a file into the instance.
+func (c *LXC) FilePush(fileType string, srcpath string, dstpath string, uid int64, gid int64, mode int, write string) error {
// Check for ongoing operations (that may involve shifting).
op := operationlock.Get(c.id)
if op != nil {
op.Wait()
}
- var rootUid int64
- var rootGid int64
+ var rootUID int64
+ var rootGID int64
var errStr string
// Map uid and gid if needed
@@ -5273,7 +5292,7 @@ func (c *LXC) FilePush(type_ string, srcpath string, dstpath string, uid int64,
if idmapset != nil {
uid, gid = idmapset.ShiftIntoNs(uid, gid)
- rootUid, rootGid = idmapset.ShiftIntoNs(0, 0)
+ rootUID, rootGID = idmapset.ShiftIntoNs(0, 0)
}
}
@@ -5288,7 +5307,7 @@ func (c *LXC) FilePush(type_ string, srcpath string, dstpath string, uid int64,
}
defaultMode := 0640
- if type_ == "directory" {
+ if fileType == "directory" {
defaultMode = 0750
}
@@ -5302,12 +5321,12 @@ func (c *LXC) FilePush(type_ string, srcpath string, dstpath string, uid int64,
fmt.Sprintf("%d", c.InitPID()),
srcpath,
dstpath,
- type_,
+ fileType,
fmt.Sprintf("%d", uid),
fmt.Sprintf("%d", gid),
fmt.Sprintf("%d", mode),
- fmt.Sprintf("%d", rootUid),
- fmt.Sprintf("%d", rootGid),
+ fmt.Sprintf("%d", rootUID),
+ fmt.Sprintf("%d", rootGID),
fmt.Sprintf("%d", int(os.FileMode(defaultMode)&os.ModePerm)),
write,
)
@@ -5349,6 +5368,7 @@ func (c *LXC) FilePush(type_ string, srcpath string, dstpath string, uid int64,
return nil
}
+// FileRemove removes a file inside the instance.
func (c *LXC) FileRemove(path string) error {
var errStr string
var ourStart bool
@@ -5410,6 +5430,7 @@ func (c *LXC) FileRemove(path string) error {
return nil
}
+// Console attaches to the instance console.
func (c *LXC) Console() (*os.File, chan error, error) {
chDisconnect := make(chan error, 1)
@@ -5463,6 +5484,7 @@ func (c *LXC) Console() (*os.File, chan error, error) {
return master, chDisconnect, nil
}
+// ConsoleLog returns console log.
func (c *LXC) ConsoleLog(opts liblxc.ConsoleLogOptions) (string, error) {
msg, err := c.c.ConsoleLog(opts)
if err != nil {
@@ -5472,6 +5494,7 @@ func (c *LXC) ConsoleLog(opts liblxc.ConsoleLogOptions) (string, error) {
return string(msg), nil
}
+// Exec executes a command inside the instance.
func (c *LXC) Exec(req api.InstanceExecPost, stdin *os.File, stdout *os.File, stderr *os.File) (instance.Cmd, error) {
// Prepare the environment
envSlice := []string{}
@@ -5985,6 +6008,7 @@ func (c *LXC) removeMount(mount string) error {
return nil
}
+// InsertSeccompUnixDevice inserts a seccomp device.
func (c *LXC) InsertSeccompUnixDevice(prefix string, m deviceConfig.Device, pid int) error {
if pid < 0 {
return fmt.Errorf("Invalid request PID specified")
@@ -6300,36 +6324,39 @@ func (c *LXC) setNetworkPriority() error {
// Check that we at least succeeded to set an entry
success := false
- var last_error error
+ var lastError error
for _, netif := range netifs {
err = cg.SetNetIfPrio(fmt.Sprintf("%s %d", netif.Name, networkInt))
if err == nil {
success = true
} else {
- last_error = err
+ lastError = err
}
}
if !success {
- return fmt.Errorf("Failed to set network device priority: %s", last_error)
+ return fmt.Errorf("Failed to set network device priority: %s", lastError)
}
return nil
}
-// Various state query functions
+// IsStateful returns is instance is stateful.
func (c *LXC) IsStateful() bool {
return c.stateful
}
+// IsEphemeral returns if instance is ephemeral.
func (c *LXC) IsEphemeral() bool {
return c.ephemeral
}
+// IsFrozen returns if instance is frozen.
func (c *LXC) IsFrozen() bool {
return c.State() == "FROZEN"
}
+// IsNesting returns if instance is nested.
func (c *LXC) IsNesting() bool {
return shared.IsTrue(c.expandedConfig["security.nesting"])
}
@@ -6347,43 +6374,53 @@ func (c *LXC) isCurrentlyPrivileged() bool {
return idmap == nil
}
+// IsPrivileged returns if instance is privileged.
func (c *LXC) IsPrivileged() bool {
return shared.IsTrue(c.expandedConfig["security.privileged"])
}
+// IsRunning returns if instance is running.
func (c *LXC) IsRunning() bool {
state := c.State()
return state != "BROKEN" && state != "STOPPED"
}
+// IsSnapshot returns if instance is a snapshot.
func (c *LXC) IsSnapshot() bool {
return c.snapshot
}
-// Various property query functions
+// Architecture returns architecture of instance.
func (c *LXC) Architecture() int {
return c.architecture
}
+// CreationDate returns creation date of instance.
func (c *LXC) CreationDate() time.Time {
return c.creationDate
}
+
+// LastUsedDate returns last used date time of instance.
func (c *LXC) LastUsedDate() time.Time {
return c.lastUsedDate
}
+
+// ExpandedConfig returns expanded config.
func (c *LXC) ExpandedConfig() map[string]string {
return c.expandedConfig
}
+// ExpandedDevices returns expanded devices config.
func (c *LXC) ExpandedDevices() deviceConfig.Devices {
return c.expandedDevices
}
-// ID gets container's ID.
+// ID gets instances's ID.
func (c *LXC) ID() int {
return c.id
}
+// InitPID returns PID of init process.
func (c *LXC) InitPID() int {
// Load the go-lxc struct
err := c.initLXC(false)
@@ -6394,14 +6431,17 @@ func (c *LXC) InitPID() int {
return c.c.InitPid()
}
+// LocalConfig returns local config.
func (c *LXC) LocalConfig() map[string]string {
return c.localConfig
}
+// LocalDevices returns local device config.
func (c *LXC) LocalDevices() deviceConfig.Devices {
return c.localDevices
}
+// CurrentIdmap returns current IDMAP.
func (c *LXC) CurrentIdmap() (*idmap.IdmapSet, error) {
jsonIdmap, ok := c.LocalConfig()["volatile.idmap.current"]
if !ok {
@@ -6411,6 +6451,7 @@ func (c *LXC) CurrentIdmap() (*idmap.IdmapSet, error) {
return storageDrivers.IDMapsetFromString(jsonIdmap)
}
+// DiskIdmap returns DISK IDMAP.
func (c *LXC) DiskIdmap() (*idmap.IdmapSet, error) {
jsonIdmap, ok := c.LocalConfig()["volatile.last_state.idmap"]
if !ok {
@@ -6420,6 +6461,7 @@ func (c *LXC) DiskIdmap() (*idmap.IdmapSet, error) {
return storageDrivers.IDMapsetFromString(jsonIdmap)
}
+// NextIdmap returns next IDMAP.
func (c *LXC) NextIdmap() (*idmap.IdmapSet, error) {
jsonIdmap, ok := c.LocalConfig()["volatile.idmap.next"]
if !ok {
@@ -6429,36 +6471,32 @@ func (c *LXC) NextIdmap() (*idmap.IdmapSet, error) {
return storageDrivers.IDMapsetFromString(jsonIdmap)
}
-func (c *LXC) DaemonState() *state.State {
- // FIXME: This function should go away, since the abstract container
- // interface should not be coupled with internal state details.
- // However this is not currently possible, because many
- // higher-level APIs use container variables as "implicit
- // handles" to database/OS state and then need a way to get a
- // reference to it.
- return c.state
-}
-
+// Location returns instance location.
func (c *LXC) Location() string {
return c.node
}
+// Project returns instance project.
func (c *LXC) Project() string {
return c.project
}
+// Name returns instance name.
func (c *LXC) Name() string {
return c.name
}
+// Description returns instance description.
func (c *LXC) Description() string {
return c.description
}
+// Profiles returns instance profiles.
func (c *LXC) Profiles() []string {
return c.profiles
}
+// State returns instance state.
func (c *LXC) State() string {
state, err := c.getLxcState()
if err != nil {
@@ -6467,42 +6505,50 @@ func (c *LXC) State() string {
return state.String()
}
-// Various container paths
+// Path instance path.
func (c *LXC) Path() string {
return storagePools.InstancePath(c.Type(), c.Project(), c.Name(), c.IsSnapshot())
}
+// DevicesPath devices path.
func (c *LXC) DevicesPath() string {
name := project.Prefix(c.Project(), c.Name())
return shared.VarPath("devices", name)
}
+// ShmountsPath shared mounts path.
func (c *LXC) ShmountsPath() string {
name := project.Prefix(c.Project(), c.Name())
return shared.VarPath("shmounts", name)
}
+// LogPath log path.
func (c *LXC) LogPath() string {
name := project.Prefix(c.Project(), c.Name())
return shared.LogPath(name)
}
+// LogFilePath log file path.
func (c *LXC) LogFilePath() string {
return filepath.Join(c.LogPath(), "lxc.log")
}
+// ConsoleBufferLogPath console buffer log path.
func (c *LXC) ConsoleBufferLogPath() string {
return filepath.Join(c.LogPath(), "console.log")
}
+// RootfsPath root filesystem path.
func (c *LXC) RootfsPath() string {
return filepath.Join(c.Path(), "rootfs")
}
+// TemplatesPath templates path.
func (c *LXC) TemplatesPath() string {
return filepath.Join(c.Path(), "templates")
}
+// StatePath state path.
func (c *LXC) StatePath() string {
/* FIXME: backwards compatibility: we used to use Join(RootfsPath(),
* "state"), which was bad. Let's just check to see if that directory
@@ -6515,6 +6561,7 @@ func (c *LXC) StatePath() string {
return filepath.Join(c.Path(), "state")
}
+// StoragePool storage pool name.
func (c *LXC) StoragePool() (string, error) {
poolName, err := c.state.Cluster.InstancePool(c.Project(), c.Name())
if err != nil {
@@ -6524,11 +6571,12 @@ func (c *LXC) StoragePool() (string, error) {
return poolName, nil
}
-// Progress tracking
+// SetOperation handles progress tracking.
func (c *LXC) SetOperation(op *operations.Operation) {
c.op = op
}
+// ExpiryDate sets expiry date.
func (c *LXC) ExpiryDate() time.Time {
if c.IsSnapshot() {
return c.expiryDate
@@ -6554,7 +6602,7 @@ func (c *LXC) updateProgress(progress string) {
}
}
-// Internal MAAS handling
+// Internal MAAS handling.
func (c *LXC) maasInterfaces(devices map[string]map[string]string) ([]maas.ContainerInterface, error) {
interfaces := []maas.ContainerInterface{}
for k, m := range devices {
@@ -6797,7 +6845,7 @@ func (c *LXC) SaveConfigFile() error {
err = c.c.SaveConfigFile(configPath)
if err != nil {
os.Remove(configPath)
- return fmt.Errorf("Failed to save LXC config to file %q", configPath, err)
+ return errors.Wrapf(err, "Failed to save LXC config to file %q", configPath)
}
return nil
From 609b2fedc0008ea45e7f16c2e0b19ddf61200fb4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:08:40 +0000
Subject: [PATCH 40/50] lxd/instance/drivers/driver/lxc: Removes DaemonState
function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 48175d9148..32cea2cba9 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -1007,7 +1007,7 @@ func (c *LXC) initLXC(config bool) error {
// Setup notification socket
// System requirement errors are handled during policy generation instead of here
- ok, err := seccomp.InstanceNeedsIntercept(c)
+ ok, err := seccomp.InstanceNeedsIntercept(c.state, c)
if err == nil && ok {
err = lxcSetConfigItem(cc, "lxc.seccomp.notify.proxy", fmt.Sprintf("unix:%s", shared.VarPath("seccomp.socket")))
if err != nil {
@@ -1992,7 +1992,7 @@ func (c *LXC) startCommon() (string, []func() error, error) {
}
// Generate the Seccomp profile
- if err := seccomp.CreateProfile(c); err != nil {
+ if err := seccomp.CreateProfile(c.state, c); err != nil {
return "", postStartHooks, err
}
@@ -2417,7 +2417,7 @@ func (c *LXC) OnStart() error {
}
// Load the container AppArmor profile
- err = apparmor.LoadProfile(c)
+ err = apparmor.LoadProfile(c.state, c)
if err != nil {
if ourStart {
c.unmount()
@@ -2431,7 +2431,7 @@ func (c *LXC) OnStart() error {
// Run any template that needs running
err = c.templateApplyNow(c.localConfig[key])
if err != nil {
- apparmor.Destroy(c)
+ apparmor.Destroy(c.state, c)
if ourStart {
c.unmount()
}
@@ -2441,7 +2441,7 @@ func (c *LXC) OnStart() error {
// Remove the volatile key from the DB
err := c.state.Cluster.ContainerConfigRemove(c.id, key)
if err != nil {
- apparmor.Destroy(c)
+ apparmor.Destroy(c.state, c)
if ourStart {
c.unmount()
}
@@ -2451,7 +2451,7 @@ func (c *LXC) OnStart() error {
err = c.templateApplyNow("start")
if err != nil {
- apparmor.Destroy(c)
+ apparmor.Destroy(c.state, c)
if ourStart {
c.unmount()
}
@@ -2794,7 +2794,7 @@ func (c *LXC) OnStop(target string) error {
c.IsRunning()
// Unload the apparmor profile
- err = apparmor.Destroy(c)
+ err = apparmor.Destroy(c.state, c)
if err != nil {
logger.Error("Failed to destroy apparmor namespace", log.Ctx{"container": c.Name(), "err": err})
}
@@ -3356,7 +3356,7 @@ func (c *LXC) cleanup() {
c.removeDiskDevices()
// Remove the security profiles
- apparmor.DeleteProfile(c)
+ apparmor.DeleteProfile(c.state, c)
seccomp.DeleteProfile(c)
// Remove the devices path
@@ -3949,7 +3949,7 @@ func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
// If apparmor changed, re-validate the apparmor profile
if shared.StringInSlice("raw.apparmor", changedConfig) || shared.StringInSlice("security.nesting", changedConfig) {
- err = apparmor.ParseProfile(c)
+ err = apparmor.ParseProfile(c.state, c)
if err != nil {
return errors.Wrap(err, "Parse AppArmor profile")
}
@@ -4021,7 +4021,7 @@ func (c *LXC) Update(args db.InstanceArgs, userRequested bool) error {
if key == "raw.apparmor" || key == "security.nesting" {
// Update the AppArmor profile
- err = apparmor.LoadProfile(c)
+ err = apparmor.LoadProfile(c.state, c)
if err != nil {
return err
}
From 058ceaac405f4ebc33b53e6c54db42821e64a73c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:09:35 +0000
Subject: [PATCH 41/50] lxd/instance/drivers/driver/qemu: Adds SaveConfigFile
placeholder
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_qemu.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index ca97f5ccc6..9f01cd8adc 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -975,6 +975,11 @@ func (vm *qemu) RegisterDevices() {
return
}
+// SaveConfigFile is not used by VMs.
+func (vm *qemu) SaveConfigFile() error {
+ return fmt.Errorf("SaveConfigFile Not Implemented")
+}
+
// deviceLoad instantiates and validates a new device and returns it along with enriched config.
func (vm *qemu) deviceLoad(deviceName string, rawConfig deviceConfig.Device) (device.Device, deviceConfig.Device, error) {
var configCopy deviceConfig.Device
From 8b2eb8767cd296496f71e0d5d3f8867df7975992 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:09:48 +0000
Subject: [PATCH 42/50] lxd/instance/drivers/driver/qemu: Removes DaemonState
function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_qemu.go | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 9f01cd8adc..f9a17f58b2 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -3449,17 +3449,6 @@ func (vm *qemu) DeferTemplateApply(trigger string) error {
return nil
}
-// DaemonState returns the state of the daemon. Deprecated.
-func (vm *qemu) DaemonState() *state.State {
- // FIXME: This function should go away, since the abstract instance
- // interface should not be coupled with internal state details.
- // However this is not currently possible, because many
- // higher-level APIs use instance variables as "implicit
- // handles" to database/OS state and then need a way to get a
- // reference to it.
- return vm.state
-}
-
// FillNetworkDevice takes a nic or infiniband device type and enriches it with automatically
// generated name and hwaddr properties if these are missing from the device.
func (vm *qemu) FillNetworkDevice(name string, m deviceConfig.Device) (deviceConfig.Device, error) {
From 54f2159114876f8cf80a21136c8b2a70ed37b304 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:10:08 +0000
Subject: [PATCH 43/50] lxd/instance/drivers/driver/utils: Adds
PrepareEqualTest function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_utils.go | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/lxd/instance/drivers/driver_utils.go b/lxd/instance/drivers/driver_utils.go
index 283fd24b10..1442ea2f2d 100644
--- a/lxd/instance/drivers/driver_utils.go
+++ b/lxd/instance/drivers/driver_utils.go
@@ -5,6 +5,8 @@ import (
"golang.org/x/sys/unix"
+ "github.com/lxc/lxd/lxd/instance"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/shared"
)
@@ -44,3 +46,15 @@ func SetupSharedMounts() error {
sharedMounted = true
return nil
}
+
+// PrepareEqualTest modifies any unexported variables required for reflect.DeepEqual to complete safely.
+// This is used for tests to avoid infinite recursion loops.
+func PrepareEqualTest(insts ...instance.Instance) {
+ for _, inst := range insts {
+ if inst.Type() == instancetype.Container {
+ // When loading from DB, we won't have a full LXC config.
+ inst.(*LXC).c = nil
+ inst.(*LXC).cConfig = false
+ }
+ }
+}
From 89dab3b76dc4eabc074be7caa909415be23d9c55 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:10:29 +0000
Subject: [PATCH 44/50] lxd/instance/instance/interface: Removes DaemonState
function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/instance_interface.go | 2 --
1 file changed, 2 deletions(-)
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
index 8b2a532343..efcf506004 100644
--- a/lxd/instance/instance_interface.go
+++ b/lxd/instance/instance_interface.go
@@ -10,7 +10,6 @@ import (
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"
)
@@ -115,5 +114,4 @@ type Instance interface {
StorageStart() (bool, error)
StorageStop() (bool, error)
DeferTemplateApply(trigger string) error
- DaemonState() *state.State
}
From f9808e19867afdc320ab89d5be7261d6baed1270 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:10:44 +0000
Subject: [PATCH 45/50] lxd/instance/instance/interface: Adds SaveConfigFile
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/instance_interface.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
index efcf506004..4cda3ed62f 100644
--- a/lxd/instance/instance_interface.go
+++ b/lxd/instance/instance_interface.go
@@ -33,6 +33,7 @@ type Instance interface {
Stop(stateful bool) error
Unfreeze() error
RegisterDevices()
+ SaveConfigFile() error
IsPrivileged() bool
From d008524697fbca5339cccc5aefdefa3eddf6fa28 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:11:09 +0000
Subject: [PATCH 46/50] lxd/migrate/container: Removes s.instance.DaemonState
dependency
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/migrate_container.go | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index dba04e7d9b..b54491d86f 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -240,7 +240,7 @@ type preDumpLoopArgs struct {
// This function contains the actual pre-dump, the corresponding rsync
// transfer and it tells the outer loop to abort if the threshold
// of memory pages transferred by pre-dumping has been reached.
-func (s *migrationSourceWs) preDumpLoop(args *preDumpLoopArgs) (bool, error) {
+func (s *migrationSourceWs) preDumpLoop(state *state.State, args *preDumpLoopArgs) (bool, error) {
// Do a CRIU pre-dump
criuMigrationArgs := instanceDrivers.CriuMigrationArgs{
Cmd: lxc.MIGRATE_PRE_DUMP,
@@ -268,7 +268,6 @@ func (s *migrationSourceWs) preDumpLoop(args *preDumpLoopArgs) (bool, error) {
// Send the pre-dump.
ctName, _, _ := shared.InstanceGetParentAndSnapshotName(s.instance.Name())
- state := s.instance.DaemonState()
err = rsync.Send(ctName, shared.AddSlash(args.checkpointDir), &shared.WebsocketIO{Conn: s.criuConn}, nil, args.rsyncFeatures, args.bwlimit, state.OS.ExecPath)
if err != nil {
return final, err
@@ -591,7 +590,7 @@ func (s *migrationSourceWs) Do(state *state.State, migrateOp *operations.Operati
final: final,
rsyncFeatures: rsyncFeatures,
}
- final, err = s.preDumpLoop(&loopArgs)
+ final, err = s.preDumpLoop(state, &loopArgs)
if err != nil {
os.RemoveAll(checkpointDir)
return abort(err)
@@ -901,7 +900,7 @@ func (c *migrationSink) Do(state *state.State, migrateOp *operations.Operation)
// Check if snapshot exists already and if not then create
// a new snapshot DB record so that the storage layer can
// populate the volume on the storage device.
- _, err := instance.LoadByProjectAndName(args.Instance.DaemonState(), args.Instance.Project(), snapArgs.Name)
+ _, err := instance.LoadByProjectAndName(state, args.Instance.Project(), snapArgs.Name)
if err != nil {
// Create the snapshot as it doesn't seem to exist.
_, err := instanceCreateInternal(state, snapArgs)
From 0e40cc7ca1070ad9982683a58452f50bccb6a0e2 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:11:33 +0000
Subject: [PATCH 47/50] lxd/patches: patchContainerConfigRegen cont
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/patches.go | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/lxd/patches.go b/lxd/patches.go
index b4a7fbca5f..b657bdd859 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -19,7 +19,7 @@ import (
"github.com/lxc/lxd/lxd/db/query"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
"github.com/lxc/lxd/lxd/instance"
- instanceDrivers "github.com/lxc/lxd/lxd/instance/drivers"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/rsync"
driver "github.com/lxc/lxd/lxd/storage"
storagePools "github.com/lxc/lxd/lxd/storage"
@@ -2075,18 +2075,17 @@ func patchContainerConfigRegen(name string, d *Daemon) error {
continue
}
- if !inst.IsRunning() {
+ if inst.Type() != instancetype.Container {
continue
}
- c, ok := inst.(*instanceDrivers.LXC)
- if !ok {
+ if !inst.IsRunning() {
continue
}
- err = c.SaveConfigFile()
+ err = inst.SaveConfigFile()
if err != nil {
- logger.Errorf("Failed to save LXC config for %q: %v", c.Name(), err)
+ logger.Errorf("Failed to save LXC config for %q: %v", inst.Name(), err)
}
}
From dd236c1567685f3e7614654ec5b74874ca5e0461 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:11:53 +0000
Subject: [PATCH 48/50] lxd/profiles/utils: Removes use of containerLXC type
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/profiles_utils.go | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/lxd/profiles_utils.go b/lxd/profiles_utils.go
index e506d56e64..bef9d19324 100644
--- a/lxd/profiles_utils.go
+++ b/lxd/profiles_utils.go
@@ -208,30 +208,33 @@ func doProfileUpdateContainer(d *Daemon, name string, old api.ProfilePut, nodeNa
if err != nil {
return err
}
+
for i, profileName := range args.Profiles {
if profileName == name {
- // Use the old config and devices.
+ // Overwrite the new config from the database with the old config and devices.
profiles[i].Config = old.Config
profiles[i].Devices = old.Devices
break
}
}
- c := containerLXCInstantiate(d.State(), args, nil)
-
- c.(*containerLXC).expandConfig(profiles)
- c.(*containerLXC).expandDevices(profiles)
-
- return c.Update(db.InstanceArgs{
- Architecture: c.Architecture(),
- Config: c.LocalConfig(),
- Description: c.Description(),
- Devices: c.LocalDevices(),
- Ephemeral: c.IsEphemeral(),
- Profiles: c.Profiles(),
- Project: c.Project(),
- Type: c.Type(),
- Snapshot: c.IsSnapshot(),
+ // Load the instance using the old profile config.
+ inst, err := instance.Load(d.State(), args, profiles)
+ if err != nil {
+ return err
+ }
+
+ // Update will internally load the new profile configs and detect the changes to apply.
+ return inst.Update(db.InstanceArgs{
+ Architecture: inst.Architecture(),
+ Config: inst.LocalConfig(),
+ Description: inst.Description(),
+ Devices: inst.LocalDevices(),
+ Ephemeral: inst.IsEphemeral(),
+ Profiles: inst.Profiles(),
+ Project: inst.Project(),
+ Type: inst.Type(),
+ Snapshot: inst.IsSnapshot(),
}, true)
}
From 79e330adfbce2fd90f7ddd730057805bf71306fd Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:12:25 +0000
Subject: [PATCH 49/50] lxd/seccomp/seccomp: Removes c.DaemonState dependency
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/seccomp/seccomp.go | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/lxd/seccomp/seccomp.go b/lxd/seccomp/seccomp.go
index 35b1a8244c..22c52a996a 100644
--- a/lxd/seccomp/seccomp.go
+++ b/lxd/seccomp/seccomp.go
@@ -366,7 +366,6 @@ type Instance interface {
Project() string
ExpandedConfig() map[string]string
IsPrivileged() bool
- DaemonState() *state.State
Architecture() int
RootfsPath() string
CurrentIdmap() (*idmap.IdmapSet, error)
@@ -429,14 +428,14 @@ func InstanceNeedsPolicy(c Instance) bool {
}
// InstanceNeedsIntercept returns whether instance needs intercept.
-func InstanceNeedsIntercept(c Instance) (bool, error) {
+func InstanceNeedsIntercept(s *state.State, c Instance) (bool, error) {
// No need if privileged
if c.IsPrivileged() {
return false, nil
}
// If nested, assume the host handles it
- if c.DaemonState().OS.RunningInUserNS {
+ if s.OS.RunningInUserNS {
return false, nil
}
@@ -454,7 +453,7 @@ func InstanceNeedsIntercept(c Instance) (bool, error) {
continue
}
- if !isSupported(c.DaemonState()) {
+ if !isSupported(s) {
return needed, fmt.Errorf("System doesn't support syscall interception")
}
@@ -464,7 +463,7 @@ func InstanceNeedsIntercept(c Instance) (bool, error) {
return needed, nil
}
-func seccompGetPolicyContent(c Instance) (string, error) {
+func seccompGetPolicyContent(s *state.State, c Instance) (string, error) {
config := c.ExpandedConfig()
// Full policy override
@@ -489,7 +488,7 @@ func seccompGetPolicyContent(c Instance) (string, error) {
}
// Syscall interception
- ok, err := InstanceNeedsIntercept(c)
+ ok, err := InstanceNeedsIntercept(s, c)
if err != nil {
return "", err
}
@@ -539,7 +538,7 @@ func seccompGetPolicyContent(c Instance) (string, error) {
}
// CreateProfile creates a seccomp profile.
-func CreateProfile(c Instance) error {
+func CreateProfile(s *state.State, c Instance) error {
/* Unlike apparmor, there is no way to "cache" profiles, and profiles
* are automatically unloaded when a task dies. Thus, we don't need to
* unload them when a container stops, and we don't have to worry about
@@ -550,7 +549,7 @@ func CreateProfile(c Instance) error {
return nil
}
- profile, err := seccompGetPolicyContent(c)
+ profile, err := seccompGetPolicyContent(s, c)
if err != nil {
return err
}
@@ -1557,7 +1556,7 @@ func (s *Server) MountSyscallShift(c Instance) bool {
return false
}
- if diskIdmap == nil && c.DaemonState().OS.Shiftfs {
+ if diskIdmap == nil && s.s.OS.Shiftfs {
return true
}
}
From 9eb3c69cf9352f7d7982700ae89fbb1c370628b4 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 11:12:42 +0000
Subject: [PATCH 50/50] lxd/storage/drivers/utils: golint fixes
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/drivers/utils.go | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lxd/storage/drivers/utils.go b/lxd/storage/drivers/utils.go
index 66b85d81f5..e77b59d553 100644
--- a/lxd/storage/drivers/utils.go
+++ b/lxd/storage/drivers/utils.go
@@ -585,10 +585,12 @@ func loopFilePath(poolName string) string {
return filepath.Join(shared.VarPath("disks"), fmt.Sprintf("%s.img", poolName))
}
+// ShiftBtrfsRootfs shifts the BTRFS root filesystem.
func ShiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
return shiftBtrfsRootfs(path, diskIdmap, true)
}
+// UnshiftBtrfsRootfs unshifts the BTRFS root filesystem.
func UnshiftBtrfsRootfs(path string, diskIdmap *idmap.IdmapSet) error {
return shiftBtrfsRootfs(path, diskIdmap, false)
}
@@ -695,6 +697,7 @@ func BTRFSSubVolumeMakeRw(path string) error {
return err
}
+// IDMapsetFromString returns an IdmapSet from string.
func IDMapsetFromString(idmapString string) (*idmap.IdmapSet, error) {
lastIdmap := new(idmap.IdmapSet)
err := json.Unmarshal([]byte(idmapString), &lastIdmap.Idmap)
@@ -709,6 +712,7 @@ func IDMapsetFromString(idmapString string) (*idmap.IdmapSet, error) {
return lastIdmap, nil
}
+// ShiftZFSSkipper indicates which files not to shift for ZFS.
func ShiftZFSSkipper(dir string, absPath string, fi os.FileInfo) bool {
strippedPath := absPath
if dir != "" {
More information about the lxc-devel
mailing list