[lxc-devel] [lxd/master] Storage Create Instance From Image
tomponline on Github
lxc-bot at linuxcontainers.org
Fri Nov 1 16:07:31 UTC 2019
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20191101/042f95d4/attachment.bin>
-------------- next part --------------
From 6e54f64ca62105e1a344d7e2a11d58ae81595164 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 10:21:43 +0000
Subject: [PATCH 01/13] lxd/storage/load: Adds GetPoolByInstanceName
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/load.go | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lxd/storage/load.go b/lxd/storage/load.go
index 1c134d75d6..eb7fa6e1a2 100644
--- a/lxd/storage/load.go
+++ b/lxd/storage/load.go
@@ -128,3 +128,13 @@ func GetPoolByName(state *state.State, name string) (Pool, error) {
return &pool, nil
}
+
+// GetPoolByInstanceName retrieves the pool from the database using the instance's project and name.
+func GetPoolByInstanceName(s *state.State, projectName, instanceName string) (Pool, error) {
+ poolName, err := s.Cluster.ContainerPool(projectName, instanceName)
+ if err != nil {
+ return nil, err
+ }
+
+ return GetPoolByName(s, poolName)
+}
From a98656fd1a12dbfc6c2be5b7b40eed10ae35808b Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:36:18 +0000
Subject: [PATCH 02/13] lxd/container: Links containerCreateFromImage to new
storage layer
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/container.go | 37 +++++++++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/lxd/container.go b/lxd/container.go
index f4cfe3fe44..589525ce5e 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -24,6 +24,8 @@ import (
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/lxd/state"
+ storagePools "github.com/lxc/lxd/lxd/storage"
+ storageDrivers "github.com/lxc/lxd/lxd/storage/drivers"
"github.com/lxc/lxd/lxd/sys"
"github.com/lxc/lxd/lxd/task"
"github.com/lxc/lxd/shared"
@@ -356,7 +358,7 @@ func containerCreateEmptySnapshot(s *state.State, args db.InstanceArgs) (contain
return c, nil
}
-func containerCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, tracker *ioprogress.ProgressTracker) (container, error) {
+func containerCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *operations.Operation) (container, error) {
s := d.State()
// Get the image properties
@@ -424,11 +426,34 @@ func containerCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, trac
return nil, fmt.Errorf("Error updating image last use date: %s", err)
}
- // Now create the storage from an image
- err = c.Storage().ContainerCreateFromImage(c, hash, tracker)
- if err != nil {
- c.Delete()
- return nil, errors.Wrap(err, "Create container from image")
+ // Check if we can load new storage layer for pool driver type.
+ pool, err := storagePools.GetPoolByInstanceName(d.State(), c.Project(), c.Name())
+ if err != storageDrivers.ErrUnknownDriver {
+ if err != nil {
+ return nil, errors.Wrap(err, "Load instance storage pool")
+ }
+
+ err = pool.CreateInstanceFromImage(c, hash, op)
+ if err != nil {
+ return nil, errors.Wrap(err, "Create instance from image")
+ }
+ } else {
+ metadata := make(map[string]interface{})
+ var tracker *ioprogress.ProgressTracker
+ if op != nil {
+ tracker = &ioprogress.ProgressTracker{
+ Handler: func(percent, speed int64) {
+ shared.SetProgressMetadata(metadata, "create_container_from_image_unpack", "Unpack", percent, 0, speed)
+ op.UpdateMetadata(metadata)
+ }}
+ }
+
+ // Now create the storage from an image
+ err = c.Storage().ContainerCreateFromImage(c, hash, tracker)
+ if err != nil {
+ c.Delete()
+ return nil, errors.Wrap(err, "Create container from image")
+ }
}
// Apply any post-storage configuration
From 7ca2b7f4121ffe10a09a1a1a92deb57f222f1bde Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:36:48 +0000
Subject: [PATCH 03/13] lxd/containers/post: Moves progress tracker into
containerCreateFromImage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/containers_post.go | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/lxd/containers_post.go b/lxd/containers_post.go
index 02f05b6c79..0fd29b04b1 100644
--- a/lxd/containers_post.go
+++ b/lxd/containers_post.go
@@ -27,7 +27,6 @@ import (
"github.com/lxc/lxd/lxd/response"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
- "github.com/lxc/lxd/shared/ioprogress"
log "github.com/lxc/lxd/shared/log15"
"github.com/lxc/lxd/shared/logger"
"github.com/lxc/lxd/shared/osarch"
@@ -137,12 +136,7 @@ func createFromImage(d *Daemon, project string, req *api.InstancesPost) response
return err
}
- metadata := make(map[string]interface{})
- _, err = containerCreateFromImage(d, args, info.Fingerprint, &ioprogress.ProgressTracker{
- Handler: func(percent, speed int64) {
- shared.SetProgressMetadata(metadata, "create_container_from_image_unpack", "Unpack", percent, 0, speed)
- op.UpdateMetadata(metadata)
- }})
+ _, err = containerCreateFromImage(d, args, info.Fingerprint, op)
return err
}
From c3be23b19bc70bbe5709d6ab00d0b28b83e8eff6 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:37:09 +0000
Subject: [PATCH 04/13] lxd/images: Removes old unpackImage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/images.go | 32 --------------------------------
1 file changed, 32 deletions(-)
diff --git a/lxd/images.go b/lxd/images.go
index 77b543cd06..c43e2c4345 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -107,38 +107,6 @@ var imageAliasCmd = APIEndpoint{
end for whichever finishes last. */
var imagePublishLock sync.Mutex
-func unpackImage(imagefname string, destpath string, sType storageType, runningInUserns bool, tracker *ioprogress.ProgressTracker) error {
- blockBackend := false
-
- if sType == storageTypeLvm || sType == storageTypeCeph {
- blockBackend = true
- }
-
- err := shared.Unpack(imagefname, destpath, blockBackend, runningInUserns, tracker)
- if err != nil {
- return err
- }
-
- rootfsPath := fmt.Sprintf("%s/rootfs", destpath)
- if shared.PathExists(imagefname + ".rootfs") {
- err = os.MkdirAll(rootfsPath, 0755)
- if err != nil {
- return fmt.Errorf("Error creating rootfs directory")
- }
-
- err = shared.Unpack(imagefname+".rootfs", rootfsPath, blockBackend, runningInUserns, tracker)
- if err != nil {
- return err
- }
- }
-
- if !shared.PathExists(rootfsPath) {
- return fmt.Errorf("Image is missing a rootfs: %s", imagefname)
- }
-
- return nil
-}
-
func compressFile(compress string, infile io.Reader, outfile io.Writer) error {
reproducible := []string{"gzip"}
From fe2b8ec35ae8410bfcf6c2458699221162b3a52c Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:37:38 +0000
Subject: [PATCH 05/13] lxd/storage/backend/lxd: Implements
CreateInstanceFromImage
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/backend_lxd.go | 77 +++++++++++++++++++++++++++++++++++++-
1 file changed, 75 insertions(+), 2 deletions(-)
diff --git a/lxd/storage/backend_lxd.go b/lxd/storage/backend_lxd.go
index 3a51642a92..3ac4a05a11 100644
--- a/lxd/storage/backend_lxd.go
+++ b/lxd/storage/backend_lxd.go
@@ -11,11 +11,13 @@ import (
"github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/migration"
"github.com/lxc/lxd/lxd/operations"
+ "github.com/lxc/lxd/lxd/project"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/lxd/storage/drivers"
"github.com/lxc/lxd/lxd/storage/memorypipe"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/ioprogress"
log "github.com/lxc/lxd/shared/log15"
"github.com/lxc/lxd/shared/logger"
"github.com/lxc/lxd/shared/logging"
@@ -171,8 +173,75 @@ func (b *lxdBackend) CreateInstanceFromCopy(inst Instance, src Instance, snapsho
return ErrNotImplemented
}
+// createInstanceSymlink creates a symlink in the instance directory to the instance's mount path.
+func (b *lxdBackend) createInstanceSymlink(inst Instance, mountPath string) error {
+ symlinkPath := inst.Path()
+ if !shared.PathExists(symlinkPath) {
+ err := os.Symlink(mountPath, symlinkPath)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// CreateInstanceFromImage creates a new volume for an instance populated with the image requested.
func (b *lxdBackend) CreateInstanceFromImage(inst Instance, fingerprint string, op *operations.Operation) error {
- return ErrNotImplemented
+ logger := logging.AddContext(b.logger, log.Ctx{"project": inst.Project(), "instance": inst.Name()})
+ logger.Debug("CreateInstanceFromImage started")
+ defer logger.Debug("CreateInstanceFromImage finished")
+
+ volType, err := InstanceTypeToVolumeType(inst.Type())
+ if err != nil {
+ return err
+ }
+
+ revert := true
+ defer func() {
+ if !revert {
+ return
+ }
+ b.DeleteInstance(inst, op)
+ }()
+
+ filler := func(instanceMountPath string) error {
+ var tracker *ioprogress.ProgressTracker
+ if op != nil { // Not passed when being done as part of pre-migration setup.
+ metadata := make(map[string]interface{})
+ tracker = &ioprogress.ProgressTracker{
+ Handler: func(percent, speed int64) {
+ shared.SetProgressMetadata(metadata, "create_instance_from_image_unpack", "Unpack", percent, 0, speed)
+ op.UpdateMetadata(metadata)
+ }}
+ }
+
+ imagePath := shared.VarPath("images", fingerprint)
+
+ // tomp TODO currently passing false to isBlockBackend argument, which only affects
+ // user hint on how to increase disk space if not enough to unpack image. Ask about
+ // removing this argument entirely.
+ return ImageUnpack(imagePath, instanceMountPath, false, b.state.OS.RunningInUserNS, tracker)
+ }
+
+ vol := b.newVolume(volType, drivers.ContentTypeFS, project.Prefix(inst.Project(), inst.Name()), nil)
+ err = b.driver.CreateVolume(vol, filler, op)
+ if err != nil {
+ return err
+ }
+
+ err = b.createInstanceSymlink(inst, vol.MountPath())
+ if err != nil {
+ return err
+ }
+
+ err = inst.TemplateApply("create")
+ if err != nil {
+ return err
+ }
+
+ revert = false
+ return nil
}
func (b *lxdBackend) CreateInstanceFromMigration(inst Instance, conn io.ReadWriteCloser, args migration.SinkArgs, op *operations.Operation) error {
@@ -184,6 +253,10 @@ func (b *lxdBackend) RenameInstance(inst Instance, newName string, op *operation
}
func (b *lxdBackend) DeleteInstance(inst Instance, op *operations.Operation) error {
+ logger := logging.AddContext(b.logger, log.Ctx{"project": inst.Project(), "instance": inst.Name()})
+ logger.Debug("DeleteInstance started")
+ defer logger.Debug("DeleteInstance finished")
+
return ErrNotImplemented
}
@@ -201,7 +274,7 @@ func (b *lxdBackend) BackupInstance(inst Instance, targetPath string, optimized
// GetInstanceUsage returns the disk usage of the Instance's root device.
func (b *lxdBackend) GetInstanceUsage(inst Instance) (int64, error) {
- logger := logging.AddContext(b.logger, log.Ctx{"instance": inst.Name()})
+ logger := logging.AddContext(b.logger, log.Ctx{"project": inst.Project(), "instance": inst.Name()})
logger.Debug("GetInstanceUsage started")
defer logger.Debug("GetInstanceUsage finished")
From 5b00064598537b4f791f16312542f9bbfed6416e Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:38:18 +0000
Subject: [PATCH 06/13] lxd/storage/drivers/driver/dir: Switches to using
volume.CreateMounthPath()
To ensure perms are applied consistently and correctly across all drivers.
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/drivers/driver_dir.go | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/lxd/storage/drivers/driver_dir.go b/lxd/storage/drivers/driver_dir.go
index f50ee8ceef..816664c420 100644
--- a/lxd/storage/drivers/driver_dir.go
+++ b/lxd/storage/drivers/driver_dir.go
@@ -172,9 +172,10 @@ func (d *dir) CreateVolume(vol Volume, filler func(path string) error, op *opera
volID, err := d.getVolID(vol.volType, vol.name)
if err != nil {
return err
+
}
- err = os.MkdirAll(volPath, 0711)
+ err = vol.CreateMountPath()
if err != nil {
return err
}
@@ -286,7 +287,7 @@ func (d *dir) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, vol
}
snapPath := snapshot.MountPath()
- err = os.MkdirAll(snapPath, 0711)
+ err = snapshot.CreateMountPath()
if err != nil {
return err
}
@@ -317,7 +318,7 @@ func (d *dir) CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, vol
volPath := vol.MountPath()
// Finally the actual volume is sent by sender, so create that last.
- err = os.MkdirAll(volPath, 0711)
+ err = vol.CreateMountPath()
if err != nil {
return err
}
@@ -393,7 +394,7 @@ func (d *dir) CreateVolumeFromCopy(vol Volume, srcVol Volume, copySnapshots bool
}
dstSnapPath := dstSnapshot.MountPath()
- err = os.MkdirAll(dstSnapPath, 0711)
+ err = dstSnapshot.CreateMountPath()
if err != nil {
return err
}
@@ -416,7 +417,7 @@ func (d *dir) CreateVolumeFromCopy(vol Volume, srcVol Volume, copySnapshots bool
}
volPath := vol.MountPath()
- err = os.MkdirAll(volPath, 0711)
+ err = vol.CreateMountPath()
if err != nil {
return err
}
@@ -513,6 +514,7 @@ func (d *dir) RenameVolume(volType VolumeType, volName string, newVolName string
return err
}
+ // tomp TODO check old snapshots dir is removed.
err = os.MkdirAll(snapshotDir, 0711)
if err != nil {
return err
@@ -761,10 +763,12 @@ func (d *dir) CreateVolumeSnapshot(volType VolumeType, volName string, newSnapsh
}
srcPath := GetVolumeMountPath(d.name, volType, volName)
- snapPath := GetVolumeMountPath(d.name, volType, GetSnapshotVolumeName(volName, newSnapshotName))
+ fullSnapName := GetSnapshotVolumeName(volName, newSnapshotName)
+ snapVol := NewVolume(d, d.name, volType, ContentTypeFS, fullSnapName, nil)
+ snapPath := snapVol.MountPath()
// Create snapshot directory.
- err = os.MkdirAll(snapPath, 0711)
+ err = snapVol.CreateMountPath()
if err != nil {
return err
}
From 4e69206d98ac48286cd241bfed55526f039b7d02 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:39:02 +0000
Subject: [PATCH 07/13] lxd/storage/drivers/volume: Adds CreateMountPath
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/drivers/volume.go | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/lxd/storage/drivers/volume.go b/lxd/storage/drivers/volume.go
index 5dd78a91fa..a9dacb955c 100644
--- a/lxd/storage/drivers/volume.go
+++ b/lxd/storage/drivers/volume.go
@@ -2,6 +2,7 @@ package drivers
import (
"fmt"
+ "os"
"github.com/lxc/lxd/lxd/operations"
"github.com/lxc/lxd/shared"
@@ -74,6 +75,28 @@ func (v Volume) MountPath() string {
return GetVolumeMountPath(v.pool, v.volType, v.name)
}
+// CreateMountPath creates the volume's mount path and sets the correct permission for the type.
+func (v Volume) CreateMountPath() error {
+ volPath := v.MountPath()
+
+ // Create volume's mount path, with any created directories set to 0711.
+ err := os.MkdirAll(volPath, 0711)
+ if err != nil {
+ return err
+ }
+
+ // Set very restrictive mode 0100 for non-custom and non-image volumes.
+ if v.volType != VolumeTypeCustom && v.volType != VolumeTypeImage {
+ // Set mode of actual volume's mount path.
+ err = os.Chmod(volPath, 0100)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
// MountTask runs the supplied task after mounting the volume if needed. If the volume was mounted
// for this then it is unmounted when the task finishes.
func (v Volume) MountTask(task func(mountPath string, op *operations.Operation) error, op *operations.Operation) error {
From b3f97536789205579bee4320b18ecec75b0e9cc5 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:39:24 +0000
Subject: [PATCH 08/13] lxd/storage/load: Improves getVolID error when volume
not found
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/load.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lxd/storage/load.go b/lxd/storage/load.go
index eb7fa6e1a2..6db6f2834a 100644
--- a/lxd/storage/load.go
+++ b/lxd/storage/load.go
@@ -32,7 +32,7 @@ func volIDFuncMake(state *state.State, poolID int64) func(volType drivers.Volume
volID, _, err := state.Cluster.StoragePoolNodeVolumeGetTypeByProject("default", volName, volTypeID, poolID)
if err != nil {
if err == db.ErrNoSuchObject {
- return -1, fmt.Errorf("Volume doesn't exist")
+ return -1, fmt.Errorf("Failed to get volume ID, volume '%s' of type '%s' doesn't exist", volName, volType)
}
return -1, err
From a4cf41b9f00bb7b08bafe0fa735f553bb8b3ff85 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:40:11 +0000
Subject: [PATCH 09/13] lxd/storage/utils: Adds InstanceTypeToVolumeType
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/utils.go | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index b22e8c1ada..14a40f3e32 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -10,6 +10,7 @@ import (
"golang.org/x/sys/unix"
"github.com/lxc/lxd/lxd/db"
+ "github.com/lxc/lxd/lxd/instance/instancetype"
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/lxd/storage/drivers"
"github.com/lxc/lxd/shared"
@@ -417,6 +418,18 @@ func VolumeTypeToDBType(volType drivers.VolumeType) (int, error) {
return -1, fmt.Errorf("Invalid storage volume type")
}
+// InstanceTypeToVolumeType converts instance type to volume type.
+func InstanceTypeToVolumeType(instType instancetype.Type) (drivers.VolumeType, error) {
+ switch instType {
+ case instancetype.Container:
+ return drivers.VolumeTypeContainer, nil
+ case instancetype.VM:
+ return drivers.VolumeTypeVM, nil
+ }
+
+ return "", fmt.Errorf("Invalid instance type")
+}
+
// VolumeDBCreate creates a volume in the database.
func VolumeDBCreate(s *state.State, poolName string, volumeName, volumeDescription string, volumeTypeName string, snapshot bool, volumeConfig map[string]string) error {
// Convert the volume type name to our internal integer representation.
From b98393ed76969622849b564db154480893cc2387 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:40:22 +0000
Subject: [PATCH 10/13] lxd/storage/utils: Adds ImageUnpack
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/utils.go | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/lxd/storage/utils.go b/lxd/storage/utils.go
index 14a40f3e32..c71f69f980 100644
--- a/lxd/storage/utils.go
+++ b/lxd/storage/utils.go
@@ -15,6 +15,7 @@ import (
"github.com/lxc/lxd/lxd/storage/drivers"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/ioprogress"
"github.com/lxc/lxd/shared/logger"
"github.com/lxc/lxd/shared/units"
)
@@ -696,3 +697,30 @@ func validateVolumeCommonRules() map[string]func(string) error {
},
}
}
+
+// ImageUnpack unpacks a filesystem image into the destination path.
+func ImageUnpack(imageFile string, destPath string, blockBackend bool, runningInUserns bool, tracker *ioprogress.ProgressTracker) error {
+ err := shared.Unpack(imageFile, destPath, blockBackend, runningInUserns, tracker)
+ if err != nil {
+ return err
+ }
+
+ rootfsPath := fmt.Sprintf("%s/rootfs", destPath)
+ if shared.PathExists(imageFile + ".rootfs") {
+ err = os.MkdirAll(rootfsPath, 0755)
+ if err != nil {
+ return fmt.Errorf("Error creating rootfs directory")
+ }
+
+ err = shared.Unpack(imageFile+".rootfs", rootfsPath, blockBackend, runningInUserns, tracker)
+ if err != nil {
+ return err
+ }
+ }
+
+ if !shared.PathExists(rootfsPath) {
+ return fmt.Errorf("Image is missing a rootfs: %s", imageFile)
+ }
+
+ return nil
+}
From 0432f3521ec39ca3d47386ddced3172ee6dbbf82 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:40:39 +0000
Subject: [PATCH 11/13] test/suites/basic: Updates tests to take into account
more secure volume perms
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
test/suites/basic.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/suites/basic.sh b/test/suites/basic.sh
index 29dfe6d64b..a3f7334f9e 100644
--- a/test/suites/basic.sh
+++ b/test/suites/basic.sh
@@ -423,7 +423,7 @@ test_basic_usage() {
lxc profile create unconfined
lxc profile set unconfined security.privileged true
lxc init testimage foo2 -p unconfined -s "lxdtest-$(basename "${LXD_DIR}")"
- [ "$(stat -L -c "%a" "${LXD_DIR}/containers/foo2")" = "700" ]
+ [ "$(stat -L -c "%a" "${LXD_DIR}/containers/foo2")" = "100" ]
lxc delete foo2
lxc profile delete unconfined
From e93175747e743d0dcbf7adfe7a06e9d66ffa64ee Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 14:41:11 +0000
Subject: [PATCH 12/13] lxd: Updates use of driver.ImageUnpack
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage_btrfs.go | 2 +-
lxd/storage_ceph.go | 2 +-
lxd/storage_dir.go | 2 +-
lxd/storage_lvm.go | 2 +-
lxd/storage_lvm_utils.go | 2 +-
lxd/storage_zfs.go | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 85a73b8f7c..ff1eb628f6 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -2008,7 +2008,7 @@ func (s *storageBtrfs) ImageCreate(fingerprint string, tracker *ioprogress.Progr
// Unpack the image in imageMntPoint.
imagePath := shared.VarPath("images", fingerprint)
- err = unpackImage(imagePath, tmpImageSubvolumeName, storageTypeBtrfs, s.s.OS.RunningInUserNS, tracker)
+ err = driver.ImageUnpack(imagePath, tmpImageSubvolumeName, false, s.s.OS.RunningInUserNS, tracker)
if err != nil {
return err
}
diff --git a/lxd/storage_ceph.go b/lxd/storage_ceph.go
index 526a02f1a6..846cc91155 100644
--- a/lxd/storage_ceph.go
+++ b/lxd/storage_ceph.go
@@ -2102,7 +2102,7 @@ func (s *storageCeph) ImageCreate(fingerprint string, tracker *ioprogress.Progre
// rsync contents into image
imagePath := shared.VarPath("images", fingerprint)
- err = unpackImage(imagePath, imageMntPoint, storageTypeCeph, s.s.OS.RunningInUserNS, nil)
+ err = driver.ImageUnpack(imagePath, imageMntPoint, true, s.s.OS.RunningInUserNS, nil)
if err != nil {
logger.Errorf(`Failed to unpack image for RBD storage volume for image "%s" on storage pool "%s": %s`, fingerprint, s.pool.Name, err)
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index e005c880d6..844849ae0f 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -572,7 +572,7 @@ func (s *storageDir) ContainerCreateFromImage(container Instance, imageFingerpri
}
imagePath := shared.VarPath("images", imageFingerprint)
- err = unpackImage(imagePath, containerMntPoint, storageTypeDir, s.s.OS.RunningInUserNS, nil)
+ err = driver.ImageUnpack(imagePath, containerMntPoint, false, s.s.OS.RunningInUserNS, nil)
if err != nil {
return errors.Wrap(err, "Unpack image")
}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 763c0c5de1..4a05f07206 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -1939,7 +1939,7 @@ func (s *storageLvm) ImageCreate(fingerprint string, tracker *ioprogress.Progres
}
imagePath := shared.VarPath("images", fingerprint)
- err = unpackImage(imagePath, imageMntPoint, storageTypeLvm, s.s.OS.RunningInUserNS, nil)
+ err = driver.ImageUnpack(imagePath, imageMntPoint, true, s.s.OS.RunningInUserNS, nil)
if err != nil {
return err
}
diff --git a/lxd/storage_lvm_utils.go b/lxd/storage_lvm_utils.go
index f782366ad2..56a60c8d11 100644
--- a/lxd/storage_lvm_utils.go
+++ b/lxd/storage_lvm_utils.go
@@ -504,7 +504,7 @@ func (s *storageLvm) containerCreateFromImageLv(c Instance, fp string) error {
imagePath := shared.VarPath("images", fp)
containerMntPoint := driver.GetContainerMountPoint(c.Project(), s.pool.Name, containerName)
- err = unpackImage(imagePath, containerMntPoint, storageTypeLvm, s.s.OS.RunningInUserNS, nil)
+ err = driver.ImageUnpack(imagePath, containerMntPoint, true, s.s.OS.RunningInUserNS, nil)
if err != nil {
logger.Errorf(`Failed to unpack image "%s" into non-thinpool LVM storage volume "%s" for container "%s" on storage pool "%s": %s`, imagePath, containerMntPoint, containerName, s.pool.Name, err)
return err
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index 0e5d7d3cc9..139fbba671 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -2406,7 +2406,7 @@ func (s *storageZfs) ImageCreate(fingerprint string, tracker *ioprogress.Progres
}
// Unpack the image into the temporary mountpoint.
- err = unpackImage(imagePath, tmpImageDir, storageTypeZfs, s.s.OS.RunningInUserNS, nil)
+ err = driver.ImageUnpack(imagePath, tmpImageDir, false, s.s.OS.RunningInUserNS, nil)
if err != nil {
return err
}
From db021c9bfc1761babaed53919fc92b2d43a430ba Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parrott at canonical.com>
Date: Fri, 1 Nov 2019 16:06:03 +0000
Subject: [PATCH 13/13] lxd/storage/load: Makes volIDFuncMake project aware
Signed-off-by: Thomas Parrott <thomas.parrott at canonical.com>
---
lxd/storage/load.go | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/lxd/storage/load.go b/lxd/storage/load.go
index 6db6f2834a..725a0bf2b7 100644
--- a/lxd/storage/load.go
+++ b/lxd/storage/load.go
@@ -2,6 +2,7 @@ package storage
import (
"fmt"
+ "strings"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/operations"
@@ -28,11 +29,21 @@ func volIDFuncMake(state *state.State, poolID int64) func(volType drivers.Volume
return -1, err
}
- // TODO add project support in the future by splitting the volName by "_".
- volID, _, err := state.Cluster.StoragePoolNodeVolumeGetTypeByProject("default", volName, volTypeID, poolID)
+ // It is possible for the project name to be encoded into the volume name in the
+ // format <project>_<volume>. However not all volume types currently use this
+ // encoding format, so if there is no underscore in the volume name then we assume
+ // the project is default.
+ project := "default"
+ volParts := strings.SplitN(volName, "_", 2)
+ if len(volParts) > 1 {
+ project = volParts[0]
+ volName = volParts[1]
+ }
+
+ volID, _, err := state.Cluster.StoragePoolNodeVolumeGetTypeByProject(project, volName, volTypeID, poolID)
if err != nil {
if err == db.ErrNoSuchObject {
- return -1, fmt.Errorf("Failed to get volume ID, volume '%s' of type '%s' doesn't exist", volName, volType)
+ return -1, fmt.Errorf("Failed to get volume ID for project '%s', volume '%s', type '%s': Volume doesn't exist", project, volName, volType)
}
return -1, err
More information about the lxc-devel
mailing list