The following pull request was submitted through Github. It can be accessed and reviewed at: https://github.com/lxc/distrobuilder/pull/267
This e-mail was sent by the LXC bot, direct replies will not reach the author unless they happen to be subscribed to this list. === Description (from pull-request) ===
From 42cc5df8b5b4f51559d236daa5e6a8caca82e646 Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Tue, 29 Oct 2019 13:38:12 +0100 Subject: [PATCH 1/3] shared: Export ChrootMount struct This exports the ChrootMount struct. Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- shared/chroot.go | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/shared/chroot.go b/shared/chroot.go index eefdeab..a6ad591 100644 --- a/shared/chroot.go +++ b/shared/chroot.go @@ -12,19 +12,20 @@ import ( lxd "github.com/lxc/lxd/shared" ) -type chrootMount struct { - source string - target string - fstype string - flags uintptr - data string - isDir bool +// ChrootMount defines mount args. +type ChrootMount struct { + Source string + Target string + FSType string + Flags uintptr + Data string + IsDir bool } // ActiveChroots is a map of all active chroots and their exit functions var ActiveChroots = make(map[string]func() error) -func setupMounts(rootfs string, mounts []chrootMount) error { +func setupMounts(rootfs string, mounts []ChrootMount) error { // Create a temporary mount path err := os.MkdirAll(filepath.Join(rootfs, ".distrobuilder"), 0700) if err != nil { @@ -36,7 +37,7 @@ func setupMounts(rootfs string, mounts []chrootMount) error { tmpTarget := filepath.Join(rootfs, ".distrobuilder", fmt.Sprintf("%d", i)) // Create the target mountpoint - if mount.isDir { + if mount.IsDir { err := os.MkdirAll(tmpTarget, 0755) if err != nil { return err @@ -49,22 +50,22 @@ func setupMounts(rootfs string, mounts []chrootMount) error { } // Mount to the temporary path - err := syscall.Mount(mount.source, tmpTarget, mount.fstype, mount.flags, mount.data) + err := syscall.Mount(mount.Source, tmpTarget, mount.FSType, mount.Flags, mount.Data) if err != nil { - return fmt.Errorf("Failed to mount '%s': %s", mount.source, err) + return fmt.Errorf("Failed to mount '%s': %s", mount.Source, err) } } return nil } -func moveMounts(mounts []chrootMount) error { +func moveMounts(mounts []ChrootMount) error { for i, mount := range mounts { // Source path tmpSource := filepath.Join("/", ".distrobuilder", fmt.Sprintf("%d", i)) // Resolve symlinks - target := mount.target + target := mount.Target for { // Get information on current target fi, err := os.Lstat(target) @@ -93,7 +94,7 @@ func moveMounts(mounts []chrootMount) error { } // Create target path - if mount.isDir { + if mount.IsDir { err = os.MkdirAll(target, 0755) if err != nil { return err @@ -108,7 +109,7 @@ func moveMounts(mounts []chrootMount) error { // Move the mount to its destination err = syscall.Mount(tmpSource, target, "", syscall.MS_MOVE, "") if err != nil { - return fmt.Errorf("Failed to mount '%s': %s", mount.source, err) + return fmt.Errorf("Failed to mount '%s': %s", mount.Source, err) } } @@ -159,7 +160,7 @@ func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { } // Setup all other needed mounts - mounts := []chrootMount{ + mounts := []ChrootMount{ {"none", "/proc", "proc", 0, "", true}, {"none", "/sys", "sysfs", 0, "", true}, {"/dev", "/dev", "", syscall.MS_BIND, "", true}, From 8378262caeaaaf8cd9dc285efda1fffab5fd2aac Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Tue, 29 Oct 2019 15:07:57 +0100 Subject: [PATCH 2/3] *: Pass custom mounts to SetupChroot() This allows additional mounts to be passed to SetupChroot() Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- distrobuilder/main_lxc.go | 2 +- distrobuilder/main_lxd.go | 2 +- shared/chroot.go | 10 +++++++--- sources/alpine-http.go | 2 +- sources/centos-http.go | 4 ++-- sources/oraclelinux-http.go | 2 +- sources/ubuntu-http.go | 2 +- 7 files changed, 14 insertions(+), 10 deletions(-) diff --git a/distrobuilder/main_lxc.go b/distrobuilder/main_lxc.go index 0b8fb77..9ce050e 100644 --- a/distrobuilder/main_lxc.go +++ b/distrobuilder/main_lxc.go @@ -60,7 +60,7 @@ func (c *cmdLXC) run(cmd *cobra.Command, args []string) error { } exitChroot, err := shared.SetupChroot(c.global.sourceDir, - c.global.definition.Environment) + c.global.definition.Environment, nil) if err != nil { return err } diff --git a/distrobuilder/main_lxd.go b/distrobuilder/main_lxd.go index 9aea6dc..73596bb 100644 --- a/distrobuilder/main_lxd.go +++ b/distrobuilder/main_lxd.go @@ -85,7 +85,7 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string) error { } exitChroot, err := shared.SetupChroot(c.global.sourceDir, - c.global.definition.Environment) + c.global.definition.Environment, nil) if err != nil { return err } diff --git a/shared/chroot.go b/shared/chroot.go index a6ad591..1c652b3 100644 --- a/shared/chroot.go +++ b/shared/chroot.go @@ -152,7 +152,7 @@ func killChrootProcesses(rootfs string) error { } // SetupChroot sets up mount and files, a reverter and then chroots for you -func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { +func SetupChroot(rootfs string, envs DefinitionEnv, m []ChrootMount) (func() error, error) { // Mount the rootfs err := syscall.Mount(rootfs, rootfs, "", syscall.MS_BIND, "") if err != nil { @@ -181,7 +181,11 @@ func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { } // Setup all needed mounts in a temporary location - err = setupMounts(rootfs, mounts) + if m != nil && len(m) > 0 { + err = setupMounts(rootfs, append(mounts, m...)) + } else { + err = setupMounts(rootfs, mounts) + } if err != nil { return nil, fmt.Errorf("Failed to mount filesystems: %v", err) } @@ -199,7 +203,7 @@ func SetupChroot(rootfs string, envs DefinitionEnv) (func() error, error) { } // Move all the mounts into place - err = moveMounts(mounts) + err = moveMounts(append(mounts, m...)) if err != nil { return nil, err } diff --git a/sources/alpine-http.go b/sources/alpine-http.go index b32ea1d..1429459 100644 --- a/sources/alpine-http.go +++ b/sources/alpine-http.go @@ -98,7 +98,7 @@ func (s *AlpineLinuxHTTP) Run(definition shared.Definition, rootfsDir string) er // Handle edge builds if definition.Image.Release == "edge" { // Upgrade to edge - exitChroot, err := shared.SetupChroot(rootfsDir, definition.Environment) + exitChroot, err := shared.SetupChroot(rootfsDir, definition.Environment, nil) if err != nil { return err } diff --git a/sources/centos-http.go b/sources/centos-http.go index ea533b7..a16bb38 100644 --- a/sources/centos-http.go +++ b/sources/centos-http.go @@ -158,7 +158,7 @@ func (s CentOSHTTP) unpackRaw(filePath, rootfsDir string) error { } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } @@ -285,7 +285,7 @@ func (s CentOSHTTP) unpackISO(filePath, rootfsDir string) error { } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } diff --git a/sources/oraclelinux-http.go b/sources/oraclelinux-http.go index 4906455..6d21904 100644 --- a/sources/oraclelinux-http.go +++ b/sources/oraclelinux-http.go @@ -169,7 +169,7 @@ func (s *OracleLinuxHTTP) unpackISO(latestUpdate, filePath, rootfsDir string) er } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(tempRootDir, shared.DefinitionEnv{}, nil) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } diff --git a/sources/ubuntu-http.go b/sources/ubuntu-http.go index b82042a..c7ca68c 100644 --- a/sources/ubuntu-http.go +++ b/sources/ubuntu-http.go @@ -150,7 +150,7 @@ func (s *UbuntuHTTP) runCoreVariant(definition shared.Definition, rootfsDir stri return err } - exitChroot, err := shared.SetupChroot(baseImageDir, shared.DefinitionEnv{}) + exitChroot, err := shared.SetupChroot(baseImageDir, shared.DefinitionEnv{}, nil) if err != nil { return err } From bdbdceea0963464e7d958a9389782ea01bb4af65 Mon Sep 17 00:00:00 2001 From: Thomas Hipp <thomas.h...@canonical.com> Date: Tue, 29 Oct 2019 09:12:53 +0100 Subject: [PATCH 3/3] distrobuilder: Add VM support This adds VM support. Signed-off-by: Thomas Hipp <thomas.h...@canonical.com> --- distrobuilder/main.go | 79 ++++++++++++++- distrobuilder/main_lxd.go | 4 +- distrobuilder/scripts.go | 199 ++++++++++++++++++++++++++++++++++++++ image/lxd.go | 45 ++++++--- image/lxd_test.go | 6 +- 5 files changed, 313 insertions(+), 20 deletions(-) create mode 100644 distrobuilder/scripts.go diff --git a/distrobuilder/main.go b/distrobuilder/main.go index 043d656..b1d0508 100644 --- a/distrobuilder/main.go +++ b/distrobuilder/main.go @@ -64,6 +64,7 @@ import ( "strings" "time" + lxd "github.com/lxc/lxd/shared" "github.com/spf13/cobra" "gopkg.in/yaml.v2" @@ -203,7 +204,6 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error { return err } } - if cmd.CalledAs() == "build-dir" { c.sourceDir = c.targetDir } else { @@ -230,6 +230,75 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error { } } + var mounts []shared.ChrootMount + + isVM, err := cmd.Flags().GetBool("vm") + if err != nil { + return err + } + + if isVM { + imgFile, err := shared.RenderTemplate(fmt.Sprintf("%s.img", c.definition.Image.Name), c.definition) + if err != nil { + return err + } + + err = shared.RunScript(fmt.Sprintf(preVM, imgFile, c.sourceDir, c.flagCacheDir)) + if err != nil { + return err + } + defer lxd.RunCommand("umount", "-R", c.sourceDir) + + } + + env := c.definition.Environment + envFile := filepath.Join(c.flagCacheDir, "env") + var loopDev string + + if lxd.PathExists(envFile) { + f, err := os.Open(envFile) + if err != nil { + return err + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + fields := strings.SplitN(scanner.Text(), "=", 2) + + if len(fields) < 2 { + continue + } + + // Remember this one as we need to clean up the loop device later. + if fields[0] == "DISTROBUILDER_LOOP_DEVICE" { + loopDev = fields[1] + } + + env.EnvVariables = append(env.EnvVariables, shared.DefinitionEnvVars{ + Key: fields[0], + Value: fields[1], + }) + } + } + + // Clean up loop device. + if loopDev != "" { + defer shared.RunCommand("kpartx", "-d", loopDev) + + uefiDev := fmt.Sprintf("/dev/mapper/%sp15", strings.TrimPrefix(loopDev, "/dev/")) + mounts = []shared.ChrootMount{ + { + Source: uefiDev, + Target: "/boot/efi", + FSType: "vfat", + Flags: 0, + Data: "", + IsDir: true, + }, + } + } + // Get the downloader to use for this image downloader := sources.Get(c.definition.Source.Downloader) if downloader == nil { @@ -251,7 +320,7 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error { } // Setup the mounts and chroot into the rootfs - exitChroot, err := shared.SetupChroot(c.sourceDir, c.definition.Environment) + exitChroot, err := shared.SetupChroot(c.sourceDir, env, mounts) if err != nil { return fmt.Errorf("Failed to setup chroot: %s", err) } @@ -296,6 +365,12 @@ func (c *cmdGlobal) preRunBuild(cmd *cobra.Command, args []string) error { } } + // Run the post VM script which writes /etc/fstab, and runs grub-install. + err = shared.RunScript(postVM) + if err != nil { + return err + } + return nil } diff --git a/distrobuilder/main_lxd.go b/distrobuilder/main_lxd.go index 73596bb..8061a26 100644 --- a/distrobuilder/main_lxd.go +++ b/distrobuilder/main_lxd.go @@ -19,6 +19,7 @@ type cmdLXD struct { flagType string flagCompression string + flagVM bool } func (c *cmdLXD) commandBuild() *cobra.Command { @@ -38,6 +39,7 @@ func (c *cmdLXD) commandBuild() *cobra.Command { c.cmdBuild.Flags().StringVar(&c.flagType, "type", "split", "Type of tarball to create"+"``") c.cmdBuild.Flags().StringVar(&c.flagCompression, "compression", "xz", "Type of compression to use"+"``") + c.cmdBuild.Flags().BoolVar(&c.flagVM, "vm", false, "Create a qcow2 image for VMs"+"``") return c.cmdBuild } @@ -101,7 +103,7 @@ func (c *cmdLXD) run(cmd *cobra.Command, args []string) error { exitChroot() - err = img.Build(c.flagType == "unified", c.flagCompression) + err = img.Build(c.flagType == "unified", c.flagCompression, c.flagVM) if err != nil { return fmt.Errorf("Failed to create LXD image: %s", err) } diff --git a/distrobuilder/scripts.go b/distrobuilder/scripts.go new file mode 100644 index 0000000..d50c325 --- /dev/null +++ b/distrobuilder/scripts.go @@ -0,0 +1,199 @@ +package main + +var preVM = ` +#!/bin/sh +set -eux + +# default imagesize = 2252*1024**2 = 2.2G (the current size we ship) +IMAGESIZE=2361393152 +DISK_IMAGE="%s" +MOUNTPOINT="%s" +CACHEDIR=%s +FS_LABEL=rootfs +ROOTFS_DEV_MAPPER= +LOOP_DEVICE= + +create_empty_disk_image() { + # Prepare an empty disk image + dd if=/dev/zero of="$1" bs=1 count=0 seek="${IMAGESIZE}" +} + +create_partitions() { + disk_image="$1" + sgdisk "${disk_image}" --zap-all + sgdisk "${disk_image}" \ + --new=14::+4M \ + --new=15::+106M \ + --new=1:: + sgdisk "${disk_image}" \ + -t 14:ef02 \ + -t 15:ef00 + sgdisk "${disk_image}" \ + --print +} + +mount_image() { + #trap clean_loops EXIT + backing_img="$1" + local rootpart="$2" + kpartx_mapping="$(kpartx -s -v -a ${backing_img})" + + # Find the loop device + loop_p1="$(echo ${kpartx_mapping} | awk '{print$3}')" + LOOP_DEVICE="/dev/${loop_p1%%p[0-9]*}" + if [ ! -b ${LOOP_DEVICE} ]; then + echo "unable to find loop device for ${backing_img}" + exit 1 + fi + + # Find the rootfs location + ROOTFS_DEV_MAPPER="/dev/mapper/${loop_p1%%%%[0-9]}${rootpart}" + if [ ! -b "${ROOTFS_DEV_MAPPER}" ]; then + echo "${ROOTFS_DEV_MAPPER} is not a block device"; + exit 1 + fi + + # Add some information to the debug logs + echo "Mounted disk image ${backing_img} to ${ROOTFS_DEV_MAPPER}" + blkid ${ROOTFS_DEV_MAPPER} + + return 0 +} + +make_ext4_partition() { + device="$1" + label=${FS_LABEL:+-L "${FS_LABEL}"} + mkfs.ext4 -F -b 4096 -i 8192 -m 0 ${label} -E resize=536870912 "$device" +} + +create_and_mount_uefi_partition() { + uefi_dev="/dev/mapper/${LOOP_DEVICE#/dev/}p15" + mountpoint="$1" + mkfs.vfat -F 32 -n UEFI "${uefi_dev}" + + mkdir -p "${mountpoint}"/boot/efi + mount "${uefi_dev}" "$mountpoint"/boot/efi +} + +if [ -f "${DISK_IMAGE}" ]; then + rm "${DISK_IMAGE}" +fi + +create_empty_disk_image "${DISK_IMAGE}" +create_partitions "${DISK_IMAGE}" +mount_image "${DISK_IMAGE}" 1 + +PARTUUID=$(blkid -s PARTUUID -o value "$ROOTFS_DEV_MAPPER") + +make_ext4_partition "${ROOTFS_DEV_MAPPER}" +mount "${ROOTFS_DEV_MAPPER}" "${MOUNTPOINT}" +create_and_mount_uefi_partition ${MOUNTPOINT} + +# write useful env variables to cache file which will then be passed +# to the actions +echo DISTROBUILDER_FS_LABEL="${FS_LABEL}" >> "${CACHEDIR}"/env +echo DISTROBUILDER_PARTUUID="${PARTUUID}" >> "${CACHEDIR}"/env +echo DISTROBUILDER_LOOP_DEVICE="${LOOP_DEVICE}" >> "${CACHEDIR}"/env +` + +var postVM = ` +#!/bin/sh +set -eux + +fs_label="${DISTROBUILDER_FS_LABEL}" +partuuid="${DISTROBUILDER_PARTUUID}" +loop_device="${DISTROBUILDER_LOOP_DEVICE}" + +if [ -z "${fs_label}" ]; then + echo "Missing fs_label" >&2 + exit 1 +elif [ -z "${partuuid}" ]; then + echo "Missing partuuid" >&2 + exit 1 +elif [ -z "${loop_device}" ]; then + echo "Missing loop_device" >&2 + exit 1 +fi + +divert_grub() { + # Don't divert all of grub-probe here; just the scripts we don't want + # running. Otherwise, you may be missing part-uuids for the search + # command, for example. ~cyphermox + + dpkg-divert --local \ + --divert /etc/grub.d/30_os-prober.dpkg-divert \ + --rename /etc/grub.d/30_os-prober + + # Divert systemd-detect-virt; /etc/kernel/postinst.d/zz-update-grub + # no-ops if we are in a container, and the launchpad farm runs builds + # in lxd. We therefore pretend that we're never in a container (by + # exiting 1). + dpkg-divert --local \ + --rename /usr/bin/systemd-detect-virt + echo "exit 1" > /usr/bin/systemd-detect-virt + chmod +x /usr/bin/systemd-detect-virt +} + +undivert_grub() { + dpkg-divert --remove --local \ + --divert /etc/grub.d/30_os-prober.dpkg-divert \ + --rename /etc/grub.d/30_os-prober + + rm /usr/bin/systemd-detect-virt + dpkg-divert --remove --local \ + --rename /usr/bin/systemd-detect-virt +} + +replace_grub_root_with_label() { + # When update-grub is run, it will detect the disks in the build system. + # Instead, we want grub to use the right labelled disk + + # If boot by partuuid has been requested, don't override. + if [ -f /etc/default/grub.d/40-force-partuuid.cfg ] && \ + grep -q ^GRUB_FORCE_PARTUUID= /etc/default/grub.d/40-force-partuuid.cfg + then + return 0 + fi + sed -i -e "s,root=[^ ]*,root=LABEL=${fs_label}," \ + "/boot/grub/grub.cfg" +} + +cat << EOF > /etc/fstab +LABEL=rootfs / ext4 defaults 0 0 +LABEL=UEFI /boot/efi vfat defaults 0 0 +EOF + +if [ -n "$partuuid" ]; then + echo "GRUB_FORCE_PARTUUID=${partuuid}" >> /etc/default/grub.d/40-force-partuuid.cfg +fi + +# Install bootloader +efi_target=x86_64-efi + +grub-install "${loop_device}" \ + --boot-directory=/boot \ + --efi-directory=/boot/efi \ + --target=${efi_target} \ + --removable \ + --uefi-secure-boot \ + --no-nvram + +if [ -f /boot/efi/EFI/BOOT/grub.cfg ]; then + IMAGE_STR="# This file was created/modified by distrobuilder" + sed -i "s| root| root hd0,gpt1|" /boot/efi/EFI/BOOT/grub.cfg + sed -i "1i${IMAGE_STR}" /boot/efi/EFI/BOOT/grub.cfg + # For some reason the grub disk is looking for /boot/grub/grub.cfg on + # part 15.... + mkdir -p /boot/efi/boot/grub + cp /boot/efi/EFI/BOOT/grub.cfg /boot/efi/boot/grub +fi + +# Install the BIOS/GPT bits. Since GPT boots from the ESP partition, +# it means that we just run this simple command and we're done +grub-install --target=i386-pc "${loop_device}" + +divert_grub +update-grub +replace_grub_root_with_label +undivert_grub +` diff --git a/image/lxd.go b/image/lxd.go index 52400a5..2c65ddc 100644 --- a/image/lxd.go +++ b/image/lxd.go @@ -37,12 +37,17 @@ func NewLXDImage(sourceDir, targetDir, cacheDir string, } // Build creates a LXD image. -func (l *LXDImage) Build(unified bool, compression string) error { +func (l *LXDImage) Build(unified bool, compression string, vm bool) error { err := l.createMetadata() if err != nil { return nil } + if vm { + // If we're building a VM, we need the separate metadata tarball. + unified = false + } + file, err := os.Create(filepath.Join(l.cacheDir, "metadata.yaml")) if err != nil { return err @@ -67,16 +72,16 @@ func (l *LXDImage) Build(unified bool, compression string) error { paths = append(paths, "templates") } - if unified { - var fname string - if l.definition.Image.Name != "" { - // Use a custom name for the unified tarball. - fname, _ = shared.RenderTemplate(l.definition.Image.Name, l.definition) - } else { - // Default name for the unified tarball. - fname = "lxd" - } + var fname string + if l.definition.Image.Name != "" { + // Use a custom name for the unified tarball. + fname, _ = shared.RenderTemplate(l.definition.Image.Name, l.definition) + } else { + // Default name for the unified tarball. + fname = "lxd" + } + if unified { // Add the rootfs to the tarball, prefix all files with "rootfs" err = shared.Pack(filepath.Join(l.targetDir, fmt.Sprintf("%s.tar", fname)), "", l.sourceDir, "--transform", "s,^./,rootfs/,", ".") @@ -91,13 +96,25 @@ func (l *LXDImage) Build(unified bool, compression string) error { return err } } else { - // Create rootfs as squashfs. - err = shared.RunCommand("mksquashfs", l.sourceDir, - filepath.Join(l.targetDir, "rootfs.squashfs"), "-noappend", "-comp", - "xz", "-b", "1M", "-no-progress", "-no-recovery") + if vm { + // Create compressed qcow2 image. + err = shared.RunCommand("qemu-img", "convert", "-c", "-O", "qcow2", "-o", "compat=0.10", + filepath.Join(l.targetDir, fmt.Sprintf("%s.img", fname)), + filepath.Join(l.targetDir, fmt.Sprintf("%s.qcow2", fname))) + } else { + // Create rootfs as squashfs. + err = shared.RunCommand("mksquashfs", l.sourceDir, + filepath.Join(l.targetDir, "rootfs.squashfs"), "-noappend", "-comp", + "xz", "-b", "1M", "-no-progress", "-no-recovery") + } if err != nil { return err } + defer func() { + if vm { + os.RemoveAll(filepath.Join(l.targetDir, fmt.Sprintf("%s.img", fname))) + } + }() // Create metadata tarball. err = shared.Pack(filepath.Join(l.targetDir, "lxd.tar"), compression, diff --git a/image/lxd_test.go b/image/lxd_test.go index d9efcd1..c5ce4db 100644 --- a/image/lxd_test.go +++ b/image/lxd_test.go @@ -76,7 +76,7 @@ func TestLXDBuild(t *testing.T) { func testLXDBuildSplitImage(t *testing.T, image *LXDImage) { // Create split tarball and squashfs. - err := image.Build(false, "xz") + err := image.Build(false, "xz", false) require.NoError(t, err) defer func() { os.Remove("lxd.tar.xz") @@ -89,7 +89,7 @@ func testLXDBuildSplitImage(t *testing.T, image *LXDImage) { func testLXDBuildUnifiedImage(t *testing.T, image *LXDImage) { // Create unified tarball with custom name. - err := image.Build(true, "xz") + err := image.Build(true, "xz", false) require.NoError(t, err) defer os.Remove("ubuntu-17.10-x86_64-testing.tar.xz") @@ -97,7 +97,7 @@ func testLXDBuildUnifiedImage(t *testing.T, image *LXDImage) { // Create unified tarball with default name. image.definition.Image.Name = "" - err = image.Build(true, "xz") + err = image.Build(true, "xz", false) require.NoError(t, err) defer os.Remove("lxd.tar.xz")
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel