[lxc-devel] [lxd/master] images: add nopersist create image mode

joelhockey on Github lxc-bot at linuxcontainers.org
Mon Feb 11 01:28:22 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 581 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190210/2cae5b1f/attachment.bin>
-------------- next part --------------
From 4a304dc62310143d95cffcb6691712ed1b7e8a73 Mon Sep 17 00:00:00 2001
From: Joel Hockey <joelhockey at chromium.org>
Date: Sun, 10 Feb 2019 16:43:28 -0800
Subject: [PATCH] images: add nopersist create image mode

New api.ImagesPostSource.Mode value 'nopersist'
allows image to be created from a container
without persisting the image to lxd db or any
intermediate storage.

The image is written directly to
api.ImagesPost.Filename.

Signed-off-by: Joel Hockey <joelhockey at chromium.org>
---
 lxd/images.go | 29 ++++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git a/lxd/images.go b/lxd/images.go
index 062c04ca59..7d48eaa259 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -180,17 +180,28 @@ func imgPostContInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *operati
 		info.Public = false
 	}
 
+	// In 'nopersist' mode, stream container to req.Filename and do not write to db
+	noPersist := req.Source.Mode == "nopersist"
+
 	c, err := containerLoadByProjectAndName(d.State(), project, name)
 	if err != nil {
 		return nil, err
 	}
 
 	// Build the actual image file
-	imageFile, err := ioutil.TempFile(builddir, "lxd_build_image_")
-	if err != nil {
-		return nil, err
+	var imageFile *os.File
+	if noPersist {
+		imageFile, err = os.Create(req.Filename)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		imageFile, err = ioutil.TempFile(builddir, "lxd_build_image_")
+		if err != nil {
+			return nil, err
+		}
+		defer os.Remove(imageFile.Name())
 	}
-	defer os.Remove(imageFile.Name())
 
 	// Calculate (close estimate of) total size of input to image
 	totalSize := int64(0)
@@ -269,6 +280,13 @@ func imgPostContInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *operati
 	}
 	info.Size = fi.Size()
 	info.Fingerprint = fmt.Sprintf("%x", sha256.Sum(nil))
+	info.Architecture, _ = osarch.ArchitectureName(c.Architecture())
+	info.Properties = req.Properties
+
+	// In 'nopersist' mode, image has been written to req.Filename, and we are done
+	if noPersist {
+		return &info, nil
+	}
 
 	_, _, err = d.cluster.ImageGet(project, info.Fingerprint, false, true)
 	if err != db.ErrNoSuchObject {
@@ -286,9 +304,6 @@ func imgPostContInfo(d *Daemon, r *http.Request, req api.ImagesPost, op *operati
 		return nil, err
 	}
 
-	info.Architecture, _ = osarch.ArchitectureName(c.Architecture())
-	info.Properties = req.Properties
-
 	// Create the database entry
 	err = d.cluster.ImageInsert(c.Project(), info.Fingerprint, info.Filename, info.Size, info.Public, info.AutoUpdate, info.Architecture, info.CreatedAt, info.ExpiresAt, info.Properties)
 	if err != nil {


More information about the lxc-devel mailing list