[lxc-devel] [lxd/master] Storage: Move legacy code removal/reorg
tomponline on Github
lxc-bot at linuxcontainers.org
Fri Feb 28 15:46:02 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 350 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200228/4f2d0a21/attachment-0001.bin>
-------------- next part --------------
From e5c1ad935fac79ad15ee1e5cfbfa9fc00b9adc9b 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/62] 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 6601ca70755a78c8b403cda0b81ba146d4e4f373 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/62] 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 34efed44a4477f924dd6ebd7d0046cb1fab683be 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/62] 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 9f7002034f0d0a9902f27b5c68f57b4d9fcdf432 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/62] 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 273f5f9fe925df384ee518c484a419d0898db492 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/62] lxd/api/internal: instance.Container usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/api_internal.go | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index 9d1dab7c1a..a8fe617433 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -135,7 +135,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.(instance.Container)
err = c.OnStart()
if err != nil {
logger.Error("The start hook failed", log.Ctx{"container": c.Name(), "err": err})
@@ -166,7 +166,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.(instance.Container)
err = c.OnStopNS(target, netns)
if err != nil {
logger.Error("The stopns hook failed", log.Ctx{"container": c.Name(), "err": err})
@@ -196,7 +196,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.(instance.Container)
err = c.OnStop(target)
if err != nil {
logger.Error("The stop hook failed", log.Ctx{"container": c.Name(), "err": err})
From dd627333af234c7cc02d63bbca293f9a37145765 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/62] lxd/container: instance.CriuMigrationArgs and
instance.Container usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container.go | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/lxd/container.go b/lxd/container.go
index 4b521fbef0..094d6fad37 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -384,17 +384,17 @@ 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 := instance.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_DUMP,
+ StateDir: stateDir,
+ Function: "snapshot",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
- c := sourceInstance.(*containerLXC)
+ c := sourceInstance.(instance.Container)
err = c.Migrate(&criuMigrationArgs)
if err != nil {
os.RemoveAll(sourceInstance.StatePath())
From 9739cd70b94090ab5d3ab82b9247f254b7edbcc0 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 07/62] lxd/container/console: instance.Container usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_console.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lxd/container_console.go b/lxd/container_console.go
index e461a9f7ff..9207508b32 100644
--- a/lxd/container_console.go
+++ b/lxd/container_console.go
@@ -354,7 +354,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.(instance.Container)
ent := response.FileResponseEntry{}
if !c.IsRunning() {
// Hand back the contents of the console ringbuffer logfile.
@@ -408,7 +408,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.(instance.Container)
truncateConsoleLogFile := func(path string) error {
// Check that this is a regular file. We don't want to try and unlink
From ab5601a6e1ef14a47469c387cd5a0125c02b7b11 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 08/62] lxd/container/exec: instance.Container usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_exec.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index 2302ee54b3..c15c4afe90 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -426,7 +426,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.(instance.Container)
idmapset, err := c.CurrentIdmap()
if err != nil {
return response.InternalError(err)
From 420b7046238a7ac7802db20aa99835a7b945e266 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 09/62] 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 1675115c51808be93e412a6f0d24029685ca4f8a 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 10/62] lxd/container/test: instance.Container 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..e4677eec76 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.(instance.Container).NextIdmap()
suite.Req.Nil(err)
- map2, err := c2.(*containerLXC).NextIdmap()
+ map2, err := c2.(instance.Container).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.(instance.Container).NextIdmap()
suite.Req.Nil(err)
- map2, err := c2.(*containerLXC).NextIdmap()
+ map2, err := c2.(instance.Container).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.(instance.Container).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.(instance.Container).NextIdmap()
suite.Req.Nil(err)
maps = append(maps, m)
From 740b63fe5d9e313ee78f61ff065135b8dce7f393 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 11/62] 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 3800bac21c9852280d531236b9570fccd5082c10 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 12/62] 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 8daed6643205be6ea93a60295b36fd446b02cb70 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 13/62] 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 fa58c80e66668f8bf76a8d5f420f25b4e42789d9 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 14/62] lxd/devlxd: instance.Container usage
And golint fixes
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/devlxd.go | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/lxd/devlxd.go b/lxd/devlxd.go
index 7eb41c9e98..2414a22646 100644
--- a/lxd/devlxd.go
+++ b/lxd/devlxd.go
@@ -180,15 +180,15 @@ func hoistReq(f func(*Daemon, instance.Instance, http.ResponseWriter, *http.Requ
}
// Access control
- rootUid := int64(0)
+ rootUID := int64(0)
idmapset, err := c.CurrentIdmap()
if err == nil && idmapset != nil {
uid, _ := idmapset.ShiftIntoNs(0, 0)
- rootUid = int64(uid)
+ rootUID = int64(uid)
}
- if rootUid != cred.UID {
+ if rootUID != cred.UID {
http.Error(w, "Access denied for non-root user", 401)
return
}
@@ -308,7 +308,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) (instance.Container, 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,8 +355,7 @@ func findContainerForPid(pid int32, s *state.State) (*containerLXC, error) {
return nil, fmt.Errorf("Instance is not container type")
}
- c := inst.(*containerLXC)
- return c, nil
+ return inst.(instance.Container), nil
}
status, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/status", pid))
@@ -405,7 +404,7 @@ func findContainerForPid(pid int32, s *state.State) (*containerLXC, error) {
}
if origPidNs == pidNs {
- return inst.(*containerLXC), nil
+ return inst.(instance.Container), nil
}
}
From 339e4d29ee031d82106e1be3e21bb1d6d0eab644 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 15/62] lxd/instance/drivers/driver/lxc: Renames containerLXC
to lxc
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 350 ++++++++++++++---------------
1 file changed, 169 insertions(+), 181 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 9b13c10503..e0809956b8 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,
@@ -427,8 +426,8 @@ func containerLXCInstantiate(s *state.State, args db.InstanceArgs, expandedDevic
return c
}
-// The LXC container driver
-type containerLXC struct {
+// The LXC container driver.
+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
@@ -1275,7 +1274,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 {
@@ -1290,7 +1289,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
@@ -1312,7 +1311,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
@@ -1324,7 +1323,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
@@ -1389,7 +1388,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)
@@ -1417,7 +1416,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
@@ -1440,7 +1439,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" {
@@ -1469,7 +1468,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
@@ -1484,7 +1483,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.
@@ -1553,7 +1552,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 {
@@ -1614,7 +1613,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
@@ -1661,7 +1660,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.
@@ -1681,7 +1680,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)
@@ -1696,7 +1695,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 {
@@ -1709,7 +1708,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)
@@ -1746,7 +1745,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
@@ -1807,7 +1806,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)
@@ -1821,7 +1820,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)
@@ -1886,7 +1885,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{}
@@ -2247,7 +2246,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
@@ -2269,7 +2268,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
@@ -2313,14 +2312,14 @@ func (c *containerLXC) Start(stateful bool) error {
return fmt.Errorf("Container has no existing state to restore")
}
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_RESTORE,
- stateDir: c.StatePath(),
- function: "snapshot",
- stop: false,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
+ criuMigrationArgs := instance.CriuMigrationArgs{
+ Cmd: liblxc.MIGRATE_RESTORE,
+ StateDir: c.StatePath(),
+ Function: "snapshot",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
err := c.Migrate(&criuMigrationArgs)
@@ -2421,7 +2420,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
@@ -2478,7 +2477,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 {
@@ -2511,7 +2510,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
@@ -2549,14 +2548,14 @@ func (c *containerLXC) Stop(stateful bool) error {
return err
}
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_DUMP,
- stateDir: stateDir,
- function: "snapshot",
- stop: true,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
+ criuMigrationArgs := instance.CriuMigrationArgs{
+ Cmd: liblxc.MIGRATE_DUMP,
+ StateDir: stateDir,
+ Function: "snapshot",
+ Stop: true,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
// Checkpoint
@@ -2652,7 +2651,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
@@ -2715,7 +2714,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})
@@ -2730,7 +2729,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})
@@ -2795,7 +2794,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
@@ -2845,7 +2844,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)
@@ -2858,7 +2857,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,
@@ -2911,7 +2910,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,
@@ -2965,7 +2964,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
}
@@ -2986,11 +2985,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)
@@ -3049,7 +3048,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")
}
@@ -3107,7 +3106,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
@@ -3131,7 +3130,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() {
@@ -3166,7 +3165,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 {
@@ -3188,7 +3187,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.
@@ -3313,14 +3312,14 @@ func (c *containerLXC) Restore(sourceContainer instance.Instance, stateful bool)
logger.Debug("Performing stateful restore", ctxMap)
c.stateful = true
- criuMigrationArgs := CriuMigrationArgs{
- cmd: lxc.MIGRATE_RESTORE,
- stateDir: c.StatePath(),
- function: "snapshot",
- stop: false,
- actionScript: false,
- dumpDir: "",
- preDumpDir: "",
+ criuMigrationArgs := instance.CriuMigrationArgs{
+ Cmd: liblxc.MIGRATE_RESTORE,
+ StateDir: c.StatePath(),
+ Function: "snapshot",
+ Stop: false,
+ ActionScript: false,
+ DumpDir: "",
+ PreDumpDir: "",
}
// Checkpoint.
@@ -3360,7 +3359,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()
@@ -3376,7 +3375,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,
@@ -3490,7 +3489,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,
@@ -3636,7 +3635,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 {
@@ -3652,7 +3651,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 {
@@ -3672,7 +3671,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.") {
@@ -3710,7 +3709,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"
@@ -4433,7 +4432,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.
@@ -4488,7 +4487,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,
@@ -4735,18 +4734,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 *instance.CriuMigrationArgs) error {
ctxMap := log.Ctx{
"project": c.project,
"name": c.name,
@@ -4954,7 +4942,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")
@@ -4963,7 +4951,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) {
@@ -5105,7 +5093,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
@@ -5153,7 +5141,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 {
@@ -5282,7 +5270,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 {
@@ -5378,7 +5366,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
@@ -5439,7 +5427,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{
@@ -5492,7 +5480,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
@@ -5501,7 +5489,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{}
@@ -5583,7 +5571,7 @@ func (c *containerLXC) Exec(req api.InstanceExecPost, stdin *os.File, stdout *os
return nil, err
}
- instCmd := &ContainerLXCCmd{
+ instCmd := &lxcCmd{
cmd: &cmd,
attachedChildPid: attachedPid,
}
@@ -5591,7 +5579,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
@@ -5621,7 +5609,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() {
@@ -5655,7 +5643,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 {
@@ -5705,7 +5693,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()
@@ -5763,7 +5751,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 {
@@ -5813,8 +5801,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
}
@@ -5829,7 +5817,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
@@ -5839,12 +5827,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
@@ -5868,12 +5856,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
@@ -5897,7 +5885,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
@@ -5955,7 +5943,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 == "" {
@@ -5974,7 +5962,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)
}
@@ -5982,7 +5970,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 {
@@ -6014,7 +6002,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")
}
@@ -6069,7 +6057,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
@@ -6101,7 +6089,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()
@@ -6260,7 +6248,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
@@ -6294,7 +6282,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
@@ -6347,23 +6335,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()
}
@@ -6376,44 +6364,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 {
@@ -6423,42 +6411,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
@@ -6468,27 +6456,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()
@@ -6497,42 +6485,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.
@@ -6544,7 +6532,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
@@ -6554,11 +6542,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
}
@@ -6567,7 +6555,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
}
@@ -6584,7 +6572,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" {
@@ -6634,7 +6622,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 {
@@ -6684,7 +6672,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
@@ -6719,7 +6707,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
@@ -6754,7 +6742,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
@@ -6805,7 +6793,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 6c7099080497acf90c09d6b177c35764a6e910fa 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 16/62] 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 e0809956b8..06650943be 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 76b2e1e13e6ce336f0a2ec9637b34d9b903fb368 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 17/62] 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 06650943be..31b745cf62 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
}
@@ -1561,7 +1561,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
}
@@ -2957,18 +2957,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)
@@ -6115,7 +6115,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()
@@ -6747,12 +6747,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 783e08e135c21fa8d65a77fe00c133487dc6ffb5 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 18/62] 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 31b745cf62..9e0ed0b63b 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 57a93d2d73a1a4da28711f788dd23498fe2b4cb6 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 19/62] lxd/instance/drivers/driver/lxc: Adds devLxdSendEvent
Updates usage.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 85 +++++++++++++++++-------------
1 file changed, 47 insertions(+), 38 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 9e0ed0b63b..be5c29f8bc 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -1264,6 +1264,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.
@@ -4359,7 +4368,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
}
@@ -4373,7 +4382,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
}
@@ -4386,7 +4395,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
}
@@ -4399,7 +4408,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
}
@@ -4732,11 +4741,11 @@ func (c *lxc) Migrate(args *instance.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 {
@@ -4746,18 +4755,18 @@ func (c *lxc) Migrate(args *instance.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()
@@ -4774,14 +4783,14 @@ func (c *lxc) Migrate(args *instance.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 {
@@ -4811,11 +4820,11 @@ func (c *lxc) Migrate(args *instance.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()
@@ -4831,8 +4840,8 @@ func (c *lxc) Migrate(args *instance.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(
@@ -4853,16 +4862,16 @@ func (c *lxc) Migrate(args *instance.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
@@ -4875,12 +4884,12 @@ func (c *lxc) Migrate(args *instance.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
@@ -4891,27 +4900,27 @@ func (c *lxc) Migrate(args *instance.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})
}
@@ -4920,7 +4929,7 @@ func (c *lxc) Migrate(args *instance.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 00f2672161a3f14783cd63e66cb896fafb64999e 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 20/62] 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 be5c29f8bc..dae1574968 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -1288,6 +1288,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 83b4f27dbd3531457236d7b086da44233f25cb2d 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 21/62] 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 dae1574968..8a587921bb 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -1857,56 +1857,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
@@ -1966,9 +1916,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)
}
@@ -1982,9 +1932,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 e0c42cd5fb4b71bcac4de8dc8330650f128d87fd 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 22/62] 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 8a587921bb..d55556bc87 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -2251,7 +2251,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 c708c093e396b5b37eb15c98327bb77a66096b21 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 23/62] 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 d55556bc87..5bbede9f30 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -6774,3 +6774,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 1d586af50a821e0bb0e73ce44d38ec3927db74c0 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 24/62] 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 cd9e57ad691d08e69ed9b71fd4dd7623674b4ec1 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 25/62] 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 38be1c589a2939e00a3717537952e2a76adeade2 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 26/62] 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 73c774db2b3a80cf684102b3adcab25eae9d5e13 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 27/62] 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 69a8b179431457f7af0108242df622554ec1438e 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 28/62] lxd/migrate/container: instance.CriuMigrationArgs and
instance.Container usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/migrate_container.go | 92 ++++++++++++++++++++--------------------
1 file changed, 46 insertions(+), 46 deletions(-)
diff --git a/lxd/migrate_container.go b/lxd/migrate_container.go
index 70751a70a7..4488fb102c 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -129,22 +129,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 := instance.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.(instance.Container)
err := c.Migrate(&criuMigrationArgs)
if err != nil {
@@ -241,14 +241,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 := instance.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 +259,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.(instance.Container)
err := c.Migrate(&criuMigrationArgs)
if err != nil {
return final, err
@@ -337,7 +337,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.(instance.Container)
var offerHeader migration.MigrationHeader
var poolMigrationTypes []migration.Type
@@ -609,14 +609,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 := instance.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 +636,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 := instance.CriuMigrationArgs{
+ Cmd: lxc.MIGRATE_DUMP,
+ StateDir: checkpointDir,
+ Function: "migration",
+ Stop: true,
+ ActionScript: false,
+ DumpDir: "final",
+ PreDumpDir: "",
}
err = ct.Migrate(&criuMigrationArgs)
@@ -1044,7 +1044,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.(instance.Container)
err = resetContainerDiskIdmap(ct, srcIdmap)
if err != nil {
fsTransfer <- err
@@ -1122,20 +1122,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 := instance.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.(instance.Container)
err = ct.Migrate(&criuMigrationArgs)
if err != nil {
restore <- err
From dc0b655dfd071d07226752dea58b3ff27b9f5108 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 29/62] lxd/patches: Updates patchContainerConfigRegen to use
LXC.SaveConfigFile()
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/patches.go | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/lxd/patches.go b/lxd/patches.go
index bd13a029eb..e160fe29e2 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"
+ "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"
@@ -2068,34 +2069,23 @@ 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() {
- continue
- }
-
- lxcCt, ok := c.(*containerLXC)
- if !ok {
+ if inst.Type() != instancetype.Container {
continue
}
- err = lxcCt.initLXC(true)
- if err != nil {
- logger.Errorf("Failed to generate LXC config for '%s': %v", ct, err)
+ if !inst.IsRunning() {
continue
}
- // Generate the LXC config
- configPath := filepath.Join(lxcCt.LogPath(), "lxc.conf")
- err = lxcCt.c.SaveConfigFile(configPath)
+ err = inst.SaveConfigFile()
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", inst.Name(), err)
}
}
From 14cbd0476623179b8246e14cfb13c47d4f5ba44c 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 30/62] 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 e160fe29e2..b657bdd859 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -3320,17 +3320,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 07a6e4c643c38fff10853ce579530ab5ed75d4f3 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 31/62] 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 09b78b6037f11297c31813864e46e0095a95980f 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 32/62] lxd/storage: instance.Container usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage.go | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lxd/storage.go b/lxd/storage.go
index e0c848e8ac..e25b5122fe 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -46,7 +46,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 instance.Container) error {
// Load the DB records
poolID, pool, err := s.Cluster.StoragePoolGet(poolName)
if err != nil {
@@ -121,7 +121,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName
continue
}
- ct := instt.(*containerLXC)
+ ct := instt.(instance.Container)
var ctNextIdmap *idmap.IdmapSet
if ct.IsRunning() {
@@ -206,7 +206,7 @@ func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName
return nil
}
-func resetContainerDiskIdmap(container *containerLXC, srcIdmap *idmap.IdmapSet) error {
+func resetContainerDiskIdmap(container instance.Container, srcIdmap *idmap.IdmapSet) error {
dstIdmap, err := container.DiskIdmap()
if err != nil {
return err
@@ -332,7 +332,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.(instance.Container)
if !ok {
return fmt.Errorf("Received non-LXC container instance")
}
From dd911c7db8051c3b5a422fbcf3edf0ec864ba3f3 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 33/62] 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 e25b5122fe..c4f1b8ba37 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -69,7 +69,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
@@ -152,7 +152,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)
}
@@ -170,7 +170,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 8913bcaabedef3fb9e7e9fed17d7566f570788f0 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 34/62] 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 4ce1e5ba8db327b8bc5a705cd37a207f3cffb71f 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 35/62] 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 81dcf594465cc9bb8cddd891aca037d8f9a8e77c 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 36/62] 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 a714f6682f43db1e7555d0bc56edf80985f51e11 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 37/62] 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 e4677eec76..0a69b2f1a0 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 c1107ce2b46e6d536082655fc55e48c4f1f76c27 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 38/62] lxd/instance/drivers/driver/lxc: golint fixes
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/drivers/driver_lxc.go | 136 +++++++++++++++++++----------
1 file changed, 92 insertions(+), 44 deletions(-)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 5bbede9f30..8366c937f7 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -461,6 +461,7 @@ type lxc struct {
expiryDate time.Time
}
+// Type returns the instance type.
func (c *lxc) Type() instancetype.Type {
return c.dbType
}
@@ -1264,7 +1265,7 @@ func (c *lxc) initLXC(config bool) error {
return nil
}
-func (c *LXC) devlxdEventSend(eventType string, eventMessage interface{}) error {
+func (c *lxc) devlxdEventSend(eventType string, eventMessage interface{}) error {
event := shared.Jmap{}
event["type"] = eventType
event["timestamp"] = time.Now()
@@ -1289,7 +1290,7 @@ func (c *lxc) runHooks(hooks []func() error) error {
}
// RegisterDevices calls the Register() function on all of the instance's devices.
-func (c *LXC) RegisterDevices() {
+func (c *lxc) RegisterDevices() {
devices := c.ExpandedDevices()
for _, dev := range devices.Sorted() {
d, _, err := c.deviceLoad(dev.Name, dev.Config)
@@ -2241,6 +2242,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
@@ -2393,6 +2395,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
@@ -2624,6 +2627,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
@@ -2829,7 +2833,7 @@ func (c *lxc) cleanupDevices(netns string) {
}
}
-// Freezer functions
+// Freeze functions.
func (c *lxc) Freeze() error {
ctxMap := log.Ctx{
"project": c.project,
@@ -2883,6 +2887,7 @@ func (c *lxc) Freeze() error {
return err
}
+// Unfreeze unfreezes the instance.
func (c *lxc) Unfreeze() error {
ctxMap := log.Ctx{
"project": c.project,
@@ -2933,8 +2938,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) {
@@ -2958,10 +2961,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)
@@ -3021,6 +3025,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")
@@ -3079,6 +3084,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 {
@@ -3103,6 +3109,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
@@ -3138,6 +3145,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)
@@ -3348,6 +3356,7 @@ func (c *lxc) cleanup() {
os.RemoveAll(c.ShmountsPath())
}
+// Delete deletes the instance.
func (c *lxc) Delete() error {
ctxMap := log.Ctx{
"project": c.project,
@@ -3462,6 +3471,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{
@@ -3608,6 +3618,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)
@@ -3624,6 +3635,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)
@@ -3644,6 +3656,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 {
@@ -3682,6 +3695,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 == "" {
@@ -4460,6 +4474,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,
@@ -4707,6 +4722,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 *instance.CriuMigrationArgs) error {
ctxMap := log.Ctx{
"project": c.project,
@@ -4944,18 +4960,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
@@ -5015,7 +5031,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)
@@ -5024,7 +5040,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()
@@ -5066,6 +5082,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
@@ -5114,6 +5131,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)
@@ -5154,7 +5172,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
@@ -5210,7 +5228,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
}
@@ -5240,18 +5258,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
@@ -5263,7 +5282,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)
}
}
@@ -5278,7 +5297,7 @@ func (c *lxc) FilePush(type_ string, srcpath string, dstpath string, uid int64,
}
defaultMode := 0640
- if type_ == "directory" {
+ if fileType == "directory" {
defaultMode = 0750
}
@@ -5292,12 +5311,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,
)
@@ -5339,6 +5358,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
@@ -5400,6 +5420,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)
@@ -5453,6 +5474,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 {
@@ -5462,6 +5484,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{}
@@ -5975,6 +5998,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")
@@ -6290,36 +6314,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"])
}
@@ -6337,43 +6364,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)
@@ -6384,14 +6421,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 {
@@ -6401,6 +6441,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 {
@@ -6410,6 +6451,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 {
@@ -6419,36 +6461,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 {
@@ -6457,42 +6495,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
@@ -6505,6 +6551,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 {
@@ -6514,11 +6561,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
@@ -6544,7 +6592,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 {
@@ -6776,7 +6824,7 @@ func (c *lxc) UpdateBackupFile() error {
}
// SaveConfigFile generates the LXC config file on disk.
-func (c *LXC) SaveConfigFile() error {
+func (c *lxc) SaveConfigFile() error {
err := c.initLXC(true)
if err != nil {
return errors.Wrapf(err, "Failed to generate LXC config")
@@ -6787,7 +6835,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 dc73a833cc6ca37ca66051a07b1faead2ebaea8f 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 39/62] 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 8366c937f7..67927f52d7 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -997,7 +997,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 {
@@ -1982,7 +1982,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
}
@@ -2407,7 +2407,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()
@@ -2421,7 +2421,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()
}
@@ -2431,7 +2431,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()
}
@@ -2441,7 +2441,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()
}
@@ -2784,7 +2784,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})
}
@@ -3346,7 +3346,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
@@ -3939,7 +3939,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")
}
@@ -4011,7 +4011,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 0a43c3c721e5491c7fae11f09368a01c33ab4a1f 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 40/62] 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 8799e7fa3fddaa25ceeaee2ca730c7a6402a9944 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 41/62] 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 5ab5556b42b4b660d1ba608d240690c26b574d1f 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 42/62] 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..07d3d71061 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 1fb1752d0751cae5f8bc65f2a6e2737a1d971d3e 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 43/62] 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 0c34a2e8d21dd7b07525e5f3620a48aed88f8664 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 44/62] 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 0f66edb05283a08f6ea74eb7e9760d136b836f46 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 45/62] 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 4488fb102c..67cf6e35c5 100644
--- a/lxd/migrate_container.go
+++ b/lxd/migrate_container.go
@@ -239,7 +239,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 := instance.CriuMigrationArgs{
Cmd: lxc.MIGRATE_PRE_DUMP,
@@ -267,7 +267,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
@@ -590,7 +589,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)
@@ -900,7 +899,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 3784573a87284820a1b143aa4b6a86b996f11381 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 46/62] 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 7b460e52216e02ac05e3fecb32d572995b38eb9f 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 47/62] 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 17c45930c302471a6405f08bfac3b7502c67b5dc 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 48/62] 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 != "" {
From 8b2ce7fa0087e5b1d197994557d14d5e499b7e3e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 12:23:30 +0000
Subject: [PATCH 49/62] lxd/instance/instance/interface: Adds Container
interface
This interface provides an easy way to see the differences between the common Instance interface and the more specific container implementations.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/instance_interface.go | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
index 4cda3ed62f..f2704ce5db 100644
--- a/lxd/instance/instance_interface.go
+++ b/lxd/instance/instance_interface.go
@@ -11,6 +11,7 @@ import (
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
)
// ConfigReader is used to read instance config.
@@ -22,7 +23,7 @@ type ConfigReader interface {
LocalDevices() deviceConfig.Devices
}
-// The Instance interface.
+// Instance interface.
type Instance interface {
ConfigReader
@@ -116,3 +117,22 @@ type Instance interface {
StorageStop() (bool, error)
DeferTemplateApply(trigger string) error
}
+
+// Container interface is for container specific functions.
+type Container interface {
+ Instance
+
+ CurrentIdmap() (*idmap.IdmapSet, error)
+ DiskIdmap() (*idmap.IdmapSet, error)
+ NextIdmap() (*idmap.IdmapSet, error)
+
+ OnStart() error
+ OnStopNS(target string, netns string) error
+ OnStop(target string) error
+
+ ConsoleLog(opts liblxc.ConsoleLogOptions) (string, error)
+
+ Migrate(args *CriuMigrationArgs) error
+
+ InsertSeccompUnixDevice(prefix string, m deviceConfig.Device, pid int) error
+}
From 2f31f32da03fbdae30084041fde72e37a2f7d84e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 12:24:23 +0000
Subject: [PATCH 50/62] lxd/instance/instance/interface: Adds CriuMigrationArgs
type
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/instance/instance_interface.go | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
index f2704ce5db..c9257f6ce4 100644
--- a/lxd/instance/instance_interface.go
+++ b/lxd/instance/instance_interface.go
@@ -5,6 +5,8 @@ import (
"os"
"time"
+ liblxc "gopkg.in/lxc/go-lxc.v2"
+
"github.com/lxc/lxd/lxd/backup"
"github.com/lxc/lxd/lxd/db"
deviceConfig "github.com/lxc/lxd/lxd/device/config"
@@ -136,3 +138,15 @@ type Container interface {
InsertSeccompUnixDevice(prefix string, m deviceConfig.Device, pid int) error
}
+
+// 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
+}
From 69cbae8d3154302e2e99326d3fe38171ed10c477 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 12:25:00 +0000
Subject: [PATCH 51/62] lxd/backup/backup: Comment clarifying existence of
Instance interface
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/backup/backup.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/lxd/backup/backup.go b/lxd/backup/backup.go
index 323bd3edc7..cd514bf04f 100644
--- a/lxd/backup/backup.go
+++ b/lxd/backup/backup.go
@@ -18,6 +18,7 @@ import (
)
// Instance represents the backup relevant subset of a LXD instance.
+// This is used rather than instance.Instance to avoid import loops.
type Instance interface {
Name() string
Project() string
From c8389216f904450687d9027da86d21ce6e3b6678 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 12:27:37 +0000
Subject: [PATCH 52/62] lxd/seccomp/seccomp: Comment clarifying existence of
Instance interface
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/seccomp/seccomp.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/lxd/seccomp/seccomp.go b/lxd/seccomp/seccomp.go
index 22c52a996a..18db1c47e7 100644
--- a/lxd/seccomp/seccomp.go
+++ b/lxd/seccomp/seccomp.go
@@ -361,6 +361,7 @@ stub_x32_execveat errno 38
`
// Instance is a seccomp specific instance interface.
+// This is used rather than instance.Instance to avoid import loops.
type Instance interface {
Name() string
Project() string
From b9e99e1fbf31bdf9a00c721b33ca55da71dfcb7a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:18:23 +0000
Subject: [PATCH 53/62] lxd/container/lxc/utils: Removes unused file
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container_lxc_utils.go | 16 ----------------
1 file changed, 16 deletions(-)
delete mode 100644 lxd/container_lxc_utils.go
diff --git a/lxd/container_lxc_utils.go b/lxd/container_lxc_utils.go
deleted file mode 100644
index 7ea2afea2b..0000000000
--- a/lxd/container_lxc_utils.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package main
-
-import (
- "encoding/json"
-
- "github.com/lxc/lxd/shared/idmap"
-)
-
-func idmapsetToJSON(idmapSet *idmap.IdmapSet) (string, error) {
- idmapBytes, err := json.Marshal(idmapSet.Idmap)
- if err != nil {
- return "", err
- }
-
- return string(idmapBytes), nil
-}
From 41974edce4d9a6fce1923404ed71975d2b418461 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:18:39 +0000
Subject: [PATCH 54/62] lxd/device/device/utils/disk: Adds diskIDMapsetToJSON
function
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/device_utils_disk.go | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/lxd/device/device_utils_disk.go b/lxd/device/device_utils_disk.go
index 25f21090fa..739f42eccb 100644
--- a/lxd/device/device_utils_disk.go
+++ b/lxd/device/device_utils_disk.go
@@ -2,6 +2,7 @@ package device
import (
"bufio"
+ "encoding/json"
"fmt"
"os"
"os/exec"
@@ -14,6 +15,7 @@ import (
"github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
)
// StorageVolumeMount checks if storage volume is mounted and if not tries to mount it.
@@ -273,3 +275,12 @@ func diskCephfsOptions(clusterName string, userName string, fsName string, fsPat
return srcpath, fsOptions, nil
}
+
+func diskIDMapsetToJSON(idmapSet *idmap.IdmapSet) (string, error) {
+ idmapBytes, err := json.Marshal(idmapSet.Idmap)
+ if err != nil {
+ return "", err
+ }
+
+ return string(idmapBytes), nil
+}
From 47a4edb023009fe8252d116a8255ad622568a418 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:19:28 +0000
Subject: [PATCH 55/62] lxd/device/disk: Replaces call to StorageVolumeMount
with functions on disk device
StorageVolumeMount was only used by disk device.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/disk.go | 206 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 201 insertions(+), 5 deletions(-)
diff --git a/lxd/device/disk.go b/lxd/device/disk.go
index 9f10a0d157..18be1fc2a4 100644
--- a/lxd/device/disk.go
+++ b/lxd/device/disk.go
@@ -19,9 +19,12 @@ import (
"github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/project"
+ "github.com/lxc/lxd/lxd/revert"
storagePools "github.com/lxc/lxd/lxd/storage"
+ storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
"github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
"github.com/lxc/lxd/shared/units"
)
@@ -579,6 +582,9 @@ func (d *disk) generateLimits(runConf *deviceConfig.RunConfig) error {
// createDevice creates a disk device mount on host.
func (d *disk) createDevice() (string, error) {
+ revert := revert.New()
+ defer revert.Fail()
+
// Paths.
devPath := d.getDevicePath(d.name, d.config)
srcPath := shared.HostPath(d.config["source"])
@@ -701,17 +707,43 @@ func (d *disk) createDevice() (string, error) {
case db.StoragePoolVolumeTypeNameImage:
return "", fmt.Errorf("Using image storage volumes is not supported")
default:
- return "", fmt.Errorf("Unknown storage type prefix \"%s\" found", volumeTypeName)
+ return "", fmt.Errorf("Unknown storage type prefix %q found", volumeTypeName)
}
- err := StorageVolumeMount(d.state, d.config["pool"], volumeName, volumeTypeName, d.inst)
+ volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
+ if err != nil {
+ return "", err
+ }
+
+ pool, err := storagePools.GetPoolByName(d.state, d.config["pool"])
+ if err != nil {
+ return "", err
+ }
+
+ // Mount and prepare the volume to be attached.
+ err = func() error {
+ ourMount, err := pool.MountCustomVolume(volumeName, nil)
+ if err != nil {
+ return errors.Wrapf(err, "Could not mount storage volume %q of type %q on storage pool %q", volumeName, volumeTypeName, d.config["pool"])
+ }
+
+ if ourMount {
+ revert.Add(func() { pool.UnmountCustomVolume(volumeName, nil) })
+ }
+
+ err = d.storagePoolVolumeAttachPrepare(pool.Name(), volumeName, volumeType)
+ if err != nil {
+ return errors.Wrapf(err, "Could not attach storage volume %q of type %q on storage pool %q", volumeName, volumeTypeName, d.config["pool"])
+ }
+
+ return nil
+ }()
if err != nil {
- msg := fmt.Sprintf("Could not mount storage volume \"%s\" of type \"%s\" on storage pool \"%s\": %s.", volumeName, volumeTypeName, d.config["pool"], err)
if !isRequired {
// Will fail the PathExists test below.
- logger.Warn(msg)
+ logger.Warn(err.Error())
} else {
- return "", fmt.Errorf(msg)
+ return "", err
}
}
}
@@ -761,9 +793,173 @@ func (d *disk) createDevice() (string, error) {
return "", err
}
+ revert.Success()
return devPath, nil
}
+func (d *disk) storagePoolVolumeAttachPrepare(poolName string, volumeName string, volumeType int) error {
+ // Load the DB records
+ poolID, pool, err := d.state.Cluster.StoragePoolGet(poolName)
+ if err != nil {
+ return err
+ }
+
+ // Custom storage volumes do not currently support projects, so hardcode "default" project.
+ _, volume, err := d.state.Cluster.StoragePoolNodeVolumeGetTypeByProject("default", volumeName, volumeType, poolID)
+ if err != nil {
+ return err
+ }
+
+ poolVolumePut := volume.Writable()
+
+ // Check if unmapped
+ if shared.IsTrue(poolVolumePut.Config["security.unmapped"]) {
+ // No need to look at containers and maps for unmapped volumes
+ return nil
+ }
+
+ // Get the on-disk idmap for the volume
+ var lastIdmap *idmap.IdmapSet
+ if 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
+ }
+ }
+
+ var nextIdmap *idmap.IdmapSet
+ nextJSONMap := "[]"
+ if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) {
+ c := d.inst.(instance.Container)
+ // Get the container's idmap
+ if c.IsRunning() {
+ nextIdmap, err = c.CurrentIdmap()
+ } else {
+ nextIdmap, err = c.NextIdmap()
+ }
+ if err != nil {
+ return err
+ }
+
+ if nextIdmap != nil {
+ nextJSONMap, err = diskIDMapsetToJSON(nextIdmap)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ poolVolumePut.Config["volatile.idmap.next"] = nextJSONMap
+
+ // Get mountpoint of storage volume
+ remapPath := storagePools.GetStoragePoolVolumeMountPoint(poolName, volumeName)
+
+ if !nextIdmap.Equals(lastIdmap) {
+ logger.Debugf("Shifting storage volume")
+
+ if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) {
+ // Custom storage volumes do not currently support projects, so hardcode "default" project.
+ volumeUsedBy, err := storagePools.VolumeUsedByInstancesGet(d.state, "default", poolName, volumeName)
+ if err != nil {
+ return err
+ }
+
+ if len(volumeUsedBy) > 1 {
+ for _, ctName := range volumeUsedBy {
+ instt, err := instance.LoadByProjectAndName(d.state, d.inst.Project(), ctName)
+ if err != nil {
+ continue
+ }
+
+ if instt.Type() != instancetype.Container {
+ continue
+ }
+
+ ct := instt.(instance.Container)
+
+ var ctNextIdmap *idmap.IdmapSet
+ if ct.IsRunning() {
+ ctNextIdmap, err = ct.CurrentIdmap()
+ } else {
+ ctNextIdmap, err = ct.NextIdmap()
+ }
+ if err != nil {
+ return fmt.Errorf("Failed to retrieve idmap of container")
+ }
+
+ if !nextIdmap.Equals(ctNextIdmap) {
+ return fmt.Errorf("Idmaps of container %v and storage volume %v are not identical", ctName, volumeName)
+ }
+ }
+ } else if len(volumeUsedBy) == 1 {
+ // If we're the only one who's attached that container
+ // we can shift the storage volume.
+ // I'm not sure if we want some locking here.
+ if volumeUsedBy[0] != d.inst.Name() {
+ return fmt.Errorf("idmaps of container and storage volume are not identical")
+ }
+ }
+ }
+
+ // Unshift rootfs
+ if lastIdmap != nil {
+ var err error
+
+ if pool.Driver == "zfs" {
+ err = lastIdmap.UnshiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
+ } else {
+ err = lastIdmap.UnshiftRootfs(remapPath, nil)
+ }
+
+ if err != nil {
+ logger.Errorf("Failed to unshift \"%s\"", remapPath)
+ return err
+ }
+
+ logger.Debugf("Unshifted \"%s\"", remapPath)
+ }
+
+ // Shift rootfs
+ if nextIdmap != nil {
+ var err error
+
+ if pool.Driver == "zfs" {
+ err = nextIdmap.ShiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
+ } else {
+ err = nextIdmap.ShiftRootfs(remapPath, nil)
+ }
+
+ if err != nil {
+ logger.Errorf("Failed to shift \"%s\"", remapPath)
+ return err
+ }
+
+ logger.Debugf("Shifted \"%s\"", remapPath)
+ }
+ logger.Debugf("Shifted storage volume")
+ }
+
+ jsonIdmap := "[]"
+ if nextIdmap != nil {
+ var err error
+ jsonIdmap, err = diskIDMapsetToJSON(nextIdmap)
+ if err != nil {
+ logger.Errorf("Failed to marshal idmap")
+ return err
+ }
+ }
+
+ // Update last idmap
+ poolVolumePut.Config["volatile.idmap.last"] = jsonIdmap
+
+ err = d.state.Cluster.StoragePoolVolumeUpdateByProject("default", volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
// Stop is run when the device is removed from the instance.
func (d *disk) Stop() (*deviceConfig.RunConfig, error) {
if d.inst.Type() == instancetype.VM {
From d669d3b12015fb9fb099ac8980a26cd230aeda2c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:20:18 +0000
Subject: [PATCH 56/62] lxd/storage: Removes storageVolumeMount and
storagePoolVolumeAttachPrepare
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage.go | 209 -------------------------------------------------
1 file changed, 209 deletions(-)
diff --git a/lxd/storage.go b/lxd/storage.go
index c4f1b8ba37..7ddd8ac8cc 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -11,7 +11,6 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/device"
"github.com/lxc/lxd/lxd/instance"
- "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/state"
storagePools "github.com/lxc/lxd/lxd/storage"
storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
@@ -22,9 +21,6 @@ import (
)
func init() {
- // Expose storageVolumeMount to the device package as StorageVolumeMount.
- device.StorageVolumeMount = storageVolumeMount
-
// Expose storageVolumeUmount to the device package as StorageVolumeUmount.
device.StorageVolumeUmount = storageVolumeUmount
@@ -46,166 +42,6 @@ func readStoragePoolDriversCache() map[string]string {
return drivers.(map[string]string)
}
-func storagePoolVolumeAttachPrepare(s *state.State, poolName string, volumeName string, volumeType int, c instance.Container) error {
- // Load the DB records
- poolID, pool, err := s.Cluster.StoragePoolGet(poolName)
- if err != nil {
- return err
- }
-
- _, volume, err := s.Cluster.StoragePoolNodeVolumeGetTypeByProject("default", volumeName, volumeType, poolID)
- if err != nil {
- return err
- }
-
- poolVolumePut := volume.Writable()
-
- // Check if unmapped
- if shared.IsTrue(poolVolumePut.Config["security.unmapped"]) {
- // No need to look at containers and maps for unmapped volumes
- return nil
- }
-
- // Get the on-disk idmap for the volume
- var lastIdmap *idmap.IdmapSet
- if 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
- }
- }
-
- var nextIdmap *idmap.IdmapSet
- nextJsonMap := "[]"
- if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) {
- // Get the container's idmap
- if c.IsRunning() {
- nextIdmap, err = c.CurrentIdmap()
- } else {
- nextIdmap, err = c.NextIdmap()
- }
- if err != nil {
- return err
- }
-
- if nextIdmap != nil {
- nextJsonMap, err = idmapsetToJSON(nextIdmap)
- if err != nil {
- return err
- }
- }
- }
- poolVolumePut.Config["volatile.idmap.next"] = nextJsonMap
-
- // Get mountpoint of storage volume
- remapPath := storagePools.GetStoragePoolVolumeMountPoint(poolName, volumeName)
-
- if !nextIdmap.Equals(lastIdmap) {
- logger.Debugf("Shifting storage volume")
-
- if !shared.IsTrue(poolVolumePut.Config["security.shifted"]) {
- volumeUsedBy, err := storagePoolVolumeUsedByInstancesGet(s, "default", poolName, volumeName)
- if err != nil {
- return err
- }
-
- if len(volumeUsedBy) > 1 {
- for _, ctName := range volumeUsedBy {
- instt, err := instance.LoadByProjectAndName(s, c.Project(), ctName)
- if err != nil {
- continue
- }
-
- if instt.Type() != instancetype.Container {
- continue
- }
-
- ct := instt.(instance.Container)
-
- var ctNextIdmap *idmap.IdmapSet
- if ct.IsRunning() {
- ctNextIdmap, err = ct.CurrentIdmap()
- } else {
- ctNextIdmap, err = ct.NextIdmap()
- }
- if err != nil {
- return fmt.Errorf("Failed to retrieve idmap of container")
- }
-
- if !nextIdmap.Equals(ctNextIdmap) {
- return fmt.Errorf("Idmaps of container %v and storage volume %v are not identical", ctName, volumeName)
- }
- }
- } else if len(volumeUsedBy) == 1 {
- // If we're the only one who's attached that container
- // we can shift the storage volume.
- // I'm not sure if we want some locking here.
- if volumeUsedBy[0] != c.Name() {
- return fmt.Errorf("idmaps of container and storage volume are not identical")
- }
- }
- }
-
- // Unshift rootfs
- if lastIdmap != nil {
- var err error
-
- if pool.Driver == "zfs" {
- err = lastIdmap.UnshiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
- } else {
- err = lastIdmap.UnshiftRootfs(remapPath, nil)
- }
-
- if err != nil {
- logger.Errorf("Failed to unshift \"%s\"", remapPath)
- return err
- }
-
- logger.Debugf("Unshifted \"%s\"", remapPath)
- }
-
- // Shift rootfs
- if nextIdmap != nil {
- var err error
-
- if pool.Driver == "zfs" {
- err = nextIdmap.ShiftRootfs(remapPath, storageDrivers.ShiftZFSSkipper)
- } else {
- err = nextIdmap.ShiftRootfs(remapPath, nil)
- }
-
- if err != nil {
- logger.Errorf("Failed to shift \"%s\"", remapPath)
- return err
- }
-
- logger.Debugf("Shifted \"%s\"", remapPath)
- }
- logger.Debugf("Shifted storage volume")
- }
-
- jsonIdmap := "[]"
- if nextIdmap != nil {
- var err error
- jsonIdmap, err = idmapsetToJSON(nextIdmap)
- if err != nil {
- logger.Errorf("Failed to marshal idmap")
- return err
- }
- }
-
- // Update last idmap
- poolVolumePut.Config["volatile.idmap.last"] = jsonIdmap
-
- err = s.Cluster.StoragePoolVolumeUpdateByProject("default", volumeName, volumeType, poolID, poolVolumePut.Description, poolVolumePut.Config)
- if err != nil {
- return err
- }
-
- return nil
-}
-
func resetContainerDiskIdmap(container instance.Container, srcIdmap *idmap.IdmapSet) error {
dstIdmap, err := container.DiskIdmap()
if err != nil {
@@ -329,51 +165,6 @@ func storagePoolDriversCacheUpdate(s *state.State) {
return
}
-// 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.(instance.Container)
- if !ok {
- return fmt.Errorf("Received non-LXC container instance")
- }
-
- volumeType, err := storagePools.VolumeTypeNameToType(volumeTypeName)
- if err != nil {
- return err
- }
-
- pool, err := storagePools.GetPoolByName(state, poolName)
- if err != nil {
- return err
- }
-
- // Mount the storage volume.
- ourMount, err := pool.MountCustomVolume(volumeName, nil)
- if err != nil {
- return err
- }
-
- revert := true
- if ourMount {
- defer func() {
- if !revert {
- return
- }
-
- pool.UnmountCustomVolume(volumeName, nil)
- }()
- }
-
- // Custom storage volumes do not currently support projects, so hardcode "default" project.
- err = storagePoolVolumeAttachPrepare(state, poolName, volumeName, volumeType, c)
- if err != nil {
- return err
- }
-
- revert = false
- return nil
-}
-
// storageVolumeUmount unmounts a storage volume on a pool.
func storageVolumeUmount(state *state.State, poolName string, volumeName string, volumeType int) error {
pool, err := storagePools.GetPoolByName(state, poolName)
From a7e3bb5e2c521e2ad49cd6f0893e00076f66a060 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:20:36 +0000
Subject: [PATCH 57/62] lxd/storage/utils: Adds VolumeUsedByInstancesGet
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/utils.go | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index 8fc854c05a..b1dc2d8675 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -628,3 +628,27 @@ func InstanceContentType(inst instance.Instance) drivers.ContentType {
return contentType
}
+
+// VolumeUsedByInstancesGet gets a list of instance names using a volume.
+func VolumeUsedByInstancesGet(s *state.State, project, poolName string, volumeName string) ([]string, error) {
+ insts, err := instance.LoadByProject(s, project)
+ if err != nil {
+ return []string{}, err
+ }
+
+ instUsingVolume := []string{}
+ for _, inst := range insts {
+ for _, dev := range inst.LocalDevices() {
+ if dev["type"] != "disk" {
+ continue
+ }
+
+ if dev["pool"] == poolName && dev["source"] == volumeName {
+ instUsingVolume = append(instUsingVolume, inst.Name())
+ break
+ }
+ }
+ }
+
+ return instUsingVolume, nil
+}
From 4901fa9381bb5bc58ac39788cd44d668e7e314bc Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:20:50 +0000
Subject: [PATCH 58/62] lxd/storage/volumes/utils:
storagePools.VolumeUsedByInstancesGet usage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage_volumes_utils.go | 26 +-------------------------
1 file changed, 1 insertion(+), 25 deletions(-)
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index 8569e23426..e4abfd2d77 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -5,7 +5,6 @@ import (
"path/filepath"
"github.com/lxc/lxd/lxd/db"
- "github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/state"
storagePools "github.com/lxc/lxd/lxd/storage"
"github.com/lxc/lxd/shared"
@@ -76,29 +75,6 @@ func storagePoolVolumeTypeToAPIEndpoint(volumeType int) (string, error) {
return "", fmt.Errorf("invalid storage volume type")
}
-func storagePoolVolumeUsedByInstancesGet(s *state.State, project, poolName string, volumeName string) ([]string, error) {
- insts, err := instance.LoadByProject(s, project)
- if err != nil {
- return []string{}, err
- }
-
- instUsingVolume := []string{}
- for _, inst := range insts {
- for _, dev := range inst.LocalDevices() {
- if dev["type"] != "disk" {
- continue
- }
-
- if dev["pool"] == poolName && dev["source"] == volumeName {
- instUsingVolume = append(instUsingVolume, inst.Name())
- break
- }
- }
- }
-
- return instUsingVolume, nil
-}
-
func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
oldVolumeName string, newPoolName string, newVolumeName string) error {
@@ -311,7 +287,7 @@ func storagePoolVolumeUsedByGet(s *state.State, project, poolName string, volume
}
// Look for containers using this volume
- ctsUsingVolume, err := storagePoolVolumeUsedByInstancesGet(s, project, poolName, volumeName)
+ ctsUsingVolume, err := storagePools.VolumeUsedByInstancesGet(s, project, poolName, volumeName)
if err != nil {
return []string{}, err
}
From f6d8e1186db754acda8480aef0d9130f27db8369 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:28:29 +0000
Subject: [PATCH 59/62] lxd/storage: Removes unused functions
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage.go | 40 ----------------------------------------
1 file changed, 40 deletions(-)
diff --git a/lxd/storage.go b/lxd/storage.go
index 7ddd8ac8cc..b95b9a7ca1 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -9,7 +9,6 @@ import (
"github.com/pkg/errors"
"github.com/lxc/lxd/lxd/db"
- "github.com/lxc/lxd/lxd/device"
"github.com/lxc/lxd/lxd/instance"
"github.com/lxc/lxd/lxd/state"
storagePools "github.com/lxc/lxd/lxd/storage"
@@ -20,14 +19,6 @@ import (
"github.com/lxc/lxd/shared/version"
)
-func init() {
- // Expose storageVolumeUmount to the device package as StorageVolumeUmount.
- device.StorageVolumeUmount = storageVolumeUmount
-
- // Expose storageRootFSApplyQuota to the device package as StorageRootFSApplyQuota.
- device.StorageRootFSApplyQuota = storageRootFSApplyQuota
-}
-
// Simply cache used to storage the activated drivers on this LXD instance. This
// allows us to avoid querying the database everytime and API call is made.
var storagePoolDriversCacheVal atomic.Value
@@ -164,34 +155,3 @@ func storagePoolDriversCacheUpdate(s *state.State) {
return
}
-
-// storageVolumeUmount unmounts a storage volume on a pool.
-func storageVolumeUmount(state *state.State, poolName string, volumeName string, volumeType int) error {
- pool, err := storagePools.GetPoolByName(state, poolName)
- if err != nil {
- return err
- }
-
- _, err = pool.UnmountCustomVolume(volumeName, nil)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// storageRootFSApplyQuota applies a quota to an instance if it can, if it cannot then it will
-// return false indicating that the quota needs to be stored in volatile to be applied on next boot.
-func storageRootFSApplyQuota(state *state.State, inst instance.Instance, size string) error {
- pool, err := storagePools.GetPoolByInstance(state, inst)
- if err != nil {
- return err
- }
-
- err = pool.SetInstanceQuota(inst, size, nil)
- if err != nil {
- return err
- }
-
- return nil
-}
From 549ee02079d5ef76f0e5032b00eec0bd3698aea7 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:28:54 +0000
Subject: [PATCH 60/62] lxd/device: Removes usage of StorageRootFSApplyQuota,
StorageVolumeMount and StorageVolumeUmount
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/device/device_utils_disk.go | 11 -----------
lxd/device/disk.go | 20 ++++++++++++++++++--
2 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/lxd/device/device_utils_disk.go b/lxd/device/device_utils_disk.go
index 739f42eccb..1078ff6ef6 100644
--- a/lxd/device/device_utils_disk.go
+++ b/lxd/device/device_utils_disk.go
@@ -12,21 +12,10 @@ import (
"golang.org/x/sys/unix"
- "github.com/lxc/lxd/lxd/instance"
- "github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/idmap"
)
-// StorageVolumeMount checks if storage volume is mounted and if not tries to mount it.
-var StorageVolumeMount func(s *state.State, poolName string, volumeName string, volumeTypeName string, inst instance.Instance) error
-
-// StorageVolumeUmount unmounts a storage volume.
-var StorageVolumeUmount func(s *state.State, poolName string, volumeName string, volumeType int) error
-
-// StorageRootFSApplyQuota applies a new quota.
-var StorageRootFSApplyQuota func(s *state.State, inst instance.Instance, size string) error
-
// BlockFsDetect detects the type of block device.
func BlockFsDetect(dev string) (string, error) {
out, err := shared.RunCommand("blkid", "-s", "TYPE", "-o", "value", dev)
diff --git a/lxd/device/disk.go b/lxd/device/disk.go
index 18be1fc2a4..0c41be7986 100644
--- a/lxd/device/disk.go
+++ b/lxd/device/disk.go
@@ -494,7 +494,17 @@ func (d *disk) Update(oldDevices deviceConfig.Devices, isRunning bool) error {
}
func (d *disk) applyQuota(newSize string) error {
- return StorageRootFSApplyQuota(d.state, d.inst, newSize)
+ pool, err := storagePools.GetPoolByInstance(d.state, d.inst)
+ if err != nil {
+ return err
+ }
+
+ err = pool.SetInstanceQuota(d.inst, newSize, nil)
+ if err != nil {
+ return err
+ }
+
+ return nil
}
// generateLimits adds a set of cgroup rules to apply specified limits to the supplied RunConfig.
@@ -991,11 +1001,17 @@ func (d *disk) Stop() (*deviceConfig.RunConfig, error) {
func (d *disk) postStop() error {
// Check if pool-specific action should be taken.
if d.config["pool"] != "" {
- err := StorageVolumeUmount(d.state, d.config["pool"], d.config["source"], db.StoragePoolVolumeTypeCustom)
+ pool, err := storagePools.GetPoolByName(d.state, d.config["pool"])
if err != nil {
return err
}
+ _, err = pool.UnmountCustomVolume(d.config["source"], nil)
+ if err != nil {
+ return err
+ }
+
+ return nil
}
devPath := d.getDevicePath(d.name, d.config)
From 742486983b1ab47b03b04a125e9362809f866f2a Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:42:16 +0000
Subject: [PATCH 61/62] lxd: Removes old storagePoolVolumeType constants
Replaces with db.StoragePoolVolumeType constants.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/api_internal.go | 8 ++--
lxd/daemon_storage.go | 4 +-
lxd/migrate_storage_volumes.go | 5 ++-
lxd/patches.go | 78 ++++++++++++++++-----------------
lxd/storage_pools_utils.go | 2 +-
lxd/storage_volumes.go | 12 ++---
lxd/storage_volumes_snapshot.go | 8 ++--
lxd/storage_volumes_utils.go | 21 +++------
8 files changed, 65 insertions(+), 73 deletions(-)
diff --git a/lxd/api_internal.go b/lxd/api_internal.go
index a8fe617433..3f7e20f9d1 100644
--- a/lxd/api_internal.go
+++ b/lxd/api_internal.go
@@ -511,7 +511,7 @@ func internalImport(d *Daemon, r *http.Request) response.Response {
}
// Check if a storage volume entry for the container already exists.
- _, volume, ctVolErr := d.cluster.StoragePoolNodeVolumeGetTypeByProject(projectName, req.Name, storagePoolVolumeTypeContainer, pool.ID())
+ _, volume, ctVolErr := d.cluster.StoragePoolNodeVolumeGetTypeByProject(projectName, req.Name, db.StoragePoolVolumeTypeContainer, pool.ID())
if ctVolErr != nil {
if ctVolErr != db.ErrNoSuchObject {
return response.SmartError(ctVolErr)
@@ -550,7 +550,7 @@ func internalImport(d *Daemon, r *http.Request) response.Response {
}
// Remove the storage volume db entry for the container since force was specified.
- err := d.cluster.StoragePoolVolumeDelete(projectName, req.Name, storagePoolVolumeTypeContainer, pool.ID())
+ err := d.cluster.StoragePoolVolumeDelete(projectName, req.Name, db.StoragePoolVolumeTypeContainer, pool.ID())
if err != nil {
return response.SmartError(err)
}
@@ -651,7 +651,7 @@ func internalImport(d *Daemon, r *http.Request) response.Response {
}
// Check if a storage volume entry for the snapshot already exists.
- _, _, csVolErr := d.cluster.StoragePoolNodeVolumeGetTypeByProject(projectName, snap.Name, storagePoolVolumeTypeContainer, pool.ID())
+ _, _, csVolErr := d.cluster.StoragePoolNodeVolumeGetTypeByProject(projectName, snap.Name, db.StoragePoolVolumeTypeContainer, pool.ID())
if csVolErr != nil {
if csVolErr != db.ErrNoSuchObject {
return response.SmartError(csVolErr)
@@ -671,7 +671,7 @@ func internalImport(d *Daemon, r *http.Request) response.Response {
}
if csVolErr == nil {
- err := d.cluster.StoragePoolVolumeDelete(projectName, snap.Name, storagePoolVolumeTypeContainer, pool.ID())
+ err := d.cluster.StoragePoolVolumeDelete(projectName, snap.Name, db.StoragePoolVolumeTypeContainer, pool.ID())
if err != nil {
return response.SmartError(err)
}
diff --git a/lxd/daemon_storage.go b/lxd/daemon_storage.go
index 4ff8b30fde..86d72ec743 100644
--- a/lxd/daemon_storage.go
+++ b/lxd/daemon_storage.go
@@ -128,12 +128,12 @@ func daemonStorageValidate(s *state.State, target string) error {
}
// Confirm volume exists.
- _, _, err = s.Cluster.StoragePoolNodeVolumeGetType(volumeName, storagePoolVolumeTypeCustom, poolID)
+ _, _, err = s.Cluster.StoragePoolNodeVolumeGetType(volumeName, db.StoragePoolVolumeTypeCustom, poolID)
if err != nil {
return errors.Wrapf(err, "Unable to load storage volume \"%s\"", target)
}
- snapshots, err := s.Cluster.StoragePoolVolumeSnapshotsGetType(volumeName, storagePoolVolumeTypeCustom, poolID)
+ snapshots, err := s.Cluster.StoragePoolVolumeSnapshotsGetType(volumeName, db.StoragePoolVolumeTypeCustom, poolID)
if err != nil {
return errors.Wrapf(err, "Unable to load storage volume snapshots \"%s\"", target)
}
diff --git a/lxd/migrate_storage_volumes.go b/lxd/migrate_storage_volumes.go
index 7d362a3a29..c68133e276 100644
--- a/lxd/migrate_storage_volumes.go
+++ b/lxd/migrate_storage_volumes.go
@@ -6,6 +6,7 @@ import (
"github.com/golang/protobuf/proto"
"github.com/gorilla/websocket"
+ "github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/state"
@@ -66,12 +67,12 @@ func (s *migrationSourceWs) DoStorage(state *state.State, poolName string, volNa
// Only send snapshots when requested.
if !s.volumeOnly {
var err error
- snaps, err := storagePools.VolumeSnapshotsGet(state, poolName, volName, storagePoolVolumeTypeCustom)
+ snaps, err := storagePools.VolumeSnapshotsGet(state, poolName, volName, db.StoragePoolVolumeTypeCustom)
if err == nil {
poolID, err := state.Cluster.StoragePoolGetID(poolName)
if err == nil {
for _, snap := range snaps {
- _, snapVolume, err := state.Cluster.StoragePoolNodeVolumeGetType(snap.Name, storagePoolVolumeTypeCustom, poolID)
+ _, snapVolume, err := state.Cluster.StoragePoolNodeVolumeGetType(snap.Name, db.StoragePoolVolumeTypeCustom, poolID)
if err != nil {
continue
}
diff --git a/lxd/patches.go b/lxd/patches.go
index b657bdd859..fbfaea3420 100644
--- a/lxd/patches.go
+++ b/lxd/patches.go
@@ -213,7 +213,7 @@ func patchRenameCustomVolumeLVs(name string, d *Daemon) error {
continue
}
- volumes, err := d.cluster.StoragePoolNodeVolumesGetType(storagePoolVolumeTypeCustom, poolID)
+ volumes, err := d.cluster.StoragePoolNodeVolumesGetType(db.StoragePoolVolumeTypeCustom, poolID)
if err != nil {
return err
}
@@ -540,16 +540,16 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the container")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, db.StoragePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", storagePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", db.StoragePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
return err
@@ -628,16 +628,16 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the snapshot")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, db.StoragePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", cs, "", storagePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", cs, "", db.StoragePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
return err
@@ -709,16 +709,16 @@ func upgradeFromStorageTypeBtrfs(name string, d *Daemon, defaultPoolName string,
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, db.StoragePoolVolumeTypeImage, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the image")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, db.StoragePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", storagePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", db.StoragePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
return err
@@ -830,16 +830,16 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the container")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, db.StoragePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", storagePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", db.StoragePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
return err
@@ -947,16 +947,16 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the snapshot")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, db.StoragePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", cs, "", storagePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", cs, "", db.StoragePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
return err
@@ -977,16 +977,16 @@ func upgradeFromStorageTypeDir(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, db.StoragePoolVolumeTypeImage, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the image")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, db.StoragePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", storagePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", db.StoragePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
return err
@@ -1139,16 +1139,16 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the container")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, db.StoragePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", storagePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", db.StoragePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
return err
@@ -1300,16 +1300,16 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the snapshot")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, db.StoragePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", storagePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", db.StoragePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
return err
@@ -1483,16 +1483,16 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, db.StoragePoolVolumeTypeImage, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the image")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, db.StoragePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", storagePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", db.StoragePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
return err
@@ -1544,7 +1544,7 @@ func upgradeFromStorageTypeLvm(name string, d *Daemon, defaultPoolName string, d
// This image didn't exist as a logical volume on the
// old LXD instance so we need to kick it from the
// storage volumes database for this pool.
- err := d.cluster.StoragePoolVolumeDelete("default", img, storagePoolVolumeTypeImage, poolID)
+ err := d.cluster.StoragePoolVolumeDelete("default", img, db.StoragePoolVolumeTypeImage, poolID)
if err != nil {
return err
}
@@ -1675,16 +1675,16 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(ct, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the container")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, storagePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", ct, db.StoragePoolVolumeTypeContainer, poolID, "", containerPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", storagePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", ct, "", db.StoragePoolVolumeTypeContainer, false, poolID, containerPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for container \"%s\"", ct)
return err
@@ -1761,16 +1761,16 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, storagePoolVolumeTypeContainer, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(cs, db.StoragePoolVolumeTypeContainer, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the snapshot")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, storagePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", cs, db.StoragePoolVolumeTypeContainer, poolID, "", snapshotPoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", cs, "", storagePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", cs, "", db.StoragePoolVolumeTypeContainer, false, poolID, snapshotPoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for snapshot \"%s\"", cs)
return err
@@ -1817,16 +1817,16 @@ func upgradeFromStorageTypeZfs(name string, d *Daemon, defaultPoolName string, d
return err
}
- _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, storagePoolVolumeTypeImage, poolID)
+ _, err = d.cluster.StoragePoolNodeVolumeGetTypeID(img, db.StoragePoolVolumeTypeImage, poolID)
if err == nil {
logger.Warnf("Storage volumes database already contains an entry for the image")
- err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, storagePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
+ err := d.cluster.StoragePoolVolumeUpdateByProject("default", img, db.StoragePoolVolumeTypeImage, poolID, "", imagePoolVolumeConfig)
if err != nil {
return err
}
} else if err == db.ErrNoSuchObject {
// Insert storage volumes for containers into the database.
- _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", storagePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
+ _, err := d.cluster.StoragePoolVolumeCreate("default", img, "", db.StoragePoolVolumeTypeImage, false, poolID, imagePoolVolumeConfig)
if err != nil {
logger.Errorf("Could not insert a storage volume for image \"%s\"", img)
return err
@@ -3025,7 +3025,7 @@ func patchStorageApiPermissions(name string, d *Daemon) error {
return err
}
- volumes, err := d.cluster.StoragePoolNodeVolumesGetType(storagePoolVolumeTypeCustom, poolID)
+ volumes, err := d.cluster.StoragePoolNodeVolumesGetType(db.StoragePoolVolumeTypeCustom, poolID)
if err != nil && err != db.ErrNoSuchObject {
return err
}
diff --git a/lxd/storage_pools_utils.go b/lxd/storage_pools_utils.go
index c8721f0c16..a069b8b200 100644
--- a/lxd/storage_pools_utils.go
+++ b/lxd/storage_pools_utils.go
@@ -29,7 +29,7 @@ func storagePoolUpdate(state *state.State, name, newDescription string, newConfi
// /1.0/profiles/default
func storagePoolUsedByGet(state *state.State, project string, poolID int64, poolName string) ([]string, error) {
// Retrieve all non-custom volumes that exist on this storage pool.
- volumes, err := state.Cluster.StoragePoolNodeVolumesGet(project, poolID, []int{storagePoolVolumeTypeContainer, storagePoolVolumeTypeImage, storagePoolVolumeTypeCustom, storagePoolVolumeTypeVM})
+ volumes, err := state.Cluster.StoragePoolNodeVolumesGet(project, poolID, []int{db.StoragePoolVolumeTypeContainer, db.StoragePoolVolumeTypeImage, db.StoragePoolVolumeTypeCustom, db.StoragePoolVolumeTypeVM})
if err != nil && err != db.ErrNoSuchObject {
return []string{}, err
}
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 6cd6bcf2fc..08d97662e4 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -108,7 +108,7 @@ func storagePoolVolumesGet(d *Daemon, r *http.Request) response.Response {
return response.SmartError(err)
}
- imageVolumes, err := d.cluster.StoragePoolVolumesGet("default", poolID, []int{storagePoolVolumeTypeImage})
+ imageVolumes, err := d.cluster.StoragePoolVolumesGet("default", poolID, []int{db.StoragePoolVolumeTypeImage})
if err != nil && err != db.ErrNoSuchObject {
return response.SmartError(err)
}
@@ -1079,9 +1079,9 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
}
switch volumeType {
- case storagePoolVolumeTypeCustom:
+ case db.StoragePoolVolumeTypeCustom:
// allowed
- case storagePoolVolumeTypeImage:
+ case db.StoragePoolVolumeTypeImage:
// allowed
default:
return response.BadRequest(fmt.Errorf("Storage volumes of type %q cannot be deleted with the storage API", volumeTypeName))
@@ -1093,7 +1093,7 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
}
if len(volumeUsedBy) > 0 {
- if len(volumeUsedBy) != 1 || volumeType != storagePoolVolumeTypeImage || volumeUsedBy[0] != fmt.Sprintf("/%s/images/%s", version.APIVersion, volumeName) {
+ if len(volumeUsedBy) != 1 || volumeType != db.StoragePoolVolumeTypeImage || volumeUsedBy[0] != fmt.Sprintf("/%s/images/%s", version.APIVersion, volumeName) {
return response.BadRequest(fmt.Errorf("The storage volume is still in use"))
}
}
@@ -1104,9 +1104,9 @@ func storagePoolVolumeTypeDelete(d *Daemon, r *http.Request, volumeTypeName stri
}
switch volumeType {
- case storagePoolVolumeTypeCustom:
+ case db.StoragePoolVolumeTypeCustom:
err = pool.DeleteCustomVolume(volumeName, nil)
- case storagePoolVolumeTypeImage:
+ case db.StoragePoolVolumeTypeImage:
err = pool.DeleteImage(volumeName, nil)
default:
return response.BadRequest(fmt.Errorf(`Storage volumes of type %q cannot be deleted with the storage api`, volumeTypeName))
diff --git a/lxd/storage_volumes_snapshot.go b/lxd/storage_volumes_snapshot.go
index 0325936ba2..dca4382915 100644
--- a/lxd/storage_volumes_snapshot.go
+++ b/lxd/storage_volumes_snapshot.go
@@ -243,7 +243,7 @@ func storagePoolVolumeSnapshotTypePost(d *Daemon, r *http.Request) response.Resp
}
// Check that the storage volume type is valid.
- if volumeType != storagePoolVolumeTypeCustom {
+ if volumeType != db.StoragePoolVolumeTypeCustom {
return response.BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
}
@@ -304,7 +304,7 @@ func storagePoolVolumeSnapshotTypeGet(d *Daemon, r *http.Request) response.Respo
}
// Check that the storage volume type is valid.
- if volumeType != storagePoolVolumeTypeCustom {
+ if volumeType != db.StoragePoolVolumeTypeCustom {
return response.BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
}
@@ -361,7 +361,7 @@ func storagePoolVolumeSnapshotTypePut(d *Daemon, r *http.Request) response.Respo
}
// Check that the storage volume type is valid.
- if volumeType != storagePoolVolumeTypeCustom {
+ if volumeType != db.StoragePoolVolumeTypeCustom {
return response.BadRequest(fmt.Errorf("Invalid storage volume type %s", volumeTypeName))
}
@@ -441,7 +441,7 @@ func storagePoolVolumeSnapshotTypeDelete(d *Daemon, r *http.Request) response.Re
}
// Check that the storage volume type is valid.
- if volumeType != storagePoolVolumeTypeCustom {
+ if volumeType != db.StoragePoolVolumeTypeCustom {
return response.BadRequest(fmt.Errorf("invalid storage volume type %s", volumeTypeName))
}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index e4abfd2d77..bf2e413a72 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -12,15 +12,6 @@ import (
"github.com/lxc/lxd/shared/version"
)
-// XXX: backward compatible declarations, introduced when the db code was
-// extracted to its own package. We should eventually clean this up.
-const (
- storagePoolVolumeTypeContainer = db.StoragePoolVolumeTypeContainer
- storagePoolVolumeTypeVM = db.StoragePoolVolumeTypeVM
- storagePoolVolumeTypeImage = db.StoragePoolVolumeTypeImage
- storagePoolVolumeTypeCustom = db.StoragePoolVolumeTypeCustom
-)
-
const (
storagePoolVolumeTypeNameContainer = db.StoragePoolVolumeTypeNameContainer
storagePoolVolumeTypeNameVM = db.StoragePoolVolumeTypeNameVM
@@ -38,8 +29,8 @@ const (
storagePoolVolumeAPIEndpointCustom string = "custom"
)
-var supportedVolumeTypesExceptImages = []int{storagePoolVolumeTypeContainer, storagePoolVolumeTypeVM, storagePoolVolumeTypeCustom}
-var supportedVolumeTypes = append(supportedVolumeTypesExceptImages, storagePoolVolumeTypeImage)
+var supportedVolumeTypesExceptImages = []int{db.StoragePoolVolumeTypeContainer, db.StoragePoolVolumeTypeVM, db.StoragePoolVolumeTypeCustom}
+var supportedVolumeTypes = append(supportedVolumeTypesExceptImages, db.StoragePoolVolumeTypeImage)
func init() {
storagePools.VolumeUsedByInstancesWithProfiles = storagePoolVolumeUsedByRunningInstancesWithProfilesGet
@@ -62,13 +53,13 @@ func storagePoolVolumeTypeNameToAPIEndpoint(volumeTypeName string) (string, erro
func storagePoolVolumeTypeToAPIEndpoint(volumeType int) (string, error) {
switch volumeType {
- case storagePoolVolumeTypeContainer:
+ case db.StoragePoolVolumeTypeContainer:
return storagePoolVolumeAPIEndpointContainers, nil
- case storagePoolVolumeTypeVM:
+ case db.StoragePoolVolumeTypeVM:
return storagePoolVolumeAPIEndpointVMs, nil
- case storagePoolVolumeTypeImage:
+ case db.StoragePoolVolumeTypeImage:
return storagePoolVolumeAPIEndpointImages, nil
- case storagePoolVolumeTypeCustom:
+ case db.StoragePoolVolumeTypeCustom:
return storagePoolVolumeAPIEndpointCustom, nil
}
From 1eb809573ed0a870e4fafeaa48a2fd0fc76424b8 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 28 Feb 2020 15:44:42 +0000
Subject: [PATCH 62/62] lxd: Removes storagePoolVolumeType constants
Replaces with db.storagePoolVolumeType constants.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage_volumes.go | 6 +++---
lxd/storage_volumes_utils.go | 23 ++++++++---------------
2 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/lxd/storage_volumes.go b/lxd/storage_volumes.go
index 08d97662e4..1c5a63db55 100644
--- a/lxd/storage_volumes.go
+++ b/lxd/storage_volumes.go
@@ -274,7 +274,7 @@ func storagePoolVolumesTypePost(d *Daemon, r *http.Request) response.Response {
// We currently only allow to create storage volumes of type
// storagePoolVolumeTypeCustom. So check, that nothing else was
// requested.
- if req.Type != storagePoolVolumeTypeNameCustom {
+ if req.Type != db.StoragePoolVolumeTypeNameCustom {
return response.BadRequest(fmt.Errorf(`Currently not allowed to create `+
`storage volumes of type %s`, req.Type))
}
@@ -376,7 +376,7 @@ func storagePoolVolumesPost(d *Daemon, r *http.Request) response.Response {
// We currently only allow to create storage volumes of type
// storagePoolVolumeTypeCustom. So check, that nothing else was
// requested.
- if req.Type != storagePoolVolumeTypeNameCustom {
+ if req.Type != db.StoragePoolVolumeTypeNameCustom {
return response.BadRequest(fmt.Errorf(`Currently not allowed to create `+
`storage volumes of type %s`, req.Type))
}
@@ -522,7 +522,7 @@ func storagePoolVolumeTypePost(d *Daemon, r *http.Request, volumeTypeName string
// We currently only allow to create storage volumes of type storagePoolVolumeTypeCustom.
// So check, that nothing else was requested.
- if volumeTypeName != storagePoolVolumeTypeNameCustom {
+ if volumeTypeName != db.StoragePoolVolumeTypeNameCustom {
return response.BadRequest(fmt.Errorf("Renaming storage volumes of type %s is not allowed", volumeTypeName))
}
diff --git a/lxd/storage_volumes_utils.go b/lxd/storage_volumes_utils.go
index bf2e413a72..f478a519e9 100644
--- a/lxd/storage_volumes_utils.go
+++ b/lxd/storage_volumes_utils.go
@@ -12,13 +12,6 @@ import (
"github.com/lxc/lxd/shared/version"
)
-const (
- storagePoolVolumeTypeNameContainer = db.StoragePoolVolumeTypeNameContainer
- storagePoolVolumeTypeNameVM = db.StoragePoolVolumeTypeNameVM
- storagePoolVolumeTypeNameImage = db.StoragePoolVolumeTypeNameImage
- storagePoolVolumeTypeNameCustom = db.StoragePoolVolumeTypeNameCustom
-)
-
// Leave the string type in here! This guarantees that go treats this is as a
// typed string constant. Removing it causes go to treat these as untyped string
// constants which is not what we want.
@@ -38,13 +31,13 @@ func init() {
func storagePoolVolumeTypeNameToAPIEndpoint(volumeTypeName string) (string, error) {
switch volumeTypeName {
- case storagePoolVolumeTypeNameContainer:
+ case db.StoragePoolVolumeTypeNameContainer:
return storagePoolVolumeAPIEndpointContainers, nil
- case storagePoolVolumeTypeNameVM:
+ case db.StoragePoolVolumeTypeNameVM:
return storagePoolVolumeAPIEndpointVMs, nil
- case storagePoolVolumeTypeNameImage:
+ case db.StoragePoolVolumeTypeNameImage:
return storagePoolVolumeAPIEndpointImages, nil
- case storagePoolVolumeTypeNameCustom:
+ case db.StoragePoolVolumeTypeNameCustom:
return storagePoolVolumeAPIEndpointCustom, nil
}
@@ -95,7 +88,7 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
dir, file := filepath.Split(devices[k]["source"])
dir = filepath.Clean(dir)
- if dir != storagePoolVolumeTypeNameCustom {
+ if dir != db.StoragePoolVolumeTypeNameCustom {
continue
}
@@ -114,7 +107,7 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
if oldVolumeName != newVolumeName {
newSource := newVolumeName
if dir != "" {
- newSource = fmt.Sprintf("%s/%s", storagePoolVolumeTypeNameCustom, newVolumeName)
+ newSource = fmt.Sprintf("%s/%s", db.StoragePoolVolumeTypeNameCustom, newVolumeName)
}
devices[k]["source"] = newSource
}
@@ -171,7 +164,7 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
dir, file := filepath.Split(profile.Devices[k]["source"])
dir = filepath.Clean(dir)
- if dir != storagePoolVolumeTypeNameCustom {
+ if dir != db.StoragePoolVolumeTypeNameCustom {
continue
}
@@ -190,7 +183,7 @@ func storagePoolVolumeUpdateUsers(d *Daemon, oldPoolName string,
if oldVolumeName != newVolumeName {
newSource := newVolumeName
if dir != "" {
- newSource = fmt.Sprintf("%s/%s", storagePoolVolumeTypeNameCustom, newVolumeName)
+ newSource = fmt.Sprintf("%s/%s", db.StoragePoolVolumeTypeNameCustom, newVolumeName)
}
profile.Devices[k]["source"] = newSource
}
More information about the lxc-devel
mailing list