diff -Nru docker.io-20.10.7/debian/changelog docker.io-20.10.7/debian/changelog --- docker.io-20.10.7/debian/changelog 2021-09-10 18:34:38.000000000 +0000 +++ docker.io-20.10.7/debian/changelog 2021-10-05 19:45:26.000000000 +0000 @@ -1,3 +1,23 @@ +docker.io (20.10.7-0ubuntu5) impish; urgency=medium + + [ Sergio Durigan Junior ] + * d/t/docker-in-lxd: + Improve dep8 test. Make it run a more complex test against an + ubuntu:devel docker container, especially because glibc updates might + break docker.io. Improve test reliability when running autopkgtest + locally. + + [ Steve Beattie ] + * SECURITY UPDATE: insufficiently restricted directory permissions + - d/p/CVE-2021-41091.patch: Lock down docker root dir perms. + - CVE-2021-41091 + * SECURITY UPDATE: permissions modifications outside of install directory + - d/p/CVE-2021-41089.patch: chrootarchive: don't create parent dirs + outside of chroot. + - CVE-2021-41089 + + -- Lucas Kanashiro Tue, 05 Oct 2021 16:45:26 -0300 + docker.io (20.10.7-0ubuntu4) impish; urgency=medium * d/p/seccomp-add-support-for-clone3-syscall-in-default-policy.patch: Fix diff -Nru docker.io-20.10.7/debian/patches/CVE-2021-41089.patch docker.io-20.10.7/debian/patches/CVE-2021-41089.patch --- docker.io-20.10.7/debian/patches/CVE-2021-41089.patch 1970-01-01 00:00:00.000000000 +0000 +++ docker.io-20.10.7/debian/patches/CVE-2021-41089.patch 2021-10-05 19:44:54.000000000 +0000 @@ -0,0 +1,49 @@ +From 0a9c9352b236f12f8de41d1e450fdd95ee086eb0 Mon Sep 17 00:00:00 2001 +From: Tonis Tiigi +Date: Wed, 19 May 2021 16:51:35 -0700 +Subject: [PATCH] chrootarchive: don't create parent dirs outside of chroot + +If chroot is used with a special root directory then create +destination directory within chroot. This works automatically +already due to extractor creating parent paths and is only +used currently with cp where parent paths are actually required +and error will be shown to user before reaching this point. + +Signed-off-by: Tonis Tiigi +(cherry picked from commit 52d285184068998c22632bfb869f6294b5613a58) +Signed-off-by: Brian Goff +--- + pkg/chrootarchive/archive.go | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/engine/pkg/chrootarchive/archive.go b/engine/pkg/chrootarchive/archive.go +index 83ed0c6b2f..d11cbdf277 100644 +--- a/engine/pkg/chrootarchive/archive.go ++++ b/engine/pkg/chrootarchive/archive.go +@@ -74,13 +74,17 @@ func untarHandler(tarArchive io.Reader, dest string, options *archive.TarOptions + options.ExcludePatterns = []string{} + } + +- idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps) +- rootIDs := idMapping.RootPair() ++ // If dest is inside a root then directory is created within chroot by extractor. ++ // This case is only currently used by cp. ++ if dest == root { ++ idMapping := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps) ++ rootIDs := idMapping.RootPair() + +- dest = filepath.Clean(dest) +- if _, err := os.Stat(dest); os.IsNotExist(err) { +- if err := idtools.MkdirAllAndChownNew(dest, 0755, rootIDs); err != nil { +- return err ++ dest = filepath.Clean(dest) ++ if _, err := os.Stat(dest); os.IsNotExist(err) { ++ if err := idtools.MkdirAllAndChownNew(dest, 0755, rootIDs); err != nil { ++ return err ++ } + } + } + +-- +2.33.0 + diff -Nru docker.io-20.10.7/debian/patches/CVE-2021-41091.patch docker.io-20.10.7/debian/patches/CVE-2021-41091.patch --- docker.io-20.10.7/debian/patches/CVE-2021-41091.patch 1970-01-01 00:00:00.000000000 +0000 +++ docker.io-20.10.7/debian/patches/CVE-2021-41091.patch 2021-10-05 19:44:54.000000000 +0000 @@ -0,0 +1,382 @@ +From 93ac040bf0c0b51d9a7fedaf994bf5bf1d68ee0e Mon Sep 17 00:00:00 2001 +From: Brian Goff +Date: Fri, 2 Jul 2021 17:27:45 +0000 +Subject: [PATCH] Lock down docker root dir perms. + +Do not use 0701 perms. +0701 dir perms allows anyone to traverse the docker dir. +It happens to allow any user to execute, as an example, suid binaries +from image rootfs dirs because it allows traversal AND critically +container users need to be able to do execute things. + +0701 on lower directories also happens to allow any user to modify + things in, for instance, the overlay upper dir which neccessarily + has 0755 permissions. + +This changes to use 0710 which allows users in the group to traverse. +In userns mode the UID owner is (real) root and the GID is the remapped +root's GID. + +This prevents anyone but the remapped root to traverse our directories +(which is required for userns with runc). + +Signed-off-by: Brian Goff +(cherry picked from commit ef7237442147441a7cadcda0600be1186d81ac73) +Signed-off-by: Brian Goff +--- + daemon/container_operations_unix.go | 2 +- + daemon/create.go | 5 ++-- + daemon/daemon.go | 5 +++- + daemon/daemon_unix.go | 14 +++++------ + daemon/graphdriver/aufs/aufs.go | 13 ++++++++-- + daemon/graphdriver/btrfs/btrfs.go | 18 ++++++++++++-- + .../fuse-overlayfs/fuseoverlayfs.go | 24 +++++++++++++++---- + daemon/graphdriver/overlay/overlay.go | 20 ++++++++++++---- + daemon/graphdriver/overlay2/overlay.go | 24 +++++++++++++++---- + daemon/graphdriver/vfs/driver.go | 17 +++++++++++-- + daemon/graphdriver/zfs/zfs.go | 11 ++++++++- + 11 files changed, 121 insertions(+), 32 deletions(-) + +diff --git a/engine/daemon/container_operations_unix.go b/engine/daemon/container_operations_unix.go +index 5521adbd27..1647df0ce7 100644 +--- a/engine/daemon/container_operations_unix.go ++++ b/engine/daemon/container_operations_unix.go +@@ -466,5 +466,5 @@ func (daemon *Daemon) setupContainerMountsRoot(c *container.Container) error { + if err != nil { + return err + } +- return idtools.MkdirAllAndChown(p, 0701, idtools.CurrentIdentity()) ++ return idtools.MkdirAllAndChown(p, 0710, idtools.Identity{UID: idtools.CurrentIdentity().UID, GID: daemon.IdentityMapping().RootPair().GID}) + } +diff --git a/engine/daemon/create.go b/engine/daemon/create.go +index 57f1eff665..b07851aec9 100644 +--- a/engine/daemon/create.go ++++ b/engine/daemon/create.go +@@ -212,10 +212,11 @@ func (daemon *Daemon) create(opts createOpts) (retC *container.Container, retErr + } + ctr.RWLayer = rwLayer + +- if err := idtools.MkdirAndChown(ctr.Root, 0701, idtools.CurrentIdentity()); err != nil { ++ current := idtools.CurrentIdentity() ++ if err := idtools.MkdirAndChown(ctr.Root, 0710, idtools.Identity{UID: current.UID, GID: daemon.IdentityMapping().RootPair().GID}); err != nil { + return nil, err + } +- if err := idtools.MkdirAndChown(ctr.CheckpointDir(), 0700, idtools.CurrentIdentity()); err != nil { ++ if err := idtools.MkdirAndChown(ctr.CheckpointDir(), 0700, current); err != nil { + return nil, err + } + +diff --git a/engine/daemon/daemon.go b/engine/daemon/daemon.go +index 3d8cca2880..2a2fbbd52e 100644 +--- a/engine/daemon/daemon.go ++++ b/engine/daemon/daemon.go +@@ -861,7 +861,10 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S + } + + daemonRepo := filepath.Join(config.Root, "containers") +- if err := idtools.MkdirAllAndChown(daemonRepo, 0701, idtools.CurrentIdentity()); err != nil { ++ if err := idtools.MkdirAllAndChown(daemonRepo, 0710, idtools.Identity{ ++ UID: idtools.CurrentIdentity().UID, ++ GID: rootIDs.GID, ++ }); err != nil { + return nil, err + } + +diff --git a/engine/daemon/daemon_unix.go b/engine/daemon/daemon_unix.go +index 8754d4f972..d982018c34 100644 +--- a/engine/daemon/daemon_unix.go ++++ b/engine/daemon/daemon_unix.go +@@ -1216,21 +1216,21 @@ func setupDaemonRoot(config *config.Config, rootDir string, remappedRoot idtools + } + } + ++ id := idtools.Identity{UID: idtools.CurrentIdentity().UID, GID: remappedRoot.GID} ++ // First make sure the current root dir has the correct perms. ++ if err := idtools.MkdirAllAndChown(config.Root, 0710, id); err != nil { ++ return errors.Wrapf(err, "could not create or set daemon root permissions: %s", config.Root) ++ } ++ + // if user namespaces are enabled we will create a subtree underneath the specified root + // with any/all specified remapped root uid/gid options on the daemon creating + // a new subdirectory with ownership set to the remapped uid/gid (so as to allow + // `chdir()` to work for containers namespaced to that uid/gid) + if config.RemappedRoot != "" { +- id := idtools.CurrentIdentity() +- // First make sure the current root dir has the correct perms. +- if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil { +- return errors.Wrapf(err, "could not create or set daemon root permissions: %s", config.Root) +- } +- + config.Root = filepath.Join(rootDir, fmt.Sprintf("%d.%d", remappedRoot.UID, remappedRoot.GID)) + logrus.Debugf("Creating user namespaced daemon root: %s", config.Root) + // Create the root directory if it doesn't exist +- if err := idtools.MkdirAllAndChown(config.Root, 0701, id); err != nil { ++ if err := idtools.MkdirAllAndChown(config.Root, 0710, id); err != nil { + return fmt.Errorf("Cannot create daemon root: %s: %v", config.Root, err) + } + // we also need to verify that any pre-existing directories in the path to +diff --git a/engine/daemon/graphdriver/aufs/aufs.go b/engine/daemon/graphdriver/aufs/aufs.go +index b007274e13..cfa18666d9 100644 +--- a/engine/daemon/graphdriver/aufs/aufs.go ++++ b/engine/daemon/graphdriver/aufs/aufs.go +@@ -130,14 +130,23 @@ func Init(root string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap + } + + currentID := idtools.CurrentIdentity() ++ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) ++ if err != nil { ++ return nil, err ++ } ++ dirID := idtools.Identity{ ++ UID: currentID.UID, ++ GID: rootGID, ++ } ++ + // Create the root aufs driver dir +- if err := idtools.MkdirAllAndChown(root, 0701, currentID); err != nil { ++ if err := idtools.MkdirAllAndChown(root, 0710, dirID); err != nil { + return nil, err + } + + // Populate the dir structure + for _, p := range paths { +- if err := idtools.MkdirAllAndChown(path.Join(root, p), 0701, currentID); err != nil { ++ if err := idtools.MkdirAllAndChown(path.Join(root, p), 0710, dirID); err != nil { + return nil, err + } + } +diff --git a/engine/daemon/graphdriver/btrfs/btrfs.go b/engine/daemon/graphdriver/btrfs/btrfs.go +index 0499489d16..8fd2854a26 100644 +--- a/engine/daemon/graphdriver/btrfs/btrfs.go ++++ b/engine/daemon/graphdriver/btrfs/btrfs.go +@@ -70,7 +70,14 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap + return nil, graphdriver.ErrPrerequisites + } + +- if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil { ++ remappedRoot := idtools.NewIDMappingsFromMaps(uidMaps, gidMaps) ++ currentID := idtools.CurrentIdentity() ++ dirID := idtools.Identity{ ++ UID: currentID.UID, ++ GID: remappedRoot.RootPair().GID, ++ } ++ ++ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil { + return nil, err + } + +@@ -521,7 +528,14 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { + if err != nil { + return err + } +- if err := idtools.MkdirAllAndChown(subvolumes, 0701, idtools.CurrentIdentity()); err != nil { ++ ++ currentID := idtools.CurrentIdentity() ++ dirID := idtools.Identity{ ++ UID: currentID.UID, ++ GID: rootGID, ++ } ++ ++ if err := idtools.MkdirAllAndChown(subvolumes, 0710, dirID); err != nil { + return err + } + if parent == "" { +diff --git a/engine/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go b/engine/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go +index 782e8be984..1bf30f4298 100644 +--- a/engine/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go ++++ b/engine/daemon/graphdriver/fuse-overlayfs/fuseoverlayfs.go +@@ -88,7 +88,17 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap + return nil, graphdriver.ErrNotSupported + } + +- if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0701, idtools.CurrentIdentity()); err != nil { ++ remappedRoot := idtools.NewIDMappingsFromMaps(uidMaps, gidMaps) ++ currentID := idtools.CurrentIdentity() ++ dirID := idtools.Identity{ ++ UID: currentID.UID, ++ GID: remappedRoot.RootPair().GID, ++ } ++ ++ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil { ++ return nil, err ++ } ++ if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 700, currentID); err != nil { + return nil, err + } + +@@ -173,11 +183,15 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + } + root := idtools.Identity{UID: rootUID, GID: rootGID} + +- currentID := idtools.CurrentIdentity() +- if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, currentID); err != nil { ++ dirID := idtools.Identity{ ++ UID: rootUID, ++ GID: rootGID, ++ } ++ ++ if err := idtools.MkdirAllAndChown(path.Dir(dir), 0710, dirID); err != nil { + return err + } +- if err := idtools.MkdirAndChown(dir, 0701, currentID); err != nil { ++ if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil { + return err + } + +@@ -211,7 +225,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + return nil + } + +- if err := idtools.MkdirAndChown(path.Join(dir, workDirName), 0701, currentID); err != nil { ++ if err := idtools.MkdirAndChown(path.Join(dir, workDirName), 0710, dirID); err != nil { + return err + } + +diff --git a/engine/daemon/graphdriver/overlay/overlay.go b/engine/daemon/graphdriver/overlay/overlay.go +index 90be0e3d64..6e9897da05 100644 +--- a/engine/daemon/graphdriver/overlay/overlay.go ++++ b/engine/daemon/graphdriver/overlay/overlay.go +@@ -156,11 +156,20 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap + logrus.WithField("storage-driver", "overlay").Warn(overlayutils.ErrDTypeNotSupported("overlay", backingFs)) + } + +- // Create the driver home dir +- if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil { ++ currentID := idtools.CurrentIdentity() ++ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) ++ if err != nil { + return nil, err + } ++ dirID := idtools.Identity{ ++ UID: currentID.UID, ++ GID: rootGID, ++ } + ++ // Create the driver home dir ++ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil { ++ return nil, err ++ } + d := &Driver{ + home: home, + uidMaps: uidMaps, +@@ -262,10 +271,11 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) (retErr + root := idtools.Identity{UID: rootUID, GID: rootGID} + + currentID := idtools.CurrentIdentity() +- if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, currentID); err != nil { +- return err ++ dirID := idtools.Identity{ ++ UID: currentID.UID, ++ GID: rootGID, + } +- if err := idtools.MkdirAndChown(dir, 0701, currentID); err != nil { ++ if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil { + return err + } + +diff --git a/engine/daemon/graphdriver/overlay2/overlay.go b/engine/daemon/graphdriver/overlay2/overlay.go +index 36a921a018..562d1e58fd 100644 +--- a/engine/daemon/graphdriver/overlay2/overlay.go ++++ b/engine/daemon/graphdriver/overlay2/overlay.go +@@ -165,7 +165,20 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap + logger.Warn(overlayutils.ErrDTypeNotSupported("overlay2", backingFs)) + } + +- if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0701, idtools.CurrentIdentity()); err != nil { ++ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) ++ if err != nil { ++ return nil, err ++ } ++ ++ cur := idtools.CurrentIdentity() ++ dirID := idtools.Identity{ ++ UID: cur.UID, ++ GID: rootGID, ++ } ++ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil { ++ return nil, err ++ } ++ if err := idtools.MkdirAllAndChown(path.Join(home, linkDir), 0700, cur); err != nil { + return nil, err + } + +@@ -344,12 +357,15 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr + return err + } + root := idtools.Identity{UID: rootUID, GID: rootGID} +- current := idtools.CurrentIdentity() ++ dirID := idtools.Identity{ ++ UID: idtools.CurrentIdentity().UID, ++ GID: rootGID, ++ } + +- if err := idtools.MkdirAllAndChown(path.Dir(dir), 0701, current); err != nil { ++ if err := idtools.MkdirAllAndChown(path.Dir(dir), 0710, dirID); err != nil { + return err + } +- if err := idtools.MkdirAndChown(dir, 0701, current); err != nil { ++ if err := idtools.MkdirAndChown(dir, 0710, dirID); err != nil { + return err + } + +diff --git a/engine/daemon/graphdriver/vfs/driver.go b/engine/daemon/graphdriver/vfs/driver.go +index af9b107609..f903393da2 100644 +--- a/engine/daemon/graphdriver/vfs/driver.go ++++ b/engine/daemon/graphdriver/vfs/driver.go +@@ -37,8 +37,16 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap + if err := d.parseOptions(options); err != nil { + return nil, err + } ++ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) ++ if err != nil { ++ return nil, err ++ } + +- if err := idtools.MkdirAllAndChown(home, 0701, idtools.CurrentIdentity()); err != nil { ++ dirID := idtools.Identity{ ++ UID: idtools.CurrentIdentity().UID, ++ GID: rootGID, ++ } ++ if err := idtools.MkdirAllAndChown(home, 0710, dirID); err != nil { + return nil, err + } + +@@ -140,7 +148,12 @@ func (d *Driver) Create(id, parent string, opts *graphdriver.CreateOpts) error { + func (d *Driver) create(id, parent string, size uint64) error { + dir := d.dir(id) + rootIDs := d.idMapping.RootPair() +- if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0701, idtools.CurrentIdentity()); err != nil { ++ ++ dirID := idtools.Identity{ ++ UID: idtools.CurrentIdentity().UID, ++ GID: rootIDs.GID, ++ } ++ if err := idtools.MkdirAllAndChown(filepath.Dir(dir), 0710, dirID); err != nil { + return err + } + if err := idtools.MkdirAndChown(dir, 0755, rootIDs); err != nil { +diff --git a/engine/daemon/graphdriver/zfs/zfs.go b/engine/daemon/graphdriver/zfs/zfs.go +index f9099a2094..2fbbe9498f 100644 +--- a/engine/daemon/graphdriver/zfs/zfs.go ++++ b/engine/daemon/graphdriver/zfs/zfs.go +@@ -104,7 +104,16 @@ func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdri + return nil, fmt.Errorf("BUG: zfs get all -t filesystem -rHp '%s' should contain '%s'", options.fsName, options.fsName) + } + +- if err := idtools.MkdirAllAndChown(base, 0701, idtools.CurrentIdentity()); err != nil { ++ _, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) ++ if err != nil { ++ return nil, err ++ } ++ ++ dirID := idtools.Identity{ ++ UID: idtools.CurrentIdentity().UID, ++ GID: rootGID, ++ } ++ if err := idtools.MkdirAllAndChown(base, 0710, dirID); err != nil { + return nil, fmt.Errorf("Failed to create '%s': %v", base, err) + } + +-- +2.25.1 + diff -Nru docker.io-20.10.7/debian/patches/series docker.io-20.10.7/debian/patches/series --- docker.io-20.10.7/debian/patches/series 2021-09-10 18:34:38.000000000 +0000 +++ docker.io-20.10.7/debian/patches/series 2021-10-05 19:44:54.000000000 +0000 @@ -1 +1,3 @@ seccomp-add-support-for-clone3-syscall-in-default-policy.patch +CVE-2021-41089.patch +CVE-2021-41091.patch diff -Nru docker.io-20.10.7/debian/tests/docker-in-lxd docker.io-20.10.7/debian/tests/docker-in-lxd --- docker.io-20.10.7/debian/tests/docker-in-lxd 2021-09-10 18:33:19.000000000 +0000 +++ docker.io-20.10.7/debian/tests/docker-in-lxd 2021-10-05 19:41:16.000000000 +0000 @@ -45,6 +45,17 @@ lxc info | grep -q "^\- ${1}$" } +# Copy the local apt package archive over to the lxd container. +# This function assumes that the container is named "docker". +copy_local_apt_files() { + for local_source in $(apt-get indextargets | grep-dctrl -F URI -e '^file:///' -sURI); do + local_source=${local_source#file://} + local_dir=$(dirname "${local_source}") + lxc exec docker -- mkdir -p "${local_dir}" + tar -cC "${local_dir}" . | lxc exec docker -- tar -xC "${local_dir}" + done +} + time lxd waitready --timeout 600 # Attempt to auto-configure ipv4, but only when really running under @@ -105,12 +116,7 @@ lxc exec docker -- mkdir /etc/apt tar -cC /etc/apt . | lxc exec docker -- tar -xC /etc/apt -for local_source in $(apt-get indextargets | grep-dctrl -F URI -e '^file:///' -sURI); do - local_source=${local_source#file://} - local_dir=$(dirname ${local_source}) - lxc exec docker -- mkdir -p ${local_dir} - tar -cC ${local_dir} . | lxc exec docker -- tar -xC ${local_dir} -done +copy_local_apt_files if [ -n "${http_proxy:-}" ]; then lxc exec docker -- mkdir -p /etc/systemd/system/docker.service.d @@ -165,22 +171,49 @@ lxc restart docker sleep 5 +# We call this again here because if the local apt repository lived +# under /tmp, it won't be available anymore after a container restart. +copy_local_apt_files +lxc exec docker -- apt-get update + lxc exec docker --env DEBIAN_FRONTEND=noninteractive -- apt-get install docker.io -y # Now basically run the simplest possible test inside the container. case ${arch} in - amd64) - image=hello-world;; - armhf|i386|s390x) - image=${arch}/hello-world;; + amd64|i386|s390x) + image_hello_world=${arch}/hello-world + image_ubuntu="${arch}/ubuntu:devel";; + armhf) + image_hello_world=arm32v7/hello-world + image_ubuntu=arm32v7/ubuntu:devel;; ppc64el) - image=ppc64le/hello-world;; + image_hello_world=ppc64le/hello-world + image_ubuntu=ppc64le/ubuntu:devel;; arm64) - image=aarch64/hello-world;; + image_hello_world=arm64v8/hello-world + image_ubuntu=arm64v8/ubuntu:devel;; *) echo "unknown arch: ${arch}" exit 2;; esac -lxc exec docker -- docker run ${image} +lxc exec docker -- docker run "${image_hello_world}" + +ubuntu_devel_suite=$(lxc exec docker -- docker run --rm "${image_ubuntu}" \ + /bin/bash -c 'source /etc/lsb-release && echo "$DISTRIB_CODENAME"') + +# We also need to run some commands inside an ubuntu:devel container, +# to make sure that docker.io can work correctly with the latest +# glibc. +# +# It's also important to make sure the docker container is using the +# same apt configuration from the lxd container, which itself is the +# same apt configuration from the host. +# +# We just want to perform this test when the docker.io package is +# being tested against the development release of Ubuntu. +if [ "${ubuntu_devel_suite}" = "${suite}" ]; then + lxc exec docker -- docker run -v /etc/apt:/etc/apt "${image_ubuntu}" \ + /bin/bash -c 'apt-get update; apt-get full-upgrade -y && apt-get install -y hello' +fi