diff --git a/Makefile.am b/Makefile.am index 9e7b987..f319a7a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,9 @@ SUBDIRS = src tests docs EXTRA_DIST = PORTING README.md VERSION + +.PHONY: check +check: check-syntax + +.PHONY: check-syntax +check-syntax: + shellcheck --format=gcc .spread-prepare.sh diff --git a/spread-tests/data/apt-keys/README.md b/spread-tests/data/apt-keys/README.md new file mode 100644 index 0000000..e496ac7 --- /dev/null +++ b/spread-tests/data/apt-keys/README.md @@ -0,0 +1,4 @@ +This directory contains keys used by the sbuild program to sign the temporary +archive. Those keys are kept in the tree as ephemeral test virtual machines do +not have sufficient entropy to generate keys by themselves in reasonable amount +of time. diff --git a/spread-tests/data/apt-keys/sbuild-key.pub b/spread-tests/data/apt-keys/sbuild-key.pub new file mode 100644 index 0000000..34d8b57 Binary files /dev/null and b/spread-tests/data/apt-keys/sbuild-key.pub differ diff --git a/spread-tests/data/apt-keys/sbuild-key.sec b/spread-tests/data/apt-keys/sbuild-key.sec new file mode 100644 index 0000000..cdadd27 Binary files /dev/null and b/spread-tests/data/apt-keys/sbuild-key.sec differ diff --git a/spread-tests/distros/debian. b/spread-tests/distros/debian. new file mode 100644 index 0000000..4a5a9eb --- /dev/null +++ b/spread-tests/distros/debian. @@ -0,0 +1,2 @@ +distro_codename=sid +distro_packaging_git_branch=debian diff --git a/spread-tests/distros/debian.common b/spread-tests/distros/debian.common new file mode 100644 index 0000000..de33716 --- /dev/null +++ b/spread-tests/distros/debian.common @@ -0,0 +1,8 @@ +distro_archive=http://ftp.debian.org/debian +# NOTE: Debian packaging needs to be updated. I sent a mail to the +# debian maintainer with instructions on what needs to happen and +# how it fits into the CI system. +# +# For now all builds on debian will fail as they still contains +# debian/patches that are now applied upstream. +distro_packaging_git=git://anonscm.debian.org/collab-maint/snap-confine.git diff --git a/spread-tests/distros/ubuntu.14.04 b/spread-tests/distros/ubuntu.14.04 new file mode 100644 index 0000000..8471d57 --- /dev/null +++ b/spread-tests/distros/ubuntu.14.04 @@ -0,0 +1,2 @@ +distro_codename=trusty +distro_packaging_git_branch=14.04 diff --git a/spread-tests/distros/ubuntu.16.04 b/spread-tests/distros/ubuntu.16.04 new file mode 100644 index 0000000..4e89a35 --- /dev/null +++ b/spread-tests/distros/ubuntu.16.04 @@ -0,0 +1,2 @@ +distro_codename=xenial +distro_packaging_git_branch=16.04 diff --git a/spread-tests/distros/ubuntu.16.10 b/spread-tests/distros/ubuntu.16.10 new file mode 100644 index 0000000..374ea2e --- /dev/null +++ b/spread-tests/distros/ubuntu.16.10 @@ -0,0 +1,2 @@ +distro_codename=yakkety +distro_packaging_git_branch=16.10 diff --git a/spread-tests/distros/ubuntu.common b/spread-tests/distros/ubuntu.common new file mode 100644 index 0000000..9acd710 --- /dev/null +++ b/spread-tests/distros/ubuntu.common @@ -0,0 +1,3 @@ +distro_archive=http://archive.ubuntu.com/ubuntu +distro_packaging_git=https://git.launchpad.net/snap-confine +sbuild_args="--extra-repository=deb http://archive.ubuntu.com/ubuntu/ ${distro_codename} universe" \ No newline at end of file diff --git a/spread-tests/cgroup-used/task.yaml b/spread-tests/main/cgroup-used/task.yaml similarity index 100% rename from spread-tests/cgroup-used/task.yaml rename to spread-tests/main/cgroup-used/task.yaml diff --git a/spread-tests/hostfs-created-on-demand/task.yaml b/spread-tests/main/hostfs-created-on-demand/task.yaml similarity index 100% rename from spread-tests/hostfs-created-on-demand/task.yaml rename to spread-tests/main/hostfs-created-on-demand/task.yaml diff --git a/spread-tests/media-visible-in-devmode/task.yaml b/spread-tests/main/media-visible-in-devmode/task.yaml similarity index 100% rename from spread-tests/media-visible-in-devmode/task.yaml rename to spread-tests/main/media-visible-in-devmode/task.yaml diff --git a/spread-tests/mount-profiles-bin-snap-destination/task.yaml b/spread-tests/main/mount-profiles-bin-snap-destination/task.yaml similarity index 100% rename from spread-tests/mount-profiles-bin-snap-destination/task.yaml rename to spread-tests/main/mount-profiles-bin-snap-destination/task.yaml diff --git a/spread-tests/mount-profiles-bin-snap-source/task.yaml b/spread-tests/main/mount-profiles-bin-snap-source/task.yaml similarity index 100% rename from spread-tests/mount-profiles-bin-snap-source/task.yaml rename to spread-tests/main/mount-profiles-bin-snap-source/task.yaml diff --git a/spread-tests/mount-profiles-missing-dst/task.yaml b/spread-tests/main/mount-profiles-missing-dst/task.yaml similarity index 100% rename from spread-tests/mount-profiles-missing-dst/task.yaml rename to spread-tests/main/mount-profiles-missing-dst/task.yaml diff --git a/spread-tests/mount-profiles-missing-src/task.yaml b/spread-tests/main/mount-profiles-missing-src/task.yaml similarity index 100% rename from spread-tests/mount-profiles-missing-src/task.yaml rename to spread-tests/main/mount-profiles-missing-src/task.yaml diff --git a/spread-tests/mount-profiles-mount-tmpfs/task.yaml b/spread-tests/main/mount-profiles-mount-tmpfs/task.yaml similarity index 100% rename from spread-tests/mount-profiles-mount-tmpfs/task.yaml rename to spread-tests/main/mount-profiles-mount-tmpfs/task.yaml diff --git a/spread-tests/mount-profiles-ro-mount/task.yaml b/spread-tests/main/mount-profiles-ro-mount/task.yaml similarity index 100% rename from spread-tests/mount-profiles-ro-mount/task.yaml rename to spread-tests/main/mount-profiles-ro-mount/task.yaml diff --git a/spread-tests/mount-profiles-rw-mount/task.yaml b/spread-tests/main/mount-profiles-rw-mount/task.yaml similarity index 100% rename from spread-tests/mount-profiles-rw-mount/task.yaml rename to spread-tests/main/mount-profiles-rw-mount/task.yaml diff --git a/spread-tests/mount-usr-src/task.yaml b/spread-tests/main/mount-usr-src/task.yaml similarity index 100% rename from spread-tests/mount-usr-src/task.yaml rename to spread-tests/main/mount-usr-src/task.yaml diff --git a/spread-tests/test-snap-runs/task.yaml b/spread-tests/main/test-snap-runs/task.yaml similarity index 100% rename from spread-tests/test-snap-runs/task.yaml rename to spread-tests/main/test-snap-runs/task.yaml diff --git a/spread-tests/ubuntu-core-launcher-exists/task.yaml b/spread-tests/main/ubuntu-core-launcher-exists/task.yaml similarity index 100% rename from spread-tests/ubuntu-core-launcher-exists/task.yaml rename to spread-tests/main/ubuntu-core-launcher-exists/task.yaml diff --git a/spread-tests/unit-tests/task.yaml b/spread-tests/main/unit-tests/task.yaml similarity index 100% rename from spread-tests/unit-tests/task.yaml rename to spread-tests/main/unit-tests/task.yaml diff --git a/spread-tests/user-data-dir-created/task.yaml b/spread-tests/main/user-data-dir-created/task.yaml similarity index 100% rename from spread-tests/user-data-dir-created/task.yaml rename to spread-tests/main/user-data-dir-created/task.yaml diff --git a/spread-tests/release.sh b/spread-tests/release.sh new file mode 100755 index 0000000..83f743c --- /dev/null +++ b/spread-tests/release.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# This script creates a new release tarball +set -xue + +# Sanity check, are we in the top-level directory of the tree? +test -f configure.ac || ( echo 'this script must be executed from the top-level of the tree' && exit 1) + +# Record where the top level directory is +top_dir=$(pwd) + +# Create source distribution tarball and place it in the top-level directory. +create_dist_tarball() { + # Load the version number from a dedicated file + local pkg_version= + pkg_version="$(cat "$top_dir/VERSION")" + + # Ensure that build system is up-to-date and ready + autoreconf -i + # XXX: This fixes somewhat odd error when configure below (in an empty directory) fails with: + # configure: error: source directory already configured; run "make distclean" there first + test -f Makefile && make distclean + + # Create a scratch space to run configure + scratch_dir="$(mktemp -d)" + trap 'rm -rf "$scratch_dir"' EXIT + + # Configure the project in a scratch directory + cd "$scratch_dir" + "$top_dir/configure" --prefix=/usr + + # Create the distribution tarball + make dist + + # Ensure we got the tarball we were expecting to see + test -f "snap-confine-$pkg_version.tar.gz" + + # Move it to the top-level directory + mv "snap-confine-$pkg_version.tar.gz" "$top_dir/" +} + +create_dist_tarball diff --git a/spread-tests/spread-prepare.sh b/spread-tests/spread-prepare.sh new file mode 100755 index 0000000..0a54f93 --- /dev/null +++ b/spread-tests/spread-prepare.sh @@ -0,0 +1,155 @@ +#!/bin/sh +# This script is started by spread to prepare the execution environment +set -xue + +# Sanity check, are we in the top-level directory of the tree? +test -f configure.ac || ( echo 'this script must be executed from the top-level of the tree' && exit 1) + +# Record where the top level directory is +top_dir=$(pwd) + +# Record the current distribution release data to know what to do +release_ID="$( . /etc/os-release && echo "${ID:-linux}" )" +release_VERSION_ID="$( . /etc/os-release && echo "${VERSION_ID:-}" )" + + +build_debian_or_ubuntu_package() { + local pkg_version + local distro_packaging_git_branch + local distro_packaging_git + local distro_archive + local distro_codename + local sbuild_args="" + pkg_version="$(cat "$top_dir/VERSION")" + + if [ ! -f "$top_dir/spread-tests/distros/$release_ID.$release_VERSION_ID" ] || \ + [ ! -f "$top_dir/spread-tests/distros/$release_ID.common" ]; then + echo "Distribution: $release_ID (release $release_VERSION_ID) is not supported" + echo "please read this script and create new files in spread-test/distros" + exit 1 + fi + + # source the distro specific vars + . "$top_dir/spread-tests/distros/$release_ID.$release_VERSION_ID" + . "$top_dir/spread-tests/distros/$release_ID.common" + + # sanity check, ensure that essential variables were defined + test -n "$distro_packaging_git_branch" + test -n "$distro_packaging_git" + test -n "$distro_archive" + test -n "$distro_codename" + + # Create a scratch space + scratch_dir="$(mktemp -d)" + trap 'rm -rf "$scratch_dir"' EXIT + + # Do everything in the scratch directory + cd "$scratch_dir" + + # Fetch the current Ubuntu packaging for the appropriate release + git clone -b "$distro_packaging_git_branch" "$distro_packaging_git" distro-packaging + + # Install all the build dependencies declared by the package. + apt build-dep -y ./distro-packaging/ + + # Generate a new upstream tarball from the current state of the tree + ( cd "$top_dir" && spread-tests/release.sh ) + + # Prepare the .orig tarball and unpackaged source tree + cp "$top_dir/snap-confine-$pkg_version.tar.gz" "snap-confine_$pkg_version.orig.tar.gz" + tar -zxf "snap-confine_$pkg_version.orig.tar.gz" + + # Apply the debian directory from downstream packaging to form a complete source package + mv "distro-packaging/debian" "snap-confine-$pkg_version/debian" + rm -rf distro-packaging + + # Add an automatically-generated changelog entry + # The --controlmaint takes the maintainer details from debian/control + ( cd "snap-confine-$pkg_version" && dch --controlmaint --newversion "${pkg_version}-1" "Automatic CI build") + + # Build an unsigned source package + ( cd "snap-confine-$pkg_version" && dpkg-buildpackage -uc -us -S ) + + # Copy source package files to the top-level directory (this helps for + # interactive debugging since the package is available right there) + cp ./*.dsc ./*.debian.tar.* ./*.orig.tar.gz "$top_dir/" + + # Ensure that we have a sbuild chroot ready + if ! schroot -l | grep "chroot:${distro_codename}-.*-sbuild"; then + sbuild-createchroot \ + --include=eatmydata \ + "--make-sbuild-tarball=/var/lib/sbuild/${distro_codename}-amd64.tar.gz" \ + "$distro_codename" "$(mktemp -d)" \ + "$distro_archive" + fi + + # Build a binary package in a clean chroot. + # NOTE: nocheck is because the package still includes old unit tests that + # are deeply integrated into how ubuntu apparmor denials are logged. This + # should be removed once those test are migrated to spread testes. + DEB_BUILD_OPTIONS=nocheck sbuild \ + --arch-all \ + --dist="$distro_codename" \ + --batch \ + "$sbuild_args" \ + "snap-confine_${pkg_version}-1.dsc" + + # Copy all binary packages to the top-level directory + cp ./*.deb "$top_dir/" +} + + +# Apply tweaks +case "$release_ID" in + ubuntu) + # apt update is hanging on security.ubuntu.com with IPv6. + sysctl -w net.ipv6.conf.all.disable_ipv6=1 + trap "sysctl -w net.ipv6.conf.all.disable_ipv6=0" EXIT + ;; +esac + + +# Install all the build dependencies +case "$release_ID" in + ubuntu|debian) + apt-get update + # On Debian and derivatives we need the following things: + # - sbuild -- to build the binary package with extra hygiene + # - devscripts -- to modify the changelog automatically + # - git -- to clone native downstream packaging + apt-get install --quiet -y sbuild devscripts git + # XXX: Taken from https://wiki.debian.org/sbuild + mkdir -p /root/.gnupg + # NOTE: We cannot use sbuild-update --keygen as virtual machines lack + # the necessary entropy to generate keys before the spread timeout + # kicks in. Instead we just copy pre-made, insecure keys from the + # source repository. + mkdir -p /var/lib/sbuild/apt-keys/ + cp -a "$top_dir/spread-tests/data/apt-keys/"* /var/lib/sbuild/apt-keys/ + sbuild-adduser "$LOGNAME" + ;; + *) + echo "unsupported distribution: $release_ID" + echo "patch spread-prepare to teach it about how to install build dependencies" + exit 1 + ;; +esac + +# Build and install the native package using downstream packaging and the fresh upstream tarball +case "$release_ID" in + ubuntu|debian) + build_debian_or_ubuntu_package "$release_ID" "$release_VERSION_ID" + # Install the freshly-built packages + dpkg -i snap-confine_*.deb || apt-get -f install -y + dpkg -i ubuntu-core-launcher_*.deb || apt-get -f install -y + # Install snapd (testes require it) + apt-get install -y snapd + ;; + *) + echo "unsupported distribution: $release_ID" + exit 1 + ;; +esac + +# Install the core snap +snap list | grep -q ubuntu-core || snap install ubuntu-core diff --git a/spread.yaml b/spread.yaml index 17643b9..bb20980 100644 --- a/spread.yaml +++ b/spread.yaml @@ -10,48 +10,21 @@ backends: systems: - ubuntu-16.04-64-grub # - ubuntu-16.04-32-grub - - debian-8 path: /remote/path/ exclude: - .git + - debian + - autom4te.cache prepare: | echo "Spread is running as $(id)" [ "$REUSE_PROJECT" != 1 ] || exit 0 - release_ID="$( . /etc/os-release && echo "${ID:-linux}" )" - case $release_ID in - ubuntu) - # apt update is hanging on security.ubuntu.com with IPv6. - sysctl -w net.ipv6.conf.all.disable_ipv6=1 - trap "sysctl -w net.ipv6.conf.all.disable_ipv6=0" EXIT - ;; - debian) - echo "deb http://ftp.de.debian.org/debian sid main" > /etc/apt/sources.list.d/snappy.list - ;; - esac - case $release_ID in - ubuntu|debian) - apt-get update - apt-get install --quiet -y fakeroot - # Build a local copy of snap-confine - apt-get install --quiet -y autoconf automake autotools-dev debhelper dh-apparmor dh-autoreconf indent libapparmor-dev libseccomp-dev libudev-dev pkg-config shellcheck udev python3-docutils libglib2.0-dev - test -d /home/test || adduser --quiet --disabled-password --gecos '' test - chown test.test -R .. - sudo -i -u test /bin/sh -c "cd $PWD && DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -tc -b -Zgzip" - dpkg -i ../snap-confine_*.deb || apt-get -f install -y - dpkg -i ../ubuntu-core-launcher_*.deb || apt-get -f install -y - rm -f ../snap-confine_*.deb ../ubuntu-core-launcher_*.deb - # Install snapd (testes require it) - apt-get install -y snapd - ;; - esac - # Install the core snap - snap list | grep -q ubuntu-core || snap install ubuntu-core + ./spread-tests/spread-prepare.sh suites: - spread-tests/: + spread-tests/main/: summary: Full-system tests for snap-confine spread-tests/regression/: summary: Regression tests for past bug-fixes