[lxc-devel] [lxd/master] lxc/image: pack image on import if a directory is provided

albertodonato on Github lxc-bot at linuxcontainers.org
Tue Jul 11 17:29:19 UTC 2017


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/20170711/8f526825/attachment.bin>
-------------- next part --------------
From 8e45ccd2712f06d9576d390c4e1911c19ed2fd9a Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Tue, 11 Jul 2017 15:44:33 +0200
Subject: [PATCH] lxc/image: pack image on import if a directory is provided

Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
 lxc/image.go         | 38 ++++++++++++++++++++++++++++++++++++--
 test/suites/image.sh | 19 +++++++++++++++++++
 2 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/lxc/image.go b/lxc/image.go
index 265c8c73f..191932a05 100644
--- a/lxc/image.go
+++ b/lxc/image.go
@@ -89,8 +89,9 @@ Images can be referenced by their full hash, shortest unique partial
 hash or alias name (if one is set).
 
 
-lxc image import <tarball> [<rootfs tarball>|<URL>] [<remote>:] [--public] [--created-at=ISO-8601] [--expires-at=ISO-8601] [--fingerprint=FINGERPRINT] [--alias=ALIAS...] [prop=value]
-    Import an image tarball (or tarballs) into the LXD image store.
+lxc image import <tarball>|<dir> [<rootfs tarball>|<URL>] [<remote>:] [--public] [--created-at=ISO-8601] [--expires-at=ISO-8601] [--fingerprint=FINGERPRINT] [--alias=ALIAS...] [prop=value]
+    Import an image tarball (or tarballs) or an image directory into the LXD image store.
+    Directory import is only available on Linux and must be performed as root.
 
 lxc image copy [<remote>:]<image> <remote>: [--alias=ALIAS...] [--copy-aliases] [--public] [--auto-update]
     Copy an image from one LXD daemon to another over the network.
@@ -669,6 +670,15 @@ func (c *imageCmd) run(conf *config.Config, args []string) error {
 			var rootfs io.ReadCloser
 
 			// Open meta
+			if shared.IsDir(imageFile) {
+				imageFile, err = packImageDir(imageFile)
+				if err != nil {
+					return err
+				}
+				// remove temp file
+				defer os.Remove(imageFile)
+
+			}
 			meta, err = os.Open(imageFile)
 			if err != nil {
 				return err
@@ -1198,3 +1208,27 @@ func (c *imageCmd) aliasShouldShow(filters []string, state *api.ImageAliasesEntr
 
 	return false
 }
+
+// Package the image from the specified directory, if running as root.  Return
+// the image filename
+func packImageDir(path string) (string, error) {
+	switch os.Geteuid() {
+	case 0:
+		break
+	case -1:
+		return "", fmt.Errorf(
+			i18n.G("Directory import is not available on this platform"))
+	default:
+		return "", fmt.Errorf(i18n.G("Must run as root to import from directory"))
+	}
+
+	outFile, err := ioutil.TempFile("", "lxd_image_")
+	if err != nil {
+		return "", err
+	}
+	defer outFile.Close()
+	outFileName := outFile.Name()
+
+	shared.RunCommand("tar", "-C", path, "--numeric-owner", "-cJf", outFileName, "rootfs", "templates", "metadata.yaml")
+	return outFileName, nil
+}
diff --git a/test/suites/image.sh b/test/suites/image.sh
index 7b5c19101..89007d4f3 100644
--- a/test/suites/image.sh
+++ b/test/suites/image.sh
@@ -50,3 +50,22 @@ test_image_list_all_aliases() {
     lxc image list -c L | grep -q zzz
 
 }
+
+test_image_import_dir() {
+    ensure_import_testimage
+    lxc image export testimage
+    # shellcheck disable=2039,2034,2155
+    local image=$(ls -1 -- *.tar.xz)
+    mkdir -p unpacked
+    tar -C unpacked -xf "$image"
+    # shellcheck disable=2039,2034,2155
+    local fingerprint=$(lxc image import unpacked | awk '{print $NF;}')
+    rm -rf "$image" unpacked
+
+    lxc image export "$fingerprint"
+    # shellcheck disable=2039,2034,2155
+    local exported="${fingerprint}.tar.xz"
+
+    tar tvf "$exported" | fgrep -q metadata.yaml
+    rm "$exported"
+}


More information about the lxc-devel mailing list