[lxc-devel] [lxd/master] Apply image properties in DB during publish
stgraber on Github
lxc-bot at linuxcontainers.org
Mon Jul 13 14:06:27 UTC 2020
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 301 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20200713/0d529f89/attachment.bin>
-------------- next part --------------
From 77e19289c20a218fc59dda591c952287fa8bad1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 13 Jul 2020 09:53:11 -0400
Subject: [PATCH 1/2] lxd/images: Rename imgPostContInfo to imgPostInstanceInfo
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/images.go | 4 ++--
lxd/instance.go | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/lxd/images.go b/lxd/images.go
index 8c14b10d5d..c5453a3ab2 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -174,7 +174,7 @@ func compressFile(compress string, infile io.Reader, outfile io.Writer) error {
* This function takes a container or snapshot from the local image server and
* exports it as an image.
*/
-func imgPostContInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *operations.Operation, builddir string) (*api.Image, error) {
+func imgPostInstanceInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *operations.Operation, builddir string) (*api.Image, error) {
info := api.Image{}
info.Properties = map[string]string{}
project := projectParam(r)
@@ -821,7 +821,7 @@ func imagesPost(d *Daemon, r *http.Request) response.Response {
} else {
/* Processing image creation from container */
imagePublishLock.Lock()
- info, err = imgPostContInfo(d, r, req, op, builddir)
+ info, err = imgPostInstanceInfo(d, r, req, op, builddir)
imagePublishLock.Unlock()
}
}
diff --git a/lxd/instance.go b/lxd/instance.go
index 9b63bb49a0..736c00c273 100644
--- a/lxd/instance.go
+++ b/lxd/instance.go
@@ -126,6 +126,7 @@ func instanceCreateFromImage(d *Daemon, args db.InstanceArgs, hash string, op *o
if img.Properties != nil {
for k, v := range img.Properties {
args.Config[fmt.Sprintf("image.%s", k)] = v
+ logger.Errorf("Setting: image.%v=%v", k, v)
}
}
From ffe63869ef256c135a46d7dd6fcee1a7cc8f45d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Mon, 13 Jul 2020 10:05:33 -0400
Subject: [PATCH 2/2] lxd/instances: Return and set image properties
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes #7648
Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
lxd/images.go | 5 +-
lxd/instance/drivers/driver_lxc.go | 77 +++++++++++++-------------
lxd/instance/drivers/driver_qemu.go | 85 +++++++++++++++--------------
lxd/instance/instance_interface.go | 2 +-
4 files changed, 86 insertions(+), 83 deletions(-)
diff --git a/lxd/images.go b/lxd/images.go
index c5453a3ab2..61b4c79554 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -293,7 +293,8 @@ func imgPostInstanceInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *ope
}
// Export instance to writer.
- err = c.Export(writer, req.Properties)
+ var meta api.ImageMetadata
+ meta, err = c.Export(writer, req.Properties)
// Clean up file handles.
// When compression is used, Close on imageProgressWriter/tarWriter is required for compressFile/gzip to
@@ -337,7 +338,7 @@ func imgPostInstanceInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *ope
}
info.Architecture, _ = osarch.ArchitectureName(c.Architecture())
- info.Properties = req.Properties
+ info.Properties = meta.Properties
// Create the database entry
err = d.cluster.CreateImage(c.Project(), info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties, info.Type)
diff --git a/lxd/instance/drivers/driver_lxc.go b/lxd/instance/drivers/driver_lxc.go
index 256cc7573a..b5eac46db7 100644
--- a/lxd/instance/drivers/driver_lxc.go
+++ b/lxd/instance/drivers/driver_lxc.go
@@ -4546,7 +4546,7 @@ func (c *lxc) updateDevices(removeDevices deviceConfig.Devices, addDevices devic
}
// Export backs up the instance.
-func (c *lxc) Export(w io.Writer, properties map[string]string) error {
+func (c *lxc) Export(w io.Writer, properties map[string]string) (api.ImageMetadata, error) {
ctxMap := log.Ctx{
"project": c.project,
"name": c.name,
@@ -4554,8 +4554,10 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
"ephemeral": c.ephemeral,
"used": c.lastUsedDate}
+ meta := api.ImageMetadata{}
+
if c.IsRunning() {
- return fmt.Errorf("Cannot export a running instance as an image")
+ return meta, fmt.Errorf("Cannot export a running instance as an image")
}
logger.Info("Exporting instance", ctxMap)
@@ -4564,7 +4566,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
ourStart, err := c.mount()
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
if ourStart {
defer c.unmount()
@@ -4574,7 +4576,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
idmap, err := c.DiskIdmap()
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
// Create the tarball.
@@ -4607,7 +4609,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
defer os.RemoveAll(tempDir)
@@ -4619,7 +4621,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
arch, _ = osarch.ArchitectureName(parent.Architecture())
@@ -4631,12 +4633,11 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
arch, err = osarch.ArchitectureName(c.state.OS.Architectures[0])
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
// Fill in the metadata.
- meta := api.ImageMetadata{}
meta.Architecture = arch
meta.CreationDate = time.Now().UTC().Unix()
meta.Properties = properties
@@ -4645,7 +4646,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
// Write the actual file.
@@ -4654,14 +4655,14 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
fi, err := os.Lstat(fnam)
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
tmpOffset := len(path.Dir(fnam)) + 1
@@ -4669,41 +4670,41 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
tarWriter.Close()
logger.Debugf("Error writing to tarfile: %s", err)
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
} else {
- if properties != nil {
- // Parse the metadata.
- content, err := ioutil.ReadFile(fnam)
- if err != nil {
- tarWriter.Close()
- logger.Error("Failed exporting instance", ctxMap)
- return err
- }
+ // Parse the metadata.
+ content, err := ioutil.ReadFile(fnam)
+ if err != nil {
+ tarWriter.Close()
+ logger.Error("Failed exporting instance", ctxMap)
+ return meta, err
+ }
- metadata := new(api.ImageMetadata)
- err = yaml.Unmarshal(content, &metadata)
- if err != nil {
- tarWriter.Close()
- logger.Error("Failed exporting instance", ctxMap)
- return err
- }
- metadata.Properties = properties
+ err = yaml.Unmarshal(content, &meta)
+ if err != nil {
+ tarWriter.Close()
+ logger.Error("Failed exporting instance", ctxMap)
+ return meta, err
+ }
+
+ if properties != nil {
+ meta.Properties = properties
// Generate a new metadata.yaml.
tempDir, err := ioutil.TempDir("", "lxd_lxd_metadata_")
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
defer os.RemoveAll(tempDir)
- data, err := yaml.Marshal(&metadata)
+ data, err := yaml.Marshal(&meta)
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
// Write the actual file.
@@ -4712,7 +4713,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
@@ -4722,7 +4723,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
tarWriter.Close()
logger.Debugf("Error statting %s during export", fnam)
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
if properties != nil {
@@ -4735,7 +4736,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
tarWriter.Close()
logger.Debugf("Error writing to tarfile: %s", err)
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
@@ -4744,7 +4745,7 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
err = filepath.Walk(fnam, writeToTar)
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
// Include all the templates.
@@ -4753,18 +4754,18 @@ func (c *lxc) Export(w io.Writer, properties map[string]string) error {
err = filepath.Walk(fnam, writeToTar)
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
err = tarWriter.Close()
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
logger.Info("Exported instance", ctxMap)
- return nil
+ return meta, nil
}
func collectCRIULogFile(c instance.Instance, imagesDir string, function string, method string) error {
diff --git a/lxd/instance/drivers/driver_qemu.go b/lxd/instance/drivers/driver_qemu.go
index 31c4bec940..bf38aeefdd 100644
--- a/lxd/instance/drivers/driver_qemu.go
+++ b/lxd/instance/drivers/driver_qemu.go
@@ -3345,7 +3345,7 @@ func (vm *qemu) deviceRemove(deviceName string, rawConfig deviceConfig.Device) e
}
// Export publishes the instance.
-func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
+func (vm *qemu) Export(w io.Writer, properties map[string]string) (api.ImageMetadata, error) {
ctxMap := log.Ctx{
"project": vm.project,
"name": vm.name,
@@ -3353,8 +3353,10 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
"ephemeral": vm.ephemeral,
"used": vm.lastUsedDate}
+ meta := api.ImageMetadata{}
+
if vm.IsRunning() {
- return fmt.Errorf("Cannot export a running instance as an image")
+ return meta, fmt.Errorf("Cannot export a running instance as an image")
}
logger.Info("Exporting instance", ctxMap)
@@ -3363,7 +3365,7 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
ourStart, err := vm.mount()
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
if ourStart {
defer vm.unmount()
@@ -3398,7 +3400,7 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
defer os.RemoveAll(tempDir)
@@ -3410,7 +3412,7 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
arch, _ = osarch.ArchitectureName(parent.Architecture())
@@ -3422,12 +3424,11 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
arch, err = osarch.ArchitectureName(vm.state.OS.Architectures[0])
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
// Fill in the metadata.
- meta := api.ImageMetadata{}
meta.Architecture = arch
meta.CreationDate = time.Now().UTC().Unix()
meta.Properties = properties
@@ -3436,7 +3437,7 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
// Write the actual file.
@@ -3445,55 +3446,55 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
fi, err := os.Lstat(fnam)
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
tmpOffset := len(filepath.Dir(fnam)) + 1
if err := tarWriter.WriteFile(fnam[tmpOffset:], fnam, fi, false); err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
} else {
- if properties != nil {
- // Parse the metadata.
- content, err := ioutil.ReadFile(fnam)
- if err != nil {
- tarWriter.Close()
- logger.Error("Failed exporting instance", ctxMap)
- return err
- }
+ // Parse the metadata.
+ content, err := ioutil.ReadFile(fnam)
+ if err != nil {
+ tarWriter.Close()
+ logger.Error("Failed exporting instance", ctxMap)
+ return meta, err
+ }
- metadata := new(api.ImageMetadata)
- err = yaml.Unmarshal(content, &metadata)
- if err != nil {
- tarWriter.Close()
- logger.Error("Failed exporting instance", ctxMap)
- return err
- }
- metadata.Properties = properties
+ err = yaml.Unmarshal(content, &meta)
+ if err != nil {
+ tarWriter.Close()
+ logger.Error("Failed exporting instance", ctxMap)
+ return meta, err
+ }
+
+ if properties != nil {
+ meta.Properties = properties
// Generate a new metadata.yaml.
tempDir, err := ioutil.TempDir("", "lxd_lxd_metadata_")
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
defer os.RemoveAll(tempDir)
- data, err := yaml.Marshal(&metadata)
+ data, err := yaml.Marshal(&meta)
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
// Write the actual file.
@@ -3502,7 +3503,7 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
if err != nil {
tarWriter.Close()
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
@@ -3512,7 +3513,7 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
tarWriter.Close()
logger.Debugf("Error statting %s during export", fnam)
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
if properties != nil {
@@ -3525,43 +3526,43 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
tarWriter.Close()
logger.Debugf("Error writing to tarfile: %s", err)
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
// Convert and include the root image.
pool, err := vm.getStoragePool()
if err != nil {
- return err
+ return meta, err
}
rootDrivePath, err := pool.GetInstanceDisk(vm)
if err != nil {
- return err
+ return meta, err
}
// Convert from raw to qcow2 and add to tarball.
tmpPath, err := ioutil.TempDir(shared.VarPath("images"), "lxd_export_")
if err != nil {
- return err
+ return meta, err
}
defer os.RemoveAll(tmpPath)
fPath := fmt.Sprintf("%s/rootfs.img", tmpPath)
_, err = shared.RunCommand("qemu-img", "convert", "-c", "-O", "qcow2", rootDrivePath, fPath)
if err != nil {
- return fmt.Errorf("Failed converting image to qcow2: %v", err)
+ return meta, fmt.Errorf("Failed converting image to qcow2: %v", err)
}
fi, err := os.Lstat(fPath)
if err != nil {
- return err
+ return meta, err
}
imgOffset := len(tmpPath) + 1
err = tarWriter.WriteFile(fPath[imgOffset:], fPath, fi, false)
if err != nil {
- return err
+ return meta, err
}
// Include all the templates.
@@ -3570,18 +3571,18 @@ func (vm *qemu) Export(w io.Writer, properties map[string]string) error {
err = filepath.Walk(fnam, writeToTar)
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
}
err = tarWriter.Close()
if err != nil {
logger.Error("Failed exporting instance", ctxMap)
- return err
+ return meta, err
}
logger.Info("Exported instance", ctxMap)
- return nil
+ return meta, nil
}
// Migrate migrates the instance to another node.
diff --git a/lxd/instance/instance_interface.go b/lxd/instance/instance_interface.go
index efad8bea9b..cf2d316c32 100644
--- a/lxd/instance/instance_interface.go
+++ b/lxd/instance/instance_interface.go
@@ -66,7 +66,7 @@ type Instance interface {
Update(newConfig db.InstanceArgs, userRequested bool) error
Delete() error
- Export(w io.Writer, properties map[string]string) error
+ Export(w io.Writer, properties map[string]string) (api.ImageMetadata, error)
// Live configuration.
CGroupSet(key string, value string) error
More information about the lxc-devel
mailing list