Package: autopkgtest Version: 5.31.2 Severity: wishlist Tags: patch Recent actions by Canonical have resulted in the Incus project being forked from LXD; see https://bugs.debian.org/1042989 and https://bugs.debian.org/1058592 for background. It isn't yet in Debian, but there are efforts in progress to package it. I'm using the Zabbly packages (https://github.com/zabbly/incus) until such time as it's properly in Debian.
We've been discussing using Incus in debusine (https://salsa.debian.org/freexian-team/debusine); debusine uses autopkgtest, and autopkgtest includes LXD integration, hence this bug report. While at some point you might want to do a bit more abstraction to reduce code duplication, I think the simplest approach would be to copy autopkgtest-{build,virt}-lxd to autopkgtest-{build,virt}-incus and do a little bit of search-and-replace. I've filed https://salsa.debian.org/ci-team/autopkgtest/-/merge_requests/272 for this. To help with review, here's the diff against the LXD versions. --- tools/autopkgtest-build-lxd 2024-01-03 11:12:52.376824948 +0000 +++ tools/autopkgtest-build-incus 2024-01-03 11:24:24.368817982 +0000 @@ -1,10 +1,10 @@ #!/bin/sh -# autopkgtest-build-lxd is part of autopkgtest +# autopkgtest-build-incus is part of autopkgtest # autopkgtest is a tool for testing Debian binary packages # # autopkgtest is Copyright (C) 2006-2015 Canonical Ltd. # -# Build or update an LXD image autopkgtest/<distro>/<release>/<arch> with +# Build or update an Incus image autopkgtest/<distro>/<release>/<arch> with # autopkgtest customizations from an arbitrary existing image. # # This program is free software; you can redistribute it and/or modify @@ -29,7 +29,7 @@ generate_container_name() { while true; do CONTAINER=$(mktemp autopkgtest-prepare-XXX -u) - lxc info "$CONTAINER" >/dev/null 2>&1 || break + incus info "$CONTAINER" >/dev/null 2>&1 || break done } @@ -43,7 +43,7 @@ if echo "${proxy:-}" | egrep -q '(localhost|127\.0\.0\.[0-9]*)'; then # translate proxy address to one that can be accessed from the # running container - local bridge_interface=$(lxc profile show default | sed -n '/parent:/ { s/^.*: *//; p; q }') || true + local bridge_interface=$(incus profile show default | sed -n '/parent:/ { s/^.*: *//; p; q }') || true if [ -n "$bridge_interface" ]; then local bridge_ip=$(ip -4 a show dev "$bridge_interface" | awk '/ inet / {sub(/\/.*$/, "", $2); print $2}') || true if [ -n "$bridge_ip" ]; then @@ -63,22 +63,22 @@ setup() { # set up apt proxy for the container if [ -n "$AUTOPKGTEST_APT_PROXY" ] && [ "$AUTOPKGTEST_APT_PROXY" != "none" ]; then - echo "Acquire::http::Proxy \"$AUTOPKGTEST_APT_PROXY\";" | lxc file push - "$CONTAINER/etc/apt/apt.conf.d/01proxy" + echo "Acquire::http::Proxy \"$AUTOPKGTEST_APT_PROXY\";" | incus file push - "$CONTAINER/etc/apt/apt.conf.d/01proxy" # work around LP#1548878 - lxc exec "$CONTAINER" -- chmod 644 /etc/apt/apt.conf.d/01proxy + incus exec "$CONTAINER" -- chmod 644 /etc/apt/apt.conf.d/01proxy fi sleep 5 - if lxc exec "$CONTAINER" -- systemctl mask serial-getty@getty.service; then - lxc exec "$CONTAINER" -- reboot + if incus exec "$CONTAINER" -- systemctl mask serial-getty@getty.service; then + incus exec "$CONTAINER" -- reboot fi - # wait until it is booted: lxc exec works and we get a numeric runlevel + # wait until it is booted: incus exec works and we get a numeric runlevel timeout=60 while [ $timeout -ge 0 ]; do timeout=$((timeout - 1)) sleep 1 - O=`lxc exec "$CONTAINER" runlevel 2>/dev/null </dev/null` || continue + O=`incus exec "$CONTAINER" runlevel 2>/dev/null </dev/null` || continue [ "$O" = "${O%[0-9]}" ] || break done [ $timeout -ge 0 ] || { @@ -87,14 +87,14 @@ } # wait until a systemd based container has networking - if ! echo '[ ! -d /run/systemd/system ] || systemctl start network-online.target' | timeout 60 lxc exec "$CONTAINER" -- sh -e; then + if ! echo '[ ! -d /run/systemd/system ] || systemctl start network-online.target' | timeout 60 incus exec "$CONTAINER" -- sh -e; then echo "Timed out waiting for container to start network-online.target" >&2 exit 1 fi - ARCH=$(lxc exec "$CONTAINER" -- dpkg --print-architecture </dev/null) - DISTRO=$(lxc exec "$CONTAINER" -- sh -ec 'lsb_release -si 2>/dev/null || . /etc/os-release; echo "${NAME% *}"' </dev/null) - CRELEASE=$(lxc exec "$CONTAINER" -- sh -ec 'lsb_release -sc 2>/dev/null || awk "/^deb/ {sub(/\\[.*\\]/, \"\", \$0); print \$3; exit}" /etc/apt/sources.list' </dev/null) + ARCH=$(incus exec "$CONTAINER" -- dpkg --print-architecture </dev/null) + DISTRO=$(incus exec "$CONTAINER" -- sh -ec 'lsb_release -si 2>/dev/null || . /etc/os-release; echo "${NAME% *}"' </dev/null) + CRELEASE=$(incus exec "$CONTAINER" -- sh -ec 'lsb_release -sc 2>/dev/null || awk "/^deb/ {sub(/\\[.*\\]/, \"\", \$0); print \$3; exit}" /etc/apt/sources.list' </dev/null) echo "Container finished booting. Distribution $DISTRO, release $CRELEASE, architecture $ARCH" RELEASE=${RELEASE:-${CRELEASE}} @@ -109,7 +109,7 @@ /usr/share/autopkgtest/setup-commands/setup-testbed; do if [ -r "$script" ]; then echo "Running setup script $script..." - lxc exec "$CONTAINER" -- env \ + incus exec "$CONTAINER" -- env \ AUTOPKGTEST_KEEP_APT_SOURCES="${AUTOPKGTEST_KEEP_APT_SOURCES:-}" \ AUTOPKGTEST_APT_SOURCES="${AUTOPKGTEST_APT_SOURCES:-}" \ MIRROR="${MIRROR:-}" \ @@ -118,7 +118,7 @@ break fi done - lxc stop "$CONTAINER" + incus stop "$CONTAINER" } print_usage() { @@ -159,12 +159,12 @@ IMAGE="$1" CONTAINER='' -trap '[ -z "$CONTAINER" ] || lxc delete -f "$CONTAINER"' EXIT INT QUIT PIPE +trap '[ -z "$CONTAINER" ] || incus delete -f "$CONTAINER"' EXIT INT QUIT PIPE proxy_detect generate_container_name -# we must redirect stdin when calling lxc launch due to lp #1845037 -lxc launch "$IMAGE" "$CONTAINER" ${USE_VM:+--vm} < /dev/null +# we must redirect stdin when calling incus launch due to lp #1845037 +incus launch "$IMAGE" "$CONTAINER" ${USE_VM:+--vm} < /dev/null setup # if there already is a published image, get its fingerprint to clean it up @@ -173,14 +173,10 @@ ALIAS="autopkgtest/$DISTROLC/$RELEASE/$ARCH${USE_VM:+/vm}" DESCRIPTION="autopkgtest $DISTRO $RELEASE $ARCH" -REUSE="" -if dpkg --compare-versions $(lxc version | sed -ne 's/Client version: // p') ge 5.14; then - REUSE="--reuse" -fi -lxc publish "$CONTAINER" $REUSE --alias "$ALIAS" --public description="$DESCRIPTION" distribution="$DISTROLC" release="$RELEASE" architecture="$ARCH" +incus publish "$CONTAINER" --reuse --alias "$ALIAS" --public description="$DESCRIPTION" distribution="$DISTROLC" release="$RELEASE" architecture="$ARCH" # clean up old images -for i in $(lxc image list | grep "$DESCRIPTION" | grep -v "$ALIAS" | cut -d'|' -f3); do +for i in $(incus image list | grep "$DESCRIPTION" | grep -v "$ALIAS" | cut -d'|' -f3); do echo "Removing previous image $i" - lxc image delete "$i" + incus image delete "$i" done --- virt/autopkgtest-virt-lxd 2024-01-03 11:12:52.376824948 +0000 +++ virt/autopkgtest-virt-incus 2024-01-03 11:09:08.860827198 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/python3 # -# autopkgtest-virt-lxd is part of autopkgtest +# autopkgtest-virt-incus is part of autopkgtest # autopkgtest is a tool for testing Debian binary packages # # autopkgtest is Copyright (C) 2006-2015 Canonical Ltd. @@ -60,12 +60,12 @@ help='Enable debugging output') parser.add_argument('-r', '--remote', default='', help='Run container on given remote host instead of ' - 'locally; see "lxc remote list"') + 'locally; see "incus remote list"') parser.add_argument('--vm', action='store_true', default=False, help='Run a virtual machine instead of a container') - parser.add_argument('image', help='LXD image name') - parser.add_argument('lxcargs', nargs=argparse.REMAINDER, - help='Additional arguments to pass to lxc launch ') + parser.add_argument('image', help='Incus image name') + parser.add_argument('incusargs', nargs=argparse.REMAINDER, + help='Additional arguments to pass to incus launch ') args = parser.parse_args() if args.debug: adtlog.verbosity = 2 @@ -79,9 +79,9 @@ while True: # generate random container name rnd = [random.choice(string.ascii_lowercase) for i in range(6)] - candidate = 'autopkgtest-lxd-' + ''.join(rnd) + candidate = 'autopkgtest-incus-' + ''.join(rnd) - rc = VirtSubproc.execute_timeout(None, 10, ['lxc', 'info', candidate], + rc = VirtSubproc.execute_timeout(None, 10, ['incus', 'info', candidate], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)[0] if rc != 0: @@ -89,7 +89,7 @@ def wait_booted(): - VirtSubproc.wait_booted(['lxc', 'exec', container_name, '--'], timeout=180) + VirtSubproc.wait_booted(['incus', 'exec', container_name, '--'], timeout=180) def determine_normal_user(): @@ -99,7 +99,7 @@ # get the first UID in the Debian Policy ยง9.2.2 "dynamically allocated # user account" range - cmd = ['lxc', 'exec', container_name, '--', 'sh', '-c', + cmd = ['incus', 'exec', container_name, '--', 'sh', '-c', 'getent passwd | sort -t: -nk3 | ' "awk -F: '{if ($3 >= 1000 && $3 <= 59999) { print $1; exit } }'"] out = VirtSubproc.execute_timeout(None, 10, cmd, @@ -115,11 +115,11 @@ def hook_open(): global args, container_name, capabilities - extra_lxcargs = args.lxcargs + extra_incusargs = args.incusargs if args.vm: adtlog.debug('will start a VM (with isolation-machine capability)') capabilities.append('isolation-machine') - extra_lxcargs += ['--vm'] + extra_incusargs += ['--vm'] else: adtlog.debug('will start a container (with isolation-container capability)') capabilities.append('isolation-container') @@ -127,7 +127,7 @@ container_name = args.remote + get_available_container_name() adtlog.debug('using container name %s' % container_name) VirtSubproc.check_exec( - ['lxc', 'launch', '--ephemeral', args.image, container_name] + extra_lxcargs, + ['incus', 'launch', '--ephemeral', args.image, container_name] + extra_incusargs, outp=True, timeout=600 ) @@ -140,11 +140,11 @@ # We also want to avoid exiting with 255 as that's auxverb's exit code # if the auxverb itself failed; so we translate that to 253. # Tests or builds sometimes leak background processes which might still - # be connected to lxc exec's stdout/err; we need to kill these after the - # main program (build or test script) finishes, otherwise we get + # be connected to incus exec's stdout/err; we need to kill these after + # the main program (build or test script) finishes, otherwise we get # eternal hangs. VirtSubproc.auxverb = [ - 'lxc', 'exec', container_name, '--', + 'incus', 'exec', container_name, '--', 'env', '-i', 'bash', '-c', 'set -a; ' '[ -r /etc/environment ] && . /etc/environment 2>/dev/null || true; ' @@ -168,7 +168,7 @@ ] except Exception: # Clean up on failure - VirtSubproc.execute_timeout(None, 300, ['lxc', 'delete', '--force', container_name]) + VirtSubproc.execute_timeout(None, 300, ['incus', 'delete', '--force', container_name]) raise @@ -184,7 +184,7 @@ def get_uptime(): try: (rc, out, _) = VirtSubproc.execute_timeout( - None, 10, ['lxc', 'exec', container_name, '--', 'cat', '/proc/uptime'], + None, 10, ['incus', 'exec', container_name, '--', 'cat', '/proc/uptime'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if rc != 0: @@ -204,7 +204,7 @@ def hook_wait_reboot(*func_args, **kwargs): adtlog.debug('hook_wait_reboot: waiting for container to shut down...') - # "lxc exec" exits with 0 when the container stops, so just wait longer + # "incus exec" exits with 0 when the container stops, so just wait longer # than our timeout initial_uptime = kwargs['initial_uptime'] @@ -234,7 +234,7 @@ def hook_cleanup(): VirtSubproc.downtmp_remove() - VirtSubproc.check_exec(['lxc', 'delete', '--force', container_name], timeout=600) + VirtSubproc.check_exec(['incus', 'delete', '--force', container_name], timeout=600) def hook_capabilities(): -- System Information: Debian Release: trixie/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 6.5.0-14-generic (SMP w/4 CPU threads; PREEMPT) Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_FIRMWARE_WORKAROUND, TAINT_OOT_MODULE Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8), LANGUAGE=en_GB:en Shell: /bin/sh linked to /usr/bin/dash Init: unable to detect Versions of packages autopkgtest depends on: ii apt-utils 2.7.7 ii libdpkg-perl 1.22.2 ii mawk 1.3.4.20231126-1 ii procps 2:4.0.4-2 ii python3 3.11.6-1 ii python3-debian 0.1.49 Versions of packages autopkgtest recommends: ii autodep8 0.28 ii fakeroot 1.32.2-1 Versions of packages autopkgtest suggests: pn docker.io <none> pn fakemachine <none> ii genisoimage 9:1.1.11-3.4 pn lxc <none> pn lxd <none> ii ovmf 2023.11-2 pn ovmf-ia32 <none> pn podman <none> ii python3-distro-info 1.7 ii qemu-efi-aarch64 2023.11-2 ii qemu-efi-arm 2023.11-2 pn qemu-system <none> ii qemu-utils 1:8.2.0+ds-1 pn schroot <none> ii util-linux 2.39.3-2 pn vmdb2 <none> pn zerofree <none> -- no debconf information Thanks, -- Colin Watson (he/him) [cjwat...@debian.org]