[Libguestfs] [libnbd PATCH 5/5] Introduction of automated testing

Martin Kletzander mkletzan at redhat.com
Thu May 6 11:30:10 UTC 2021


This setup uses the libvirt-ci to get as much coverage as possible with the ease
of use provided by that repository.  Not all the data are available there at the
time of posting this patch, so if anyone wants to recreate the Containerfiles
and variable files (for cirrus CI) my temporary branch of libvirt-ci called
nbd_prep has all the work that is going to be proposed for inclusion there once
this goes in:

  https://gitlab.com/nertpinx/libvirt-ci/-/tree/nbd_prep

The result of this branch CI run is available here:

  https://gitlab.com/nertpinx/libnbd/-/pipelines

If there are any questions related to how the CI is running, how it
works, how to replicate CI builds locally or how to change anything,
then I am more than happy to help.

Actually recreating the builds locally (at least for Linux distributions
and setups) is pretty straightforward. Choose a file from ci/containers
which represents the desired setup, for our example let's pick fedora
rawhide, and build your container and tag it, e.g. using podman (or feel
free to substitute "podman" with "docker"):

  podman build ci/containers/fedora-33.Dockerfile -t libnbd-fedora-rawhide

That will get you a container tagged `libnbd-fedora-rawhide` that you
can execute the tests on.  You can then run whatever you want inside
that container with the current repository passed through like this:

  podman run -it --rm -v .:/repo -w /repo libnbd-fedora-rawhide bash

which will bind-mount the current directory onto /repo inside the
container and also use that path as the working directory (just so you
do not have to `cd /repo` before any commands.  I prefer running bash,
but of course you can just run the build script used in the CI.  I have
put all the CI build commands into one file for simplicity, so that you
can simply run `ci/build_script.sh`.  Executing that script will give
you the results and you can experiment right inside that environment to
figure out what is needed.  At the same time you can easily modify any
files inside that repository on your host, just like you are used to, so
that you can use your editor and other setups that work for you.  Just
make sure that build files do not interfere between the host and the
container, if you want to replicate a clean build you need to either use
VPATH or just clean everything.

Let me know what you think, and have a nice day.

Signed-off-by: Martin Kletzander <mkletzan at redhat.com>
---
 Makefile.am                                   |   1 +
 .gitlab-ci.yml                                | 479 ++++++++++++++++++
 ci/build_script.sh                            |  43 ++
 ci/cirrus/build.yml                           |  22 +
 ci/cirrus/freebsd-12.vars                     |  14 +
 ci/cirrus/freebsd-current.vars                |  14 +
 ci/cirrus/macos-11.vars                       |  14 +
 ci/cirrus/refresh                             |  22 +
 ci/containers/README.rst                      |  14 +
 ci/containers/centos-8.Dockerfile             |  61 +++
 ci/containers/centos-stream-8.Dockerfile      |  61 +++
 .../debian-10-cross-aarch64.Dockerfile        |  86 ++++
 .../debian-10-cross-armv6l.Dockerfile         |  86 ++++
 .../debian-10-cross-armv7l.Dockerfile         |  86 ++++
 ci/containers/debian-10-cross-i686.Dockerfile |  86 ++++
 ci/containers/debian-10-cross-mips.Dockerfile |  86 ++++
 .../debian-10-cross-mips64el.Dockerfile       |  86 ++++
 .../debian-10-cross-mipsel.Dockerfile         |  86 ++++
 .../debian-10-cross-ppc64le.Dockerfile        |  86 ++++
 .../debian-10-cross-s390x.Dockerfile          |  86 ++++
 ci/containers/debian-10.Dockerfile            |  64 +++
 .../debian-sid-cross-aarch64.Dockerfile       |  86 ++++
 .../debian-sid-cross-armv6l.Dockerfile        |  86 ++++
 .../debian-sid-cross-armv7l.Dockerfile        |  86 ++++
 .../debian-sid-cross-i686.Dockerfile          |  86 ++++
 .../debian-sid-cross-mips64el.Dockerfile      |  86 ++++
 .../debian-sid-cross-mipsel.Dockerfile        |  86 ++++
 .../debian-sid-cross-ppc64le.Dockerfile       |  86 ++++
 .../debian-sid-cross-s390x.Dockerfile         |  86 ++++
 ci/containers/debian-sid.Dockerfile           |  64 +++
 ci/containers/fedora-33.Dockerfile            |  68 +++
 ci/containers/fedora-34.Dockerfile            |  68 +++
 .../fedora-rawhide-cross-mingw32.Dockerfile   |  71 +++
 .../fedora-rawhide-cross-mingw64.Dockerfile   |  71 +++
 ci/containers/fedora-rawhide.Dockerfile       |  69 +++
 ci/containers/opensuse-leap-152.Dockerfile    |  56 ++
 ci/containers/opensuse-tumbleweed.Dockerfile  |  57 +++
 ci/containers/refresh                         |  42 ++
 ci/containers/ubuntu-1804.Dockerfile          |  62 +++
 ci/containers/ubuntu-2004.Dockerfile          |  64 +++
 40 files changed, 2963 insertions(+)
 create mode 100644 .gitlab-ci.yml
 create mode 100755 ci/build_script.sh
 create mode 100644 ci/cirrus/build.yml
 create mode 100644 ci/cirrus/freebsd-12.vars
 create mode 100644 ci/cirrus/freebsd-current.vars
 create mode 100644 ci/cirrus/macos-11.vars
 create mode 100755 ci/cirrus/refresh
 create mode 100644 ci/containers/README.rst
 create mode 100644 ci/containers/centos-8.Dockerfile
 create mode 100644 ci/containers/centos-stream-8.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-aarch64.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-armv6l.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-armv7l.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-i686.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-mips.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-mips64el.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-mipsel.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-ppc64le.Dockerfile
 create mode 100644 ci/containers/debian-10-cross-s390x.Dockerfile
 create mode 100644 ci/containers/debian-10.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-aarch64.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-armv6l.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-armv7l.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-i686.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-mips64el.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-mipsel.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-ppc64le.Dockerfile
 create mode 100644 ci/containers/debian-sid-cross-s390x.Dockerfile
 create mode 100644 ci/containers/debian-sid.Dockerfile
 create mode 100644 ci/containers/fedora-33.Dockerfile
 create mode 100644 ci/containers/fedora-34.Dockerfile
 create mode 100644 ci/containers/fedora-rawhide-cross-mingw32.Dockerfile
 create mode 100644 ci/containers/fedora-rawhide-cross-mingw64.Dockerfile
 create mode 100644 ci/containers/fedora-rawhide.Dockerfile
 create mode 100644 ci/containers/opensuse-leap-152.Dockerfile
 create mode 100644 ci/containers/opensuse-tumbleweed.Dockerfile
 create mode 100755 ci/containers/refresh
 create mode 100644 ci/containers/ubuntu-1804.Dockerfile
 create mode 100644 ci/containers/ubuntu-2004.Dockerfile

diff --git a/Makefile.am b/Makefile.am
index 8e5d42518e64..c98e3f0737e0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -62,6 +62,7 @@ maintainer-check-extra-dist:
 	@zcat $(PACKAGE_NAME)-$(VERSION).tar.gz | tar tf - | sort | \
 	    sed 's,^$(PACKAGE_NAME)-$(VERSION)/,,' > tarfiles
 	@git ls-files | \
+      grep -v -e '^\.gitlab-ci.yml' -e '^ci/' | \
 	    sort > gitfiles
 	@comm -13 tarfiles gitfiles > comm-out
 	@echo Checking for differences between EXTRA_DIST and git ...
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 000000000000..07d81ca779df
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,479 @@
+variables:
+  GIT_DEPTH: 100
+
+stages:
+  - containers
+  - builds
+
+.script_variables: &script_variables |
+  export MAKEFLAGS="-j $(getconf _NPROCESSORS_ONLN)"
+  export CCACHE_BASEDIR="$(pwd)"
+  export CCACHE_DIR="$CCACHE_BASEDIR/ccache"
+  export CCACHE_MAXSIZE="500M"
+  export PATH="$CCACHE_WRAPPERSDIR:$PATH"
+
+# Common templates
+
+.container_job:
+  image: docker:stable
+  stage: containers
+  needs: []
+  services:
+    - docker:dind
+  before_script:
+    - export TAG="$CI_REGISTRY_IMAGE/$NAME:latest"
+    - export COMMON_TAG="$CI_REGISTRY/nbdkit/libnbd/$NAME:latest"
+    - docker info
+    - docker login registry.gitlab.com -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD"
+  script:
+    - docker pull "$TAG" || docker pull "$COMMON_TAG" || true
+    - docker build --cache-from "$TAG" --cache-from "$COMMON_TAG" --tag "$TAG" -f "ci/containers/$NAME.Dockerfile" ci/containers
+    - docker push "$TAG"
+  after_script:
+    - docker logout
+
+.native_build_job:
+  stage: builds
+  image: $CI_REGISTRY_IMAGE/$NAME:latest
+  cache:
+    paths:
+      - ccache/
+    key: "$CI_JOB_NAME"
+  before_script:
+    - *script_variables
+  script:
+    - ci/build_script.sh
+
+# Jobs that we delegate to Cirrus CI because they require an operating
+# system other than Linux. These jobs will only run if the required
+# setup has been performed on the GitLab account (see ci/README.rst).
+#
+# The Cirrus CI configuration is generated by replacing target-specific
+# variables in a generic template: some of these variables are provided
+# when the GitLab CI job is defined, others are taken from a shell
+# snippet generated using lcitool.
+#
+# Note that the $PATH environment variable has to be treated with
+# special care, because we can't just override it at the GitLab CI job
+# definition level or we risk breaking it completely.
+.cirrus_build_job:
+  stage: builds
+  image: registry.gitlab.com/libvirt/libvirt-ci/cirrus-run:master
+  needs: []
+  script:
+    - source ci/cirrus/$NAME.vars
+    - sed -e "s|[@]CI_REPOSITORY_URL@|$CI_REPOSITORY_URL|g"
+          -e "s|[@]CI_COMMIT_REF_NAME@|$CI_COMMIT_REF_NAME|g"
+          -e "s|[@]CI_COMMIT_SHA@|$CI_COMMIT_SHA|g"
+          -e "s|[@]CIRRUS_VM_INSTANCE_TYPE@|$CIRRUS_VM_INSTANCE_TYPE|g"
+          -e "s|[@]CIRRUS_VM_IMAGE_SELECTOR@|$CIRRUS_VM_IMAGE_SELECTOR|g"
+          -e "s|[@]CIRRUS_VM_IMAGE_NAME@|$CIRRUS_VM_IMAGE_NAME|g"
+          -e "s|[@]UPDATE_COMMAND@|$UPDATE_COMMAND|g"
+          -e "s|[@]INSTALL_COMMAND@|$INSTALL_COMMAND|g"
+          -e "s|[@]PATH@|$PATH_EXTRA${PATH_EXTRA:+:}\$PATH|g"
+          -e "s|[@]PKG_CONFIG_PATH@|$PKG_CONFIG_PATH|g"
+          -e "s|[@]PKGS@|$PKGS|g"
+          -e "s|[@]MAKE@|$MAKE|g"
+          -e "s|[@]PYTHON@|$PYTHON|g"
+          -e "s|[@]PIP3@|$PIP3|g"
+          -e "s|[@]PYPI_PKGS@|$PYPI_PKGS|g"
+      <ci/cirrus/build.yml >ci/cirrus/$NAME.yml
+    - cat ci/cirrus/$NAME.yml
+    - cirrus-run -v --show-build-log always ci/cirrus/$NAME.yml
+  rules:
+    - if: "$CIRRUS_GITHUB_REPO && $CIRRUS_API_TOKEN"
+
+.cross_build_job:
+  stage: builds
+  image: $CI_REGISTRY_IMAGE/$NAME-cross-$CROSS:latest
+  cache:
+    paths:
+      - ccache/
+    key: "$CI_JOB_NAME"
+  before_script:
+    - *script_variables
+  script:
+    - ci/build_script.sh
+
+# Native container build jobs
+
+x64-centos-8-container:
+  extends: .container_job
+  variables:
+    NAME: centos-8
+
+x64-centos-stream-8-container:
+  extends: .container_job
+  variables:
+    NAME: centos-stream-8
+
+x64-debian-10-container:
+  extends: .container_job
+  variables:
+    NAME: debian-10
+
+x64-debian-sid-container:
+  extends: .container_job
+  variables:
+    NAME: debian-sid
+
+x64-fedora-33-container:
+  extends: .container_job
+  variables:
+    NAME: fedora-33
+
+x64-fedora-34-container:
+  extends: .container_job
+  variables:
+    NAME: fedora-34
+
+x64-fedora-rawhide-container:
+  extends: .container_job
+  variables:
+    NAME: fedora-rawhide
+
+x64-opensuse-leap-152-container:
+  extends: .container_job
+  variables:
+    NAME: opensuse-leap-152
+
+x64-opensuse-tumbleweed-container:
+  extends: .container_job
+  variables:
+    NAME: opensuse-tumbleweed
+
+x64-ubuntu-1804-container:
+  extends: .container_job
+  variables:
+    NAME: ubuntu-1804
+
+x64-ubuntu-2004-container:
+  extends: .container_job
+  variables:
+    NAME: ubuntu-2004
+
+
+# Cross-build containers build jobs
+
+aarch64-debian-10-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-10-cross-aarch64
+
+armv6l-debian-10-container:
+  extends: .container_job
+  variables:
+    NAME: debian-10-cross-armv6l
+
+armv7l-debian-10-container:
+  extends: .container_job
+  variables:
+    NAME: debian-10-cross-armv7l
+
+i686-debian-10-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-10-cross-i686
+
+mips-debian-10-container:
+  extends: .container_job
+  variables:
+    NAME: debian-10-cross-mips
+
+mips64el-debian-10-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-10-cross-mips64el
+
+mipsel-debian-10-container:
+  extends: .container_job
+  variables:
+    NAME: debian-10-cross-mipsel
+
+ppc64le-debian-10-container:
+  extends: .container_job
+  variables:
+    NAME: debian-10-cross-ppc64le
+
+s390x-debian-10-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-10-cross-s390x
+
+aarch64-debian-sid-container:
+  extends: .container_job
+  variables:
+    NAME: debian-sid-cross-aarch64
+
+armv6l-debian-sid-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-sid-cross-armv6l
+
+armv7l-debian-sid-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-sid-cross-armv7l
+
+i686-debian-sid-container:
+  extends: .container_job
+  variables:
+    NAME: debian-sid-cross-i686
+
+mips64el-debian-sid-container:
+  extends: .container_job
+  variables:
+    NAME: debian-sid-cross-mips64el
+
+mipsel-debian-sid-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-sid-cross-mipsel
+
+ppc64le-debian-sid-container:
+  extends: .container_job
+  allow_failure: true
+  variables:
+    NAME: debian-sid-cross-ppc64le
+
+s390x-debian-sid-container:
+  extends: .container_job
+  variables:
+    NAME: debian-sid-cross-s390x
+
+mingw32-fedora-rawhide-container:
+  extends: .container_job
+  variables:
+    NAME: fedora-rawhide-cross-mingw32
+
+mingw64-fedora-rawhide-container:
+  extends: .container_job
+  variables:
+    NAME: fedora-rawhide-cross-mingw64
+
+# Native architecture build + test jobs
+
+x64-debian-10:
+  extends: .native_build_job
+  needs:
+    - x64-debian-10-container
+  variables:
+    NAME: debian-10
+
+x64-debian-10-clang:
+  extends: .native_build_job
+  needs:
+    - x64-debian-10-container
+  variables:
+    NAME: debian-10
+    CC: clang
+
+x64-debian-sid:
+  extends: .native_build_job
+  needs:
+    - x64-debian-sid-container
+  variables:
+    NAME: debian-sid
+
+x64-centos-8:
+  extends: .native_build_job
+  needs:
+    - x64-centos-8-container
+  variables:
+    NAME: centos-8
+
+x64-centos-8-clang:
+  extends: .native_build_job
+  needs:
+    - x64-centos-8-container
+  variables:
+    NAME: centos-8
+    CC: clang
+
+x64-centos-stream-8:
+  extends: .native_build_job
+  needs:
+    - x64-centos-stream-8-container
+  variables:
+    NAME: centos-stream-8
+
+x64-fedora-33:
+  extends: .native_build_job
+  needs:
+    - x64-fedora-33-container
+  variables:
+    NAME: fedora-33
+
+x64-fedora-34:
+  extends: .native_build_job
+  needs:
+    - x64-fedora-34-container
+  variables:
+    NAME: fedora-34
+
+x64-fedora-rawhide:
+  extends: .native_build_job
+  needs:
+    - x64-fedora-rawhide-container
+  variables:
+    NAME: fedora-rawhide
+
+x64-fedora-rawhide-clang:
+  extends: .native_build_job
+  needs:
+    - x64-fedora-rawhide-container
+  variables:
+    NAME: fedora-rawhide
+    CC: clang
+
+x64-opensuse-leap-152:
+  extends: .native_build_job
+  needs:
+    - x64-opensuse-leap-152-container
+  variables:
+    NAME: opensuse-leap-152
+
+x64-opensuse-tumbleweed:
+  extends: .native_build_job
+  needs:
+    - x64-opensuse-tumbleweed-container
+  variables:
+    NAME: opensuse-tumbleweed
+
+x64-ubuntu-1804:
+  extends: .native_build_job
+  needs:
+    - x64-ubuntu-1804-container
+  variables:
+    NAME: ubuntu-1804
+    GOLANG: skip
+
+x64-ubuntu-2004:
+  extends: .native_build_job
+  needs:
+    - x64-ubuntu-2004-container
+  variables:
+    NAME: ubuntu-2004
+
+x64-freebsd-12-build:
+  extends: .cirrus_build_job
+  variables:
+    NAME: freebsd-12
+    CIRRUS_VM_INSTANCE_TYPE: freebsd_instance
+    CIRRUS_VM_IMAGE_SELECTOR: image_family
+    CIRRUS_VM_IMAGE_NAME: freebsd-12-2
+    UPDATE_COMMAND: pkg update
+    INSTALL_COMMAND: pkg install -y
+
+x64-macos-11-build:
+  extends: .cirrus_build_job
+  allow_failure: true
+  variables:
+    NAME: macos-11
+    CIRRUS_VM_INSTANCE_TYPE: osx_instance
+    CIRRUS_VM_IMAGE_SELECTOR: image
+    CIRRUS_VM_IMAGE_NAME: big-sur-base
+    UPDATE_COMMAND: brew update
+    INSTALL_COMMAND: brew install
+    PATH_EXTRA: /usr/local/opt/ccache/libexec:/usr/local/opt/gettext/bin:/usr/local/opt/libpcap/bin:/usr/local/opt/libxslt/bin:/usr/local/opt/rpcgen/bin
+    PKG_CONFIG_PATH: /usr/local/opt/curl/lib/pkgconfig:/usr/local/opt/libpcap/lib/pkgconfig:/usr/local/opt/libxml2/lib/pkgconfig:/usr/local/opt/ncurses/lib/pkgconfig:/usr/local/opt/readline/lib/pkgconfig
+
+
+# Cross compiled build jobs
+
+aarch64-debian-sid:
+  extends: .cross_build_job
+  needs:
+    - aarch64-debian-sid-container
+  variables:
+    NAME: debian-sid
+    CROSS: aarch64
+
+armv6l-debian-10:
+  extends: .cross_build_job
+  needs:
+    - armv6l-debian-10-container
+  variables:
+    NAME: debian-10
+    CROSS: armv6l
+
+armv7l-debian-10:
+  extends: .cross_build_job
+  needs:
+    - armv7l-debian-10-container
+  variables:
+    NAME: debian-10
+    CROSS: armv7l
+
+i686-debian-sid:
+  extends: .cross_build_job
+  needs:
+    - i686-debian-sid-container
+  variables:
+    NAME: debian-sid
+    CROSS: i686
+
+mips-debian-10:
+  extends: .cross_build_job
+  needs:
+    - mips-debian-10-container
+  variables:
+    NAME: debian-10
+    CROSS: mips
+
+mips64el-debian-sid:
+  extends: .cross_build_job
+  needs:
+    - mips64el-debian-sid-container
+  variables:
+    NAME: debian-sid
+    CROSS: mips64el
+
+mipsel-debian-10:
+  extends: .cross_build_job
+  needs:
+    - mipsel-debian-10-container
+  variables:
+    NAME: debian-10
+    CROSS: mipsel
+
+ppc64le-debian-10:
+  extends: .cross_build_job
+  needs:
+    - ppc64le-debian-10-container
+  variables:
+    NAME: debian-10
+    CROSS: ppc64le
+
+s390x-debian-sid:
+  extends: .cross_build_job
+  needs:
+    - s390x-debian-sid-container
+  variables:
+    NAME: debian-sid
+    CROSS: s390x
+
+mingw32-fedora-rawhide:
+  extends: .cross_build_job
+  allow_failure: true
+  needs:
+    - mingw32-fedora-rawhide-container
+  variables:
+    NAME: fedora-rawhide
+    CROSS: mingw32
+
+mingw64-fedora-rawhide:
+  extends: .cross_build_job
+  allow_failure: true
+  needs:
+    - mingw64-fedora-rawhide-container
+  variables:
+    NAME: fedora-rawhide
+    CROSS: mingw64
diff --git a/ci/build_script.sh b/ci/build_script.sh
new file mode 100755
index 000000000000..a27f80251cd0
--- /dev/null
+++ b/ci/build_script.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+set -e
+
+main() {
+    autoreconf -if
+
+    CONFIG_ARGS="--enable-gcc-warnings --enable-fuse --enable-ocaml --enable-python --enable-golang --with-gnutls --with-libxml2"
+
+    if test "$GOLANG" != "skip"
+    then
+       CONFIG_ARGS="$CONFIG_ARGS --enable-golang"
+    fi
+
+    ./configure $CONFIG_ARGS
+
+    $MAKE
+
+    if test -n "$CROSS"
+    then
+       return 0
+    fi
+
+    $MAKE check || { find . -name test-suite.log -exec grep -l '^X\?FAIL:' '{}' \+ | xargs cat; exit 1; }
+
+    if test "$CHECK_VALGRIND" = "force"
+    then
+        $MAKE check-valgrind
+    fi
+
+    if test "$DIST" != "skip"
+    then
+        $MAKE dist
+        $MAKE maintainer-check-extra-dist
+    fi
+
+    if test "$DISTCHECK" = "force"
+    then
+        $MAKE distcheck
+    fi
+}
+
+main "$@"
diff --git a/ci/cirrus/build.yml b/ci/cirrus/build.yml
new file mode 100644
index 000000000000..5a5c65e3b640
--- /dev/null
+++ b/ci/cirrus/build.yml
@@ -0,0 +1,22 @@
+ at CIRRUS_VM_INSTANCE_TYPE@:
+  @CIRRUS_VM_IMAGE_SELECTOR@: @CIRRUS_VM_IMAGE_NAME@
+
+env:
+  CI_REPOSITORY_URL: "@CI_REPOSITORY_URL@"
+  CI_COMMIT_REF_NAME: "@CI_COMMIT_REF_NAME@"
+  CI_COMMIT_SHA: "@CI_COMMIT_SHA@"
+  PATH: "@PATH@"
+  PKG_CONFIG_PATH: "@PKG_CONFIG_PATH@"
+  PYTHON: "@PYTHON@"
+  MAKE: "@MAKE@"
+
+build_task:
+  install_script:
+    - @INSTALL_COMMAND@ @PKGS@
+    - if test -n "@PYPI_PKGS@" ; then @PIP3@ install @PYPI_PKGS@ ; fi
+  clone_script:
+    - git clone --depth 100 "$CI_REPOSITORY_URL" .
+    - git fetch origin "$CI_COMMIT_REF_NAME"
+    - git reset --hard "$CI_COMMIT_SHA"
+  build_script:
+    - ci/build_script.sh
diff --git a/ci/cirrus/freebsd-12.vars b/ci/cirrus/freebsd-12.vars
new file mode 100644
index 000000000000..4e7f653a859c
--- /dev/null
+++ b/ci/cirrus/freebsd-12.vars
@@ -0,0 +1,14 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool variables freebsd-12 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/ea3fb1a9a5976a2c70b85e4621dcefefaf1b53f2
+
+PACKAGING_COMMAND='pkg'
+CC='/usr/bin/clang'
+CCACHE='/usr/local/bin/ccache'
+MAKE='/usr/local/bin/gmake'
+NINJA='/usr/local/bin/ninja'
+PYTHON='/usr/local/bin/python3'
+PIP3='/usr/local/bin/pip-3.7'
+PKGS='autoconf automake bash-completion ca_root_nss ccache coreutils diffutils fusefs-libs git glib gmake gnutls go gsed libev libtool libxml2 nbdkit ocaml ocaml-findlib perl5 pkgconf python3 qemu'
diff --git a/ci/cirrus/freebsd-current.vars b/ci/cirrus/freebsd-current.vars
new file mode 100644
index 000000000000..dfdf58e8616b
--- /dev/null
+++ b/ci/cirrus/freebsd-current.vars
@@ -0,0 +1,14 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool variables freebsd-current libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/ea3fb1a9a5976a2c70b85e4621dcefefaf1b53f2
+
+PACKAGING_COMMAND='pkg'
+CC='/usr/bin/clang'
+CCACHE='/usr/local/bin/ccache'
+MAKE='/usr/local/bin/gmake'
+NINJA='/usr/local/bin/ninja'
+PYTHON='/usr/local/bin/python3'
+PIP3='/usr/local/bin/pip-3.7'
+PKGS='autoconf automake bash-completion ca_root_nss ccache coreutils diffutils fusefs-libs git glib gmake gnutls go gsed libev libtool libxml2 nbdkit ocaml ocaml-findlib perl5 pkgconf python3 qemu'
diff --git a/ci/cirrus/macos-11.vars b/ci/cirrus/macos-11.vars
new file mode 100644
index 000000000000..413a203782eb
--- /dev/null
+++ b/ci/cirrus/macos-11.vars
@@ -0,0 +1,14 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool variables macos-11 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/ea3fb1a9a5976a2c70b85e4621dcefefaf1b53f2
+
+PACKAGING_COMMAND='brew'
+CC='/usr/bin/clang'
+CCACHE='/usr/local/bin/ccache'
+MAKE='/usr/local/bin/gmake'
+NINJA='/usr/local/bin/ninja'
+PYTHON='/usr/local/bin/python3'
+PIP3='/usr/local/bin/pip3'
+PKGS='autoconf automake bash-completion ccache coreutils diffutils git glib gnu-sed gnutls golang libev libtool libxml2 make ocaml ocaml-findlib perl pkg-config python3 qemu'
diff --git a/ci/cirrus/refresh b/ci/cirrus/refresh
new file mode 100755
index 000000000000..459cd80d0934
--- /dev/null
+++ b/ci/cirrus/refresh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+if test -z "$1"
+then
+    echo "syntax: $0 PATH-TO-LCITOOL"
+    exit 1
+fi
+
+LCITOOL=$1
+
+if ! test -x "$LCITOOL"
+then
+    echo "$LCITOOL is not executable"
+    exit 1
+fi
+
+HOSTS=$($LCITOOL hosts | grep -E 'freebsd|macos')
+
+for host in $HOSTS
+do
+    $LCITOOL variables "$host" libnbd >"$host.vars"
+done
diff --git a/ci/containers/README.rst b/ci/containers/README.rst
new file mode 100644
index 000000000000..530897e311f5
--- /dev/null
+++ b/ci/containers/README.rst
@@ -0,0 +1,14 @@
+CI job assets
+=============
+
+This directory contains assets used in the automated CI jobs, most
+notably the Dockerfiles used to build container images in which the
+CI jobs then run.
+
+The ``refresh`` script is used to re-create the Dockerfiles using the
+``lcitool`` command that is provided by repo
+https://gitlab.com/libvirt/libvirt-ci
+
+The containers are built during the CI process and cached in the GitLab
+container registry of the project doing the build. The cached containers
+can be deleted at any time and will be correctly rebuilt.
diff --git a/ci/containers/centos-8.Dockerfile b/ci/containers/centos-8.Dockerfile
new file mode 100644
index 000000000000..867f0507d172
--- /dev/null
+++ b/ci/containers/centos-8.Dockerfile
@@ -0,0 +1,61 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile centos-8 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/centos:8
+
+RUN dnf update -y && \
+    dnf install 'dnf-command(config-manager)' -y && \
+    dnf config-manager --set-enabled -y powertools && \
+    dnf install -y centos-release-advanced-virtualization && \
+    dnf install -y epel-release && \
+    dnf install -y \
+        autoconf \
+        automake \
+        bash-completion \
+        ca-certificates \
+        ccache \
+        clang \
+        coreutils-single \
+        diffutils \
+        fuse3-devel \
+        gcc \
+        gcc-c++ \
+        git \
+        glib2-devel \
+        glibc-devel \
+        glibc-langpack-en \
+        gnutls \
+        gnutls-devel \
+        golang \
+        iproute \
+        jq \
+        libev-devel \
+        libtool \
+        libxml2-devel \
+        make \
+        nbdkit \
+        ocaml \
+        ocaml-findlib \
+        perl \
+        pkgconfig \
+        python3-devel \
+        python3-flake8 \
+        qemu-img \
+        qemu-kvm \
+        sed && \
+    dnf autoremove -y && \
+    dnf clean all -y && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/centos-stream-8.Dockerfile b/ci/containers/centos-stream-8.Dockerfile
new file mode 100644
index 000000000000..f210948ffd40
--- /dev/null
+++ b/ci/containers/centos-stream-8.Dockerfile
@@ -0,0 +1,61 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile centos-stream-8 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM quay.io/centos/centos:stream8
+
+RUN dnf update -y && \
+    dnf install 'dnf-command(config-manager)' -y && \
+    dnf config-manager --set-enabled -y powertools && \
+    dnf install -y centos-release-advanced-virtualization && \
+    dnf install -y epel-release && \
+    dnf install -y \
+        autoconf \
+        automake \
+        bash-completion \
+        ca-certificates \
+        ccache \
+        clang \
+        coreutils-single \
+        diffutils \
+        fuse3-devel \
+        gcc \
+        gcc-c++ \
+        git \
+        glib2-devel \
+        glibc-devel \
+        glibc-langpack-en \
+        gnutls \
+        gnutls-devel \
+        golang \
+        iproute \
+        jq \
+        libev-devel \
+        libtool \
+        libxml2-devel \
+        make \
+        nbdkit \
+        ocaml \
+        ocaml-findlib \
+        perl \
+        pkgconfig \
+        python3-devel \
+        python3-flake8 \
+        qemu-img \
+        qemu-kvm \
+        sed && \
+    dnf autoremove -y && \
+    dnf clean all -y && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/debian-10-cross-aarch64.Dockerfile b/ci/containers/debian-10-cross-aarch64.Dockerfile
new file mode 100644
index 000000000000..cc765f32fd1c
--- /dev/null
+++ b/ci/containers/debian-10-cross-aarch64.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross aarch64 debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture arm64 && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-aarch64-linux-gnu \
+            gcc-aarch64-linux-gnu \
+            libc6-dev:arm64 \
+            libev-dev:arm64 \
+            libfuse3-dev:arm64 \
+            libglib2.0-dev:arm64 \
+            libgnutls28-dev:arm64 \
+            libxml2-dev:arm64 && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/aarch64-linux-gnu-gcc'\n\
+ar = '/usr/bin/aarch64-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/aarch64-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/aarch64-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'aarch64'\n\
+cpu = 'aarch64'\n\
+endian = 'little'" > /usr/local/share/meson/cross/aarch64-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "aarch64-linux-gnu"
+ENV CONFIGURE_OPTS "--host=aarch64-linux-gnu"
diff --git a/ci/containers/debian-10-cross-armv6l.Dockerfile b/ci/containers/debian-10-cross-armv6l.Dockerfile
new file mode 100644
index 000000000000..200d0277cc44
--- /dev/null
+++ b/ci/containers/debian-10-cross-armv6l.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross armv6l debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture armel && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-arm-linux-gnueabi \
+            gcc-arm-linux-gnueabi \
+            libc6-dev:armel \
+            libev-dev:armel \
+            libfuse3-dev:armel \
+            libglib2.0-dev:armel \
+            libgnutls28-dev:armel \
+            libxml2-dev:armel && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/arm-linux-gnueabi-gcc'\n\
+ar = '/usr/bin/arm-linux-gnueabi-gcc-ar'\n\
+strip = '/usr/bin/arm-linux-gnueabi-strip'\n\
+pkgconfig = '/usr/bin/arm-linux-gnueabi-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'arm'\n\
+cpu = 'arm'\n\
+endian = 'little'" > /usr/local/share/meson/cross/arm-linux-gnueabi
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "arm-linux-gnueabi"
+ENV CONFIGURE_OPTS "--host=arm-linux-gnueabi"
diff --git a/ci/containers/debian-10-cross-armv7l.Dockerfile b/ci/containers/debian-10-cross-armv7l.Dockerfile
new file mode 100644
index 000000000000..71bab34202df
--- /dev/null
+++ b/ci/containers/debian-10-cross-armv7l.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross armv7l debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture armhf && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-arm-linux-gnueabihf \
+            gcc-arm-linux-gnueabihf \
+            libc6-dev:armhf \
+            libev-dev:armhf \
+            libfuse3-dev:armhf \
+            libglib2.0-dev:armhf \
+            libgnutls28-dev:armhf \
+            libxml2-dev:armhf && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/arm-linux-gnueabihf-gcc'\n\
+ar = '/usr/bin/arm-linux-gnueabihf-gcc-ar'\n\
+strip = '/usr/bin/arm-linux-gnueabihf-strip'\n\
+pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'arm'\n\
+cpu = 'armhf'\n\
+endian = 'little'" > /usr/local/share/meson/cross/arm-linux-gnueabihf
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "arm-linux-gnueabihf"
+ENV CONFIGURE_OPTS "--host=arm-linux-gnueabihf"
diff --git a/ci/containers/debian-10-cross-i686.Dockerfile b/ci/containers/debian-10-cross-i686.Dockerfile
new file mode 100644
index 000000000000..21f687fa6d4b
--- /dev/null
+++ b/ci/containers/debian-10-cross-i686.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross i686 debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture i386 && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-i686-linux-gnu \
+            gcc-i686-linux-gnu \
+            libc6-dev:i386 \
+            libev-dev:i386 \
+            libfuse3-dev:i386 \
+            libglib2.0-dev:i386 \
+            libgnutls28-dev:i386 \
+            libxml2-dev:i386 && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/i686-linux-gnu-gcc'\n\
+ar = '/usr/bin/i686-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/i686-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/i686-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'x86'\n\
+cpu = 'i686'\n\
+endian = 'little'" > /usr/local/share/meson/cross/i686-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "i686-linux-gnu"
+ENV CONFIGURE_OPTS "--host=i686-linux-gnu"
diff --git a/ci/containers/debian-10-cross-mips.Dockerfile b/ci/containers/debian-10-cross-mips.Dockerfile
new file mode 100644
index 000000000000..dd82c077411b
--- /dev/null
+++ b/ci/containers/debian-10-cross-mips.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross mips debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture mips && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-mips-linux-gnu \
+            gcc-mips-linux-gnu \
+            libc6-dev:mips \
+            libev-dev:mips \
+            libfuse3-dev:mips \
+            libglib2.0-dev:mips \
+            libgnutls28-dev:mips \
+            libxml2-dev:mips && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/mips-linux-gnu-gcc'\n\
+ar = '/usr/bin/mips-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/mips-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/mips-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'mips'\n\
+cpu = 'mips'\n\
+endian = 'big'" > /usr/local/share/meson/cross/mips-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "mips-linux-gnu"
+ENV CONFIGURE_OPTS "--host=mips-linux-gnu"
diff --git a/ci/containers/debian-10-cross-mips64el.Dockerfile b/ci/containers/debian-10-cross-mips64el.Dockerfile
new file mode 100644
index 000000000000..31d0768c4b0c
--- /dev/null
+++ b/ci/containers/debian-10-cross-mips64el.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross mips64el debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture mips64el && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-mips64el-linux-gnuabi64 \
+            gcc-mips64el-linux-gnuabi64 \
+            libc6-dev:mips64el \
+            libev-dev:mips64el \
+            libfuse3-dev:mips64el \
+            libglib2.0-dev:mips64el \
+            libgnutls28-dev:mips64el \
+            libxml2-dev:mips64el && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/mips64el-linux-gnuabi64-gcc'\n\
+ar = '/usr/bin/mips64el-linux-gnuabi64-gcc-ar'\n\
+strip = '/usr/bin/mips64el-linux-gnuabi64-strip'\n\
+pkgconfig = '/usr/bin/mips64el-linux-gnuabi64-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'mips64'\n\
+cpu = 'mips64el'\n\
+endian = 'little'" > /usr/local/share/meson/cross/mips64el-linux-gnuabi64
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "mips64el-linux-gnuabi64"
+ENV CONFIGURE_OPTS "--host=mips64el-linux-gnuabi64"
diff --git a/ci/containers/debian-10-cross-mipsel.Dockerfile b/ci/containers/debian-10-cross-mipsel.Dockerfile
new file mode 100644
index 000000000000..45dd872e7056
--- /dev/null
+++ b/ci/containers/debian-10-cross-mipsel.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross mipsel debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture mipsel && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-mipsel-linux-gnu \
+            gcc-mipsel-linux-gnu \
+            libc6-dev:mipsel \
+            libev-dev:mipsel \
+            libfuse3-dev:mipsel \
+            libglib2.0-dev:mipsel \
+            libgnutls28-dev:mipsel \
+            libxml2-dev:mipsel && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/mipsel-linux-gnu-gcc'\n\
+ar = '/usr/bin/mipsel-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/mipsel-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/mipsel-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'mips'\n\
+cpu = 'mipsel'\n\
+endian = 'little'" > /usr/local/share/meson/cross/mipsel-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "mipsel-linux-gnu"
+ENV CONFIGURE_OPTS "--host=mipsel-linux-gnu"
diff --git a/ci/containers/debian-10-cross-ppc64le.Dockerfile b/ci/containers/debian-10-cross-ppc64le.Dockerfile
new file mode 100644
index 000000000000..391d3c69ac49
--- /dev/null
+++ b/ci/containers/debian-10-cross-ppc64le.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross ppc64le debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture ppc64el && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-powerpc64le-linux-gnu \
+            gcc-powerpc64le-linux-gnu \
+            libc6-dev:ppc64el \
+            libev-dev:ppc64el \
+            libfuse3-dev:ppc64el \
+            libglib2.0-dev:ppc64el \
+            libgnutls28-dev:ppc64el \
+            libxml2-dev:ppc64el && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/powerpc64le-linux-gnu-gcc'\n\
+ar = '/usr/bin/powerpc64le-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/powerpc64le-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/powerpc64le-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'ppc64'\n\
+cpu = 'powerpc64le'\n\
+endian = 'little'" > /usr/local/share/meson/cross/powerpc64le-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "powerpc64le-linux-gnu"
+ENV CONFIGURE_OPTS "--host=powerpc64le-linux-gnu"
diff --git a/ci/containers/debian-10-cross-s390x.Dockerfile b/ci/containers/debian-10-cross-s390x.Dockerfile
new file mode 100644
index 000000000000..b11bc509fd2c
--- /dev/null
+++ b/ci/containers/debian-10-cross-s390x.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross s390x debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture s390x && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-s390x-linux-gnu \
+            gcc-s390x-linux-gnu \
+            libc6-dev:s390x \
+            libev-dev:s390x \
+            libfuse3-dev:s390x \
+            libglib2.0-dev:s390x \
+            libgnutls28-dev:s390x \
+            libxml2-dev:s390x && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/s390x-linux-gnu-gcc'\n\
+ar = '/usr/bin/s390x-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/s390x-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/s390x-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 's390x'\n\
+cpu = 's390x'\n\
+endian = 'big'" > /usr/local/share/meson/cross/s390x-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "s390x-linux-gnu"
+ENV CONFIGURE_OPTS "--host=s390x-linux-gnu"
diff --git a/ci/containers/debian-10.Dockerfile b/ci/containers/debian-10.Dockerfile
new file mode 100644
index 000000000000..649c64adc46b
--- /dev/null
+++ b/ci/containers/debian-10.Dockerfile
@@ -0,0 +1,64 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile debian-10 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:10-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            clang \
+            coreutils \
+            diffutils \
+            flake8 \
+            g++ \
+            gcc \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libc6-dev \
+            libev-dev \
+            libfuse3-dev \
+            libglib2.0-dev \
+            libgnutls28-dev \
+            libtool-bin \
+            libxml2-dev \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/debian-sid-cross-aarch64.Dockerfile b/ci/containers/debian-sid-cross-aarch64.Dockerfile
new file mode 100644
index 000000000000..f9afd0eb16ed
--- /dev/null
+++ b/ci/containers/debian-sid-cross-aarch64.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross aarch64 debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/aarch64-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture arm64 && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-aarch64-linux-gnu \
+            gcc-aarch64-linux-gnu \
+            libc6-dev:arm64 \
+            libev-dev:arm64 \
+            libfuse3-dev:arm64 \
+            libglib2.0-dev:arm64 \
+            libgnutls28-dev:arm64 \
+            libxml2-dev:arm64 && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/aarch64-linux-gnu-gcc'\n\
+ar = '/usr/bin/aarch64-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/aarch64-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/aarch64-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'aarch64'\n\
+cpu = 'aarch64'\n\
+endian = 'little'" > /usr/local/share/meson/cross/aarch64-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "aarch64-linux-gnu"
+ENV CONFIGURE_OPTS "--host=aarch64-linux-gnu"
diff --git a/ci/containers/debian-sid-cross-armv6l.Dockerfile b/ci/containers/debian-sid-cross-armv6l.Dockerfile
new file mode 100644
index 000000000000..d637036b0444
--- /dev/null
+++ b/ci/containers/debian-sid-cross-armv6l.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross armv6l debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabi-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture armel && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-arm-linux-gnueabi \
+            gcc-arm-linux-gnueabi \
+            libc6-dev:armel \
+            libev-dev:armel \
+            libfuse3-dev:armel \
+            libglib2.0-dev:armel \
+            libgnutls28-dev:armel \
+            libxml2-dev:armel && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/arm-linux-gnueabi-gcc'\n\
+ar = '/usr/bin/arm-linux-gnueabi-gcc-ar'\n\
+strip = '/usr/bin/arm-linux-gnueabi-strip'\n\
+pkgconfig = '/usr/bin/arm-linux-gnueabi-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'arm'\n\
+cpu = 'arm'\n\
+endian = 'little'" > /usr/local/share/meson/cross/arm-linux-gnueabi
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "arm-linux-gnueabi"
+ENV CONFIGURE_OPTS "--host=arm-linux-gnueabi"
diff --git a/ci/containers/debian-sid-cross-armv7l.Dockerfile b/ci/containers/debian-sid-cross-armv7l.Dockerfile
new file mode 100644
index 000000000000..6934b32f1eba
--- /dev/null
+++ b/ci/containers/debian-sid-cross-armv7l.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross armv7l debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/arm-linux-gnueabihf-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture armhf && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-arm-linux-gnueabihf \
+            gcc-arm-linux-gnueabihf \
+            libc6-dev:armhf \
+            libev-dev:armhf \
+            libfuse3-dev:armhf \
+            libglib2.0-dev:armhf \
+            libgnutls28-dev:armhf \
+            libxml2-dev:armhf && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/arm-linux-gnueabihf-gcc'\n\
+ar = '/usr/bin/arm-linux-gnueabihf-gcc-ar'\n\
+strip = '/usr/bin/arm-linux-gnueabihf-strip'\n\
+pkgconfig = '/usr/bin/arm-linux-gnueabihf-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'arm'\n\
+cpu = 'armhf'\n\
+endian = 'little'" > /usr/local/share/meson/cross/arm-linux-gnueabihf
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "arm-linux-gnueabihf"
+ENV CONFIGURE_OPTS "--host=arm-linux-gnueabihf"
diff --git a/ci/containers/debian-sid-cross-i686.Dockerfile b/ci/containers/debian-sid-cross-i686.Dockerfile
new file mode 100644
index 000000000000..01bd3b48bc02
--- /dev/null
+++ b/ci/containers/debian-sid-cross-i686.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross i686 debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture i386 && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-i686-linux-gnu \
+            gcc-i686-linux-gnu \
+            libc6-dev:i386 \
+            libev-dev:i386 \
+            libfuse3-dev:i386 \
+            libglib2.0-dev:i386 \
+            libgnutls28-dev:i386 \
+            libxml2-dev:i386 && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/i686-linux-gnu-gcc'\n\
+ar = '/usr/bin/i686-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/i686-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/i686-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'x86'\n\
+cpu = 'i686'\n\
+endian = 'little'" > /usr/local/share/meson/cross/i686-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "i686-linux-gnu"
+ENV CONFIGURE_OPTS "--host=i686-linux-gnu"
diff --git a/ci/containers/debian-sid-cross-mips64el.Dockerfile b/ci/containers/debian-sid-cross-mips64el.Dockerfile
new file mode 100644
index 000000000000..7c3057503b60
--- /dev/null
+++ b/ci/containers/debian-sid-cross-mips64el.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross mips64el debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mips64el-linux-gnuabi64-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture mips64el && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-mips64el-linux-gnuabi64 \
+            gcc-mips64el-linux-gnuabi64 \
+            libc6-dev:mips64el \
+            libev-dev:mips64el \
+            libfuse3-dev:mips64el \
+            libglib2.0-dev:mips64el \
+            libgnutls28-dev:mips64el \
+            libxml2-dev:mips64el && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/mips64el-linux-gnuabi64-gcc'\n\
+ar = '/usr/bin/mips64el-linux-gnuabi64-gcc-ar'\n\
+strip = '/usr/bin/mips64el-linux-gnuabi64-strip'\n\
+pkgconfig = '/usr/bin/mips64el-linux-gnuabi64-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'mips64'\n\
+cpu = 'mips64el'\n\
+endian = 'little'" > /usr/local/share/meson/cross/mips64el-linux-gnuabi64
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "mips64el-linux-gnuabi64"
+ENV CONFIGURE_OPTS "--host=mips64el-linux-gnuabi64"
diff --git a/ci/containers/debian-sid-cross-mipsel.Dockerfile b/ci/containers/debian-sid-cross-mipsel.Dockerfile
new file mode 100644
index 000000000000..813059edfafe
--- /dev/null
+++ b/ci/containers/debian-sid-cross-mipsel.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross mipsel debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/mipsel-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture mipsel && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-mipsel-linux-gnu \
+            gcc-mipsel-linux-gnu \
+            libc6-dev:mipsel \
+            libev-dev:mipsel \
+            libfuse3-dev:mipsel \
+            libglib2.0-dev:mipsel \
+            libgnutls28-dev:mipsel \
+            libxml2-dev:mipsel && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/mipsel-linux-gnu-gcc'\n\
+ar = '/usr/bin/mipsel-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/mipsel-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/mipsel-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'mips'\n\
+cpu = 'mipsel'\n\
+endian = 'little'" > /usr/local/share/meson/cross/mipsel-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "mipsel-linux-gnu"
+ENV CONFIGURE_OPTS "--host=mipsel-linux-gnu"
diff --git a/ci/containers/debian-sid-cross-ppc64le.Dockerfile b/ci/containers/debian-sid-cross-ppc64le.Dockerfile
new file mode 100644
index 000000000000..b8715dc4809f
--- /dev/null
+++ b/ci/containers/debian-sid-cross-ppc64le.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross ppc64le debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/powerpc64le-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture ppc64el && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-powerpc64le-linux-gnu \
+            gcc-powerpc64le-linux-gnu \
+            libc6-dev:ppc64el \
+            libev-dev:ppc64el \
+            libfuse3-dev:ppc64el \
+            libglib2.0-dev:ppc64el \
+            libgnutls28-dev:ppc64el \
+            libxml2-dev:ppc64el && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/powerpc64le-linux-gnu-gcc'\n\
+ar = '/usr/bin/powerpc64le-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/powerpc64le-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/powerpc64le-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 'ppc64'\n\
+cpu = 'powerpc64le'\n\
+endian = 'little'" > /usr/local/share/meson/cross/powerpc64le-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "powerpc64le-linux-gnu"
+ENV CONFIGURE_OPTS "--host=powerpc64le-linux-gnu"
diff --git a/ci/containers/debian-sid-cross-s390x.Dockerfile b/ci/containers/debian-sid-cross-s390x.Dockerfile
new file mode 100644
index 000000000000..7fcc77758e65
--- /dev/null
+++ b/ci/containers/debian-sid-cross-s390x.Dockerfile
@@ -0,0 +1,86 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross s390x debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            coreutils \
+            diffutils \
+            flake8 \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libtool-bin \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/s390x-linux-gnu-gcc
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    dpkg --add-architecture s390x && \
+    eatmydata apt-get update && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
+    eatmydata apt-get install --no-install-recommends -y \
+            g++-s390x-linux-gnu \
+            gcc-s390x-linux-gnu \
+            libc6-dev:s390x \
+            libev-dev:s390x \
+            libfuse3-dev:s390x \
+            libglib2.0-dev:s390x \
+            libgnutls28-dev:s390x \
+            libxml2-dev:s390x && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    mkdir -p /usr/local/share/meson/cross && \
+    echo "[binaries]\n\
+c = '/usr/bin/s390x-linux-gnu-gcc'\n\
+ar = '/usr/bin/s390x-linux-gnu-gcc-ar'\n\
+strip = '/usr/bin/s390x-linux-gnu-strip'\n\
+pkgconfig = '/usr/bin/s390x-linux-gnu-pkg-config'\n\
+\n\
+[host_machine]\n\
+system = 'linux'\n\
+cpu_family = 's390x'\n\
+cpu = 's390x'\n\
+endian = 'big'" > /usr/local/share/meson/cross/s390x-linux-gnu
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "s390x-linux-gnu"
+ENV CONFIGURE_OPTS "--host=s390x-linux-gnu"
diff --git a/ci/containers/debian-sid.Dockerfile b/ci/containers/debian-sid.Dockerfile
new file mode 100644
index 000000000000..c5257651016d
--- /dev/null
+++ b/ci/containers/debian-sid.Dockerfile
@@ -0,0 +1,64 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile debian-sid libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/debian:sid-slim
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            clang \
+            coreutils \
+            diffutils \
+            flake8 \
+            g++ \
+            gcc \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libc6-dev \
+            libev-dev \
+            libfuse3-dev \
+            libglib2.0-dev \
+            libgnutls28-dev \
+            libtool-bin \
+            libxml2-dev \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/fedora-33.Dockerfile b/ci/containers/fedora-33.Dockerfile
new file mode 100644
index 000000000000..c25eb91e5276
--- /dev/null
+++ b/ci/containers/fedora-33.Dockerfile
@@ -0,0 +1,68 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile fedora-33 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM registry.fedoraproject.org/fedora:33
+
+RUN dnf install -y nosync && \
+    echo -e '#!/bin/sh\n\
+if test -d /usr/lib64\n\
+then\n\
+    export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\
+else\n\
+    export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\
+fi\n\
+exec "$@"' > /usr/bin/nosync && \
+    chmod +x /usr/bin/nosync && \
+    nosync dnf update -y && \
+    nosync dnf install -y \
+        autoconf \
+        automake \
+        bash-completion \
+        ca-certificates \
+        ccache \
+        clang \
+        coreutils \
+        diffutils \
+        fuse3-devel \
+        gcc \
+        gcc-c++ \
+        git \
+        glib2-devel \
+        glibc-devel \
+        glibc-langpack-en \
+        gnutls \
+        gnutls-devel \
+        golang \
+        iproute \
+        jq \
+        libev-devel \
+        libtool \
+        libxml2-devel \
+        make \
+        nbd \
+        nbdkit \
+        ocaml \
+        ocaml-findlib \
+        perl-base \
+        pkgconfig \
+        python3-devel \
+        python3-flake8 \
+        qemu-img \
+        qemu-kvm \
+        sed && \
+    nosync dnf autoremove -y && \
+    nosync dnf clean all -y && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/fedora-34.Dockerfile b/ci/containers/fedora-34.Dockerfile
new file mode 100644
index 000000000000..d5e1d46156bd
--- /dev/null
+++ b/ci/containers/fedora-34.Dockerfile
@@ -0,0 +1,68 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile fedora-34 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM registry.fedoraproject.org/fedora:34
+
+RUN dnf install -y nosync && \
+    echo -e '#!/bin/sh\n\
+if test -d /usr/lib64\n\
+then\n\
+    export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\
+else\n\
+    export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\
+fi\n\
+exec "$@"' > /usr/bin/nosync && \
+    chmod +x /usr/bin/nosync && \
+    nosync dnf update -y && \
+    nosync dnf install -y \
+        autoconf \
+        automake \
+        bash-completion \
+        ca-certificates \
+        ccache \
+        clang \
+        coreutils \
+        diffutils \
+        fuse3-devel \
+        gcc \
+        gcc-c++ \
+        git \
+        glib2-devel \
+        glibc-devel \
+        glibc-langpack-en \
+        gnutls \
+        gnutls-devel \
+        golang \
+        iproute \
+        jq \
+        libev-devel \
+        libtool \
+        libxml2-devel \
+        make \
+        nbd \
+        nbdkit \
+        ocaml \
+        ocaml-findlib \
+        perl-base \
+        pkgconfig \
+        python3-devel \
+        python3-flake8 \
+        qemu-img \
+        qemu-kvm \
+        sed && \
+    nosync dnf autoremove -y && \
+    nosync dnf clean all -y && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/fedora-rawhide-cross-mingw32.Dockerfile b/ci/containers/fedora-rawhide-cross-mingw32.Dockerfile
new file mode 100644
index 000000000000..a7f1f95ac4d6
--- /dev/null
+++ b/ci/containers/fedora-rawhide-cross-mingw32.Dockerfile
@@ -0,0 +1,71 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross mingw32 fedora-rawhide libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM registry.fedoraproject.org/fedora:rawhide
+
+RUN dnf update -y --nogpgcheck fedora-gpg-keys && \
+    dnf install -y nosync && \
+    echo -e '#!/bin/sh\n\
+if test -d /usr/lib64\n\
+then\n\
+    export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\
+else\n\
+    export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\
+fi\n\
+exec "$@"' > /usr/bin/nosync && \
+    chmod +x /usr/bin/nosync && \
+    nosync dnf update -y && \
+    nosync dnf install -y \
+        autoconf \
+        automake \
+        bash-completion \
+        ca-certificates \
+        ccache \
+        coreutils \
+        diffutils \
+        git \
+        glibc-langpack-en \
+        gnutls \
+        golang \
+        iproute \
+        jq \
+        libtool \
+        make \
+        nbd \
+        nbdkit \
+        ocaml \
+        ocaml-findlib \
+        perl-base \
+        python3-devel \
+        python3-flake8 \
+        qemu-img \
+        qemu-kvm \
+        sed && \
+    nosync dnf autoremove -y && \
+    nosync dnf clean all -y && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/i686-w64-mingw32-gcc
+
+RUN nosync dnf install -y \
+        mingw32-gcc \
+        mingw32-gcc-c++ \
+        mingw32-glib2 \
+        mingw32-gnutls \
+        mingw32-headers \
+        mingw32-libxml2 \
+        mingw32-pkg-config && \
+    nosync dnf clean all -y
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "i686-w64-mingw32"
+ENV CONFIGURE_OPTS "--host=i686-w64-mingw32"
diff --git a/ci/containers/fedora-rawhide-cross-mingw64.Dockerfile b/ci/containers/fedora-rawhide-cross-mingw64.Dockerfile
new file mode 100644
index 000000000000..549ed3558bb4
--- /dev/null
+++ b/ci/containers/fedora-rawhide-cross-mingw64.Dockerfile
@@ -0,0 +1,71 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile --cross mingw64 fedora-rawhide libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM registry.fedoraproject.org/fedora:rawhide
+
+RUN dnf update -y --nogpgcheck fedora-gpg-keys && \
+    dnf install -y nosync && \
+    echo -e '#!/bin/sh\n\
+if test -d /usr/lib64\n\
+then\n\
+    export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\
+else\n\
+    export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\
+fi\n\
+exec "$@"' > /usr/bin/nosync && \
+    chmod +x /usr/bin/nosync && \
+    nosync dnf update -y && \
+    nosync dnf install -y \
+        autoconf \
+        automake \
+        bash-completion \
+        ca-certificates \
+        ccache \
+        coreutils \
+        diffutils \
+        git \
+        glibc-langpack-en \
+        gnutls \
+        golang \
+        iproute \
+        jq \
+        libtool \
+        make \
+        nbd \
+        nbdkit \
+        ocaml \
+        ocaml-findlib \
+        perl-base \
+        python3-devel \
+        python3-flake8 \
+        qemu-img \
+        qemu-kvm \
+        sed && \
+    nosync dnf autoremove -y && \
+    nosync dnf clean all -y && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/x86_64-w64-mingw32-gcc
+
+RUN nosync dnf install -y \
+        mingw64-gcc \
+        mingw64-gcc-c++ \
+        mingw64-glib2 \
+        mingw64-gnutls \
+        mingw64-headers \
+        mingw64-libxml2 \
+        mingw64-pkg-config && \
+    nosync dnf clean all -y
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
+
+ENV ABI "x86_64-w64-mingw32"
+ENV CONFIGURE_OPTS "--host=x86_64-w64-mingw32"
diff --git a/ci/containers/fedora-rawhide.Dockerfile b/ci/containers/fedora-rawhide.Dockerfile
new file mode 100644
index 000000000000..2de1ec474db5
--- /dev/null
+++ b/ci/containers/fedora-rawhide.Dockerfile
@@ -0,0 +1,69 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile fedora-rawhide libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM registry.fedoraproject.org/fedora:rawhide
+
+RUN dnf update -y --nogpgcheck fedora-gpg-keys && \
+    dnf install -y nosync && \
+    echo -e '#!/bin/sh\n\
+if test -d /usr/lib64\n\
+then\n\
+    export LD_PRELOAD=/usr/lib64/nosync/nosync.so\n\
+else\n\
+    export LD_PRELOAD=/usr/lib/nosync/nosync.so\n\
+fi\n\
+exec "$@"' > /usr/bin/nosync && \
+    chmod +x /usr/bin/nosync && \
+    nosync dnf update -y && \
+    nosync dnf install -y \
+        autoconf \
+        automake \
+        bash-completion \
+        ca-certificates \
+        ccache \
+        clang \
+        coreutils \
+        diffutils \
+        fuse3-devel \
+        gcc \
+        gcc-c++ \
+        git \
+        glib2-devel \
+        glibc-devel \
+        glibc-langpack-en \
+        gnutls \
+        gnutls-devel \
+        golang \
+        iproute \
+        jq \
+        libev-devel \
+        libtool \
+        libxml2-devel \
+        make \
+        nbd \
+        nbdkit \
+        ocaml \
+        ocaml-findlib \
+        perl-base \
+        pkgconfig \
+        python3-devel \
+        python3-flake8 \
+        qemu-img \
+        qemu-kvm \
+        sed && \
+    nosync dnf autoremove -y && \
+    nosync dnf clean all -y && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/opensuse-leap-152.Dockerfile b/ci/containers/opensuse-leap-152.Dockerfile
new file mode 100644
index 000000000000..b80e4e3ee85c
--- /dev/null
+++ b/ci/containers/opensuse-leap-152.Dockerfile
@@ -0,0 +1,56 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile opensuse-leap-152 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM registry.opensuse.org/opensuse/leap:15.2
+
+RUN zypper update -y && \
+    zypper install -y \
+           autoconf \
+           automake \
+           bash-completion \
+           ca-certificates \
+           ccache \
+           clang \
+           coreutils \
+           diffutils \
+           fuse3-devel \
+           gcc \
+           gcc-c++ \
+           git \
+           glib2-devel \
+           glibc-devel \
+           glibc-locale \
+           gnutls \
+           go \
+           iproute2 \
+           jq \
+           libev-devel \
+           libgnutls-devel \
+           libtool \
+           libxml2-devel \
+           make \
+           nbd \
+           ocaml \
+           ocaml-findlib \
+           perl-base \
+           pkgconfig \
+           python3-devel \
+           python3-flake8 \
+           qemu-kvm \
+           qemu-tools \
+           sed && \
+    zypper clean --all && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/opensuse-tumbleweed.Dockerfile b/ci/containers/opensuse-tumbleweed.Dockerfile
new file mode 100644
index 000000000000..5d9479f390dc
--- /dev/null
+++ b/ci/containers/opensuse-tumbleweed.Dockerfile
@@ -0,0 +1,57 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile opensuse-tumbleweed libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM registry.opensuse.org/opensuse/tumbleweed:latest
+
+RUN zypper update -y && \
+    zypper install -y \
+           autoconf \
+           automake \
+           bash-completion \
+           ca-certificates \
+           ccache \
+           clang \
+           coreutils \
+           diffutils \
+           fuse3-devel \
+           gcc \
+           gcc-c++ \
+           git \
+           glib2-devel \
+           glibc-devel \
+           glibc-locale \
+           gnutls \
+           go \
+           iproute2 \
+           jq \
+           libev-devel \
+           libgnutls-devel \
+           libtool \
+           libxml2-devel \
+           make \
+           nbd \
+           nbdkit \
+           ocaml \
+           ocaml-findlib \
+           perl-base \
+           pkgconfig \
+           python3-devel \
+           python3-flake8 \
+           qemu-kvm \
+           qemu-tools \
+           sed && \
+    zypper clean --all && \
+    rpm -qa | sort > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/refresh b/ci/containers/refresh
new file mode 100755
index 000000000000..327f642ed2ec
--- /dev/null
+++ b/ci/containers/refresh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+if test -z "$1"
+then
+    echo "syntax: $0 PATH-TO-LCITOOL"
+    exit 1
+fi
+
+LCITOOL=$1
+
+if ! test -x "$LCITOOL"
+then
+    echo "$LCITOOL is not executable"
+    exit 1
+fi
+
+HOSTS=$($LCITOOL hosts | grep -Ev 'freebsd|macos')
+
+for host in $HOSTS
+do
+    case "$host" in
+    fedora-rawhide)
+        for cross in mingw32 mingw64
+        do
+            $LCITOOL dockerfile $host libnbd --cross $cross > $host-cross-$cross.Dockerfile
+        done
+        ;;
+    debian-*)
+        for cross in aarch64 armv6l armv7l i686 mips mips64el mipsel ppc64le s390x
+        do
+            if test "$host-cross-$cross" = "debian-9-cross-i686" ||
+               test "$host-cross-$cross" = "debian-sid-cross-mips"
+            then
+                continue
+            fi
+            $LCITOOL dockerfile $host libnbd --cross $cross > $host-cross-$cross.Dockerfile
+        done
+        ;;
+    esac
+
+    $LCITOOL dockerfile $host libnbd > $host.Dockerfile
+done
diff --git a/ci/containers/ubuntu-1804.Dockerfile b/ci/containers/ubuntu-1804.Dockerfile
new file mode 100644
index 000000000000..3f626cc2406d
--- /dev/null
+++ b/ci/containers/ubuntu-1804.Dockerfile
@@ -0,0 +1,62 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile ubuntu-1804 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/ubuntu:18.04
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            clang \
+            coreutils \
+            diffutils \
+            flake8 \
+            g++ \
+            gcc \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libc6-dev \
+            libev-dev \
+            libglib2.0-dev \
+            libgnutls28-dev \
+            libtool-bin \
+            libxml2-dev \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
diff --git a/ci/containers/ubuntu-2004.Dockerfile b/ci/containers/ubuntu-2004.Dockerfile
new file mode 100644
index 000000000000..bf0650ac4bee
--- /dev/null
+++ b/ci/containers/ubuntu-2004.Dockerfile
@@ -0,0 +1,64 @@
+# THIS FILE WAS AUTO-GENERATED
+#
+#  $ lcitool dockerfile ubuntu-2004 libnbd
+#
+# https://gitlab.com/libvirt/libvirt-ci/-/commit/684ac15bdf4de9c5b07614f9bbf20ab0815a92c2
+
+FROM docker.io/library/ubuntu:20.04
+
+RUN export DEBIAN_FRONTEND=noninteractive && \
+    apt-get update && \
+    apt-get install -y eatmydata && \
+    eatmydata apt-get dist-upgrade -y && \
+    eatmydata apt-get install --no-install-recommends -y \
+            autoconf \
+            automake \
+            bash-completion \
+            ca-certificates \
+            ccache \
+            clang \
+            coreutils \
+            diffutils \
+            flake8 \
+            g++ \
+            gcc \
+            git \
+            gnutls-bin \
+            golang \
+            iproute2 \
+            jq \
+            libc6-dev \
+            libev-dev \
+            libfuse3-dev \
+            libglib2.0-dev \
+            libgnutls28-dev \
+            libtool-bin \
+            libxml2-dev \
+            locales \
+            make \
+            nbd-client \
+            nbd-server \
+            nbdkit \
+            ocaml \
+            ocaml-findlib \
+            perl-base \
+            pkgconf \
+            python3-dev \
+            qemu-kvm \
+            qemu-utils \
+            sed && \
+    eatmydata apt-get autoremove -y && \
+    eatmydata apt-get autoclean -y && \
+    sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
+    dpkg-reconfigure locales && \
+    dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt && \
+    mkdir -p /usr/libexec/ccache-wrappers && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/c++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/cc && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/g++ && \
+    ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+
+ENV LANG "en_US.UTF-8"
+ENV MAKE "/usr/bin/make"
+ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
-- 
2.31.1




More information about the Libguestfs mailing list