[lxc-devel] [lxd/master] Add squashfs support

stgraber on Github lxc-bot at linuxcontainers.org
Wed Jun 22 23:50:46 UTC 2016


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 468 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20160622/d1842107/attachment.bin>
-------------- next part --------------
From 719da1be34c2617af5e8cc305a0eecad9b25fbf8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?St=C3=A9phane=20Graber?= <stgraber at ubuntu.com>
Date: Wed, 22 Jun 2016 19:49:28 -0400
Subject: [PATCH] Add squashfs support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This is now needed for Ubuntu 16.10 images.

Has been tested both directly on a host and inside a container.

Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>
---
 lxd/images.go           | 41 ++++++++++++++++++++++++++---------------
 lxd/main.go             |  2 +-
 lxd/storage_btrfs.go    |  2 +-
 lxd/storage_dir.go      |  2 +-
 lxd/storage_lvm.go      | 12 ++++++------
 lxd/storage_zfs.go      |  2 +-
 shared/simplestreams.go | 41 +++++++++++++++++++++++++++++------------
 7 files changed, 65 insertions(+), 37 deletions(-)

diff --git a/lxd/images.go b/lxd/images.go
index 0c87c7a..916b86a 100644
--- a/lxd/images.go
+++ b/lxd/images.go
@@ -66,30 +66,41 @@ func detectCompression(fname string) ([]string, string, error) {
 		return []string{"--lzma", "-xf"}, ".tar.lzma", nil
 	case bytes.Equal(header[257:262], []byte{'u', 's', 't', 'a', 'r'}):
 		return []string{"-xf"}, ".tar", nil
+	case bytes.Equal(header[0:4], []byte{'h', 's', 'q', 's'}):
+		return []string{""}, ".squashfs", nil
 	default:
 		return []string{""}, "", fmt.Errorf("Unsupported compression.")
 	}
 
 }
 
-func untar(tarball string, path string) error {
-	extractArgs, _, err := detectCompression(tarball)
+func unpack(file string, path string) error {
+	extractArgs, extension, err := detectCompression(file)
 	if err != nil {
 		return err
 	}
 
-	command := "tar"
+	command := ""
 	args := []string{}
-	if runningInUserns {
-		args = append(args, "--wildcards")
-		args = append(args, "--exclude=dev/*")
-		args = append(args, "--exclude=./dev/*")
-		args = append(args, "--exclude=rootfs/dev/*")
-		args = append(args, "--exclude=rootfs/./dev/*")
+	if strings.HasPrefix(extension, ".tar") {
+		command = "tar"
+		if runningInUserns {
+			args = append(args, "--wildcards")
+			args = append(args, "--exclude=dev/*")
+			args = append(args, "--exclude=./dev/*")
+			args = append(args, "--exclude=rootfs/dev/*")
+			args = append(args, "--exclude=rootfs/./dev/*")
+		}
+		args = append(args, "-C", path, "--numeric-owner")
+		args = append(args, extractArgs...)
+		args = append(args, file)
+	} else if strings.HasPrefix(extension, ".squashfs") {
+		command = "unsquashfs"
+		args = append(args, "-f", "-d", path, "-n")
+		args = append(args, file)
+	} else {
+		return fmt.Errorf("Unsupported image format: %s", extension)
 	}
-	args = append(args, "-C", path, "--numeric-owner")
-	args = append(args, extractArgs...)
-	args = append(args, tarball)
 
 	output, err := exec.Command(command, args...).CombinedOutput()
 	if err != nil {
@@ -101,8 +112,8 @@ func untar(tarball string, path string) error {
 	return nil
 }
 
-func untarImage(imagefname string, destpath string) error {
-	err := untar(imagefname, destpath)
+func unpackImage(imagefname string, destpath string) error {
+	err := unpack(imagefname, destpath)
 	if err != nil {
 		return err
 	}
@@ -114,7 +125,7 @@ func untarImage(imagefname string, destpath string) error {
 			return fmt.Errorf("Error creating rootfs directory")
 		}
 
-		err = untar(imagefname+".rootfs", rootfsPath)
+		err = unpack(imagefname+".rootfs", rootfsPath)
 		if err != nil {
 			return err
 		}
diff --git a/lxd/main.go b/lxd/main.go
index 99d10b4..ec20ed2 100644
--- a/lxd/main.go
+++ b/lxd/main.go
@@ -333,7 +333,7 @@ func cmdDaemon() error {
 		go memProfiler(*argMemProfile)
 	}
 
-	neededPrograms := []string{"setfacl", "rsync", "tar", "xz"}
+	neededPrograms := []string{"setfacl", "rsync", "tar", "unsquashfs", "xz"}
 	for _, p := range neededPrograms {
 		_, err := exec.LookPath(p)
 		if err != nil {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index f1b6a7d..79b1aa0 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -413,7 +413,7 @@ func (s *storageBtrfs) ImageCreate(fingerprint string) error {
 		return err
 	}
 
-	if err := untarImage(imagePath, subvol); err != nil {
+	if err := unpackImage(imagePath, subvol); err != nil {
 		s.subvolDelete(subvol)
 		return err
 	}
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 7d082c6..bd9cee9 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -60,7 +60,7 @@ func (s *storageDir) ContainerCreateFromImage(
 	}
 
 	imagePath := shared.VarPath("images", imageFingerprint)
-	if err := untarImage(imagePath, container.Path()); err != nil {
+	if err := unpackImage(imagePath, container.Path()); err != nil {
 		s.ContainerDelete(container)
 		return err
 	}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index 88d4f76..2799032 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -732,28 +732,28 @@ func (s *storageLvm) ImageCreate(fingerprint string) error {
 	fstype := daemonConfig["storage.lvm_fstype"].Get()
 	err = tryMount(lvpath, tempLVMountPoint, fstype, 0, "discard")
 	if err != nil {
-		shared.Logf("Error mounting image LV for untarring: %v", err)
+		shared.Logf("Error mounting image LV for unpacking: %v", err)
 		return fmt.Errorf("Error mounting image LV: %v", err)
 	}
 
-	untarErr := untarImage(finalName, tempLVMountPoint)
+	unpackErr := unpackImage(finalName, tempLVMountPoint)
 
 	err = tryUnmount(tempLVMountPoint, 0)
 	if err != nil {
 		s.log.Warn("could not unmount LV. Will not remove",
 			log.Ctx{"lvpath": lvpath, "mountpoint": tempLVMountPoint, "err": err})
-		if untarErr == nil {
+		if unpackErr == nil {
 			return err
 		}
 
 		return fmt.Errorf(
 			"Error unmounting '%s' during cleanup of error %v",
-			tempLVMountPoint, untarErr)
+			tempLVMountPoint, unpackErr)
 	}
 
-	if untarErr != nil {
+	if unpackErr != nil {
 		s.removeLV(fingerprint)
-		return untarErr
+		return unpackErr
 	}
 
 	return nil
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index c461f1d..9290dca 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -625,7 +625,7 @@ func (s *storageZfs) ImageCreate(fingerprint string) error {
 		return err
 	}
 
-	err = untarImage(imagePath, subvol)
+	err = unpackImage(imagePath, subvol)
 	if err != nil {
 		s.zfsDestroy(fs)
 		return err
diff --git a/shared/simplestreams.go b/shared/simplestreams.go
index 9db9994..3aa8f61 100644
--- a/shared/simplestreams.go
+++ b/shared/simplestreams.go
@@ -115,14 +115,22 @@ func (s *SimpleStreamsManifest) ToLXD() ([]ImageInfo, map[string][][]string) {
 			found := 0
 			for _, item := range version.Items {
 				// Skip the files we don't care about
-				if !StringInSlice(item.FileType, []string{"root.tar.xz", "lxd.tar.xz"}) {
+				if !StringInSlice(item.FileType, []string{"root.tar.xz", "lxd.tar.xz", "squashfs"}) {
 					continue
 				}
 				found += 1
 
 				size += item.Size
-				if item.LXDHashSha256 != "" {
-					fingerprint = item.LXDHashSha256
+				if fingerprint == "" {
+					if item.LXDHashSha256SquashFs != "" {
+						fingerprint = item.LXDHashSha256SquashFs
+					}
+					if item.LXDHashSha256RootXz != "" {
+						fingerprint = item.LXDHashSha256RootXz
+					}
+					if item.LXDHashSha256 != "" {
+						fingerprint = item.LXDHashSha256
+					}
 				}
 
 				if item.FileType == "lxd.tar.xz" {
@@ -132,9 +140,16 @@ func (s *SimpleStreamsManifest) ToLXD() ([]ImageInfo, map[string][][]string) {
 					metaHash = item.HashSha256
 				}
 
-				if item.FileType == "root.tar.xz" {
-					rootfsPath = item.Path
-					rootfsHash = item.HashSha256
+				if rootfsPath == "" || rootfsHash == "" {
+					if item.FileType == "squashfs" {
+						rootfsPath = item.Path
+						rootfsHash = item.HashSha256
+					}
+
+					if item.FileType == "root.tar.xz" {
+						rootfsPath = item.Path
+						rootfsHash = item.HashSha256
+					}
 				}
 			}
 
@@ -199,12 +214,14 @@ type SimpleStreamsManifestProductVersion struct {
 }
 
 type SimpleStreamsManifestProductVersionItem struct {
-	Path          string `json:"path"`
-	FileType      string `json:"ftype"`
-	HashMd5       string `json:"md5"`
-	HashSha256    string `json:"sha256"`
-	LXDHashSha256 string `json:"combined_sha256"`
-	Size          int64  `json:"size"`
+	Path                  string `json:"path"`
+	FileType              string `json:"ftype"`
+	HashMd5               string `json:"md5"`
+	HashSha256            string `json:"sha256"`
+	LXDHashSha256         string `json:"combined_sha256"`
+	LXDHashSha256RootXz   string `json:"combined_rootxz_sha256"`
+	LXDHashSha256SquashFs string `json:"combined_squashfs_sha256"`
+	Size                  int64  `json:"size"`
 }
 
 type SimpleStreamsIndex struct {


More information about the lxc-devel mailing list