Skip to content

Commit

Permalink
tests: properly build snapd snap
Browse files Browse the repository at this point in the history
  • Loading branch information
valentindavid committed Feb 15, 2024
1 parent f9993d7 commit 9a469fe
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 141 deletions.
2 changes: 1 addition & 1 deletion spread.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ repack: |
tar c current.delta >&4
fi
kill-timeout: 30m
kill-timeout: 60m

prepare: |
# NOTE: This part of the code needs to be in spread.yaml as it runs before
Expand Down
42 changes: 26 additions & 16 deletions tests/lib/nested.sh
Original file line number Diff line number Diff line change
Expand Up @@ -556,23 +556,33 @@ nested_prepare_snapd() {
echo "Repacking snapd snap"
local snap_name output_name snap_id
if nested_is_core_16_system; then
snap_name="core"
output_name="core-from-snapd-deb.snap"
snap_id="99T7MUlRhtI3U0QFgl5mXXESAiSwt776"
if [ ! -f "$NESTED_ASSETS_DIR/core-from-snapd-deb.snap" ]; then
"$TESTSTOOLS"/snaps-state repack_snapd_deb_into_snap core "$NESTED_ASSETS_DIR"
cp "$NESTED_ASSETS_DIR/core-from-snapd-deb.snap" "$(nested_get_extra_snaps_path)/core-from-snapd-deb.snap"
fi
# sign the snapd snap with fakestore if requested
if [ "$NESTED_SIGN_SNAPS_FAKESTORE" = "true" ]; then
"$TESTSTOOLS"/store-state make-snap-installable --noack "$NESTED_FAKESTORE_BLOB_DIR" "$(nested_get_extra_snaps_path)/core-from-snapd-deb.snap" "99T7MUlRhtI3U0QFgl5mXXESAiSwt776"
fi
else
snap_name="snapd"
output_name="snapd-from-deb.snap"
snap_id="PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4"
fi

if [ ! -f "$NESTED_ASSETS_DIR/$output_name" ]; then
"$TESTSTOOLS"/snaps-state repack_snapd_deb_into_snap "$snap_name" "$NESTED_ASSETS_DIR"
fi
cp "$NESTED_ASSETS_DIR/$output_name" "$(nested_get_extra_snaps_path)/$output_name"

# sign the snapd snap with fakestore if requested
if [ "$NESTED_SIGN_SNAPS_FAKESTORE" = "true" ]; then
"$TESTSTOOLS"/store-state make-snap-installable --noack "$NESTED_FAKESTORE_BLOB_DIR" "$(nested_get_extra_snaps_path)/$output_name" "$snap_id"
for f in "${NESTED_ASSETS_DIR}"/snapd_*.snap; do
snap_name="$(basename "${f}")"
break
done
if [ ! -f "${NESTED_ASSETS_DIR}/${snap_name}" ]; then
# shellcheck source=tests/lib/prepare.sh
. "$TESTSLIB"/prepare.sh
build_snapd_snap "$NESTED_ASSETS_DIR"
for f in "${NESTED_ASSETS_DIR}"/snapd_*.snap; do
snap_name="$(basename "${f}")"
break
done
cp "${NESTED_ASSETS_DIR}/${snap_name}" "$(nested_get_extra_snaps_path)/"
fi
# sign the snapd snap with fakestore if requested
if [ "$NESTED_SIGN_SNAPS_FAKESTORE" = "true" ]; then
"$TESTSTOOLS"/store-state make-snap-installable --noack "$NESTED_FAKESTORE_BLOB_DIR" "$(nested_get_extra_snaps_path)/${snap_name}" "PMrrV4ml8uWuEUDBT8dSGnKUYbevVhc4"
fi
fi
fi
}
Expand Down
184 changes: 99 additions & 85 deletions tests/lib/prepare.sh
Original file line number Diff line number Diff line change
Expand Up @@ -425,90 +425,42 @@ prepare_classic() {
fi
}

repack_snapd_snap_with_deb_content() {
local TARGET="$1"

local UNPACK_DIR="/tmp/snapd-unpack"
unsquashfs -no-progress -d "$UNPACK_DIR" snapd_*.snap
# clean snap apparmor.d to ensure we put the right snap-confine apparmor
# file in place. Its called usr.lib.snapd.snap-confine on 14.04 but
# usr.lib.snapd.snap-confine.real everywhere else
rm -f "$UNPACK_DIR"/etc/apparmor.d/*

dpkg-deb -x "$SPREAD_PATH"/../snapd_*.deb "$UNPACK_DIR"
cp /usr/lib/snapd/info "$UNPACK_DIR"/usr/lib/snapd
snap pack "$UNPACK_DIR" "$TARGET"
rm -rf "$UNPACK_DIR"
ensure_snapcraft() {
if ! command -v snapcraft; then
snap install --channel="${SNAPCRAFT_SNAP_CHANNEL}" snapcraft --classic
"$TESTSTOOLS"/lxd-state prepare-snap
fi
}

repack_core_snap_with_tweaks() {
local CORESNAP="$1"
local TARGET="$2"

local UNPACK_DIR="/tmp/core-unpack"
unsquashfs -no-progress -d "$UNPACK_DIR" "$CORESNAP"

mkdir -p "$UNPACK_DIR"/etc/systemd/journald.conf.d
cat <<EOF > "$UNPACK_DIR"/etc/systemd/journald.conf.d/to-console.conf
[Journal]
ForwardToConsole=yes
TTYPath=/dev/ttyS0
MaxLevelConsole=debug
EOF
mkdir -p "$UNPACK_DIR"/etc/systemd/system/snapd.service.d
cat <<EOF > "$UNPACK_DIR"/etc/systemd/system/snapd.service.d/logging.conf
[Service]
Environment=SNAPD_DEBUG_HTTP=7 SNAPD_DEBUG=1 SNAPPY_TESTING=1 SNAPD_CONFIGURE_HOOK_TIMEOUT=30s
StandardOutput=journal+console
StandardError=journal+console
EOF

cp "${SPREAD_PATH}"/data/completion/bash/complete.sh "${UNPACK_DIR}"/usr/lib/snapd/complete.sh

snap pack --filename="$TARGET" "$UNPACK_DIR"

rm -rf "$UNPACK_DIR"
cleanup_snapcraft() {
snap remove --purge lxd || true
"$TESTSTOOLS"/lxd-state undo-mount-changes
snap remove --purge snapcraft || true
}

repack_kernel_snap() {
local TARGET=$1
local VERSION
local UNPACK_DIR
local CHANNEL

VERSION=$(nested_get_version)
if [ "$VERSION" = 16 ]; then
CHANNEL=latest
else
CHANNEL=$VERSION
fi

echo "Repacking kernel snap"
UNPACK_DIR=/tmp/kernel-unpack
snap download --basename=pc-kernel --channel="$CHANNEL/${KERNEL_CHANNEL}" pc-kernel
unsquashfs -no-progress -d "$UNPACK_DIR" pc-kernel.snap
snap pack --filename="$TARGET" "$UNPACK_DIR"

rm -rf pc-kernel.snap "$UNPACK_DIR"
run_snapcraft() {
ensure_snapcraft
(cd "${PROJECT_PATH}" && snapcraft "$@")
cleanup_snapcraft
}

repack_snapd_snap_with_deb_content_and_run_mode_firstboot_tweaks() {
local TARGET="$1"
build_snapd_snap() {
local TARGET
TARGET="$(realpath "${1}")"
[ -d "${TARGET}" ] || mkdir "${TARGET}"
chmod -R go+r "${PROJECT_PATH}/tests"
run_snapcraft --use-lxd --verbosity verbose
mv "${PROJECT_PATH}"/snapd_*.snap "${TARGET}/"
}

build_snapd_snap_with_run_mode_firstboot_tweaks() {
local TARGET
TARGET="$(realpath "${1}")"
chmod -R go+r "${PROJECT_PATH}/tests"
run_snapcraft --use-lxd --verbosity verbose --output="snapd_from_snapcraft.snap"
mv "${PROJECT_PATH}/snapd_from_snapcraft.snap" "/tmp/snapd_from_snapcraft.snap"
local UNPACK_DIR="/tmp/snapd-unpack"
unsquashfs -no-progress -d "$UNPACK_DIR" snapd_*.snap

# data/preseed.json is not included in the deb, use the latest
# version from source tree to replace the one in the re-packed snapd snap.
cp "$PROJECT_PATH/data/preseed.json" "$UNPACK_DIR"/usr/lib/snapd

# clean snap apparmor.d to ensure we put the right snap-confine apparmor
# file in place. Its called usr.lib.snapd.snap-confine on 14.04 but
# usr.lib.snapd.snap-confine.real everywhere else
rm -f "$UNPACK_DIR"/etc/apparmor.d/*

dpkg-deb -x "$SPREAD_PATH"/../snapd_*.deb "$UNPACK_DIR"
cp /usr/lib/snapd/info "$UNPACK_DIR"/usr/lib/snapd
unsquashfs -no-progress -d "$UNPACK_DIR" /tmp/snapd_from_snapcraft.snap

# now install a unit that sets up enough so that we can connect
cat > "$UNPACK_DIR"/lib/systemd/system/snapd.spread-tests-run-mode-tweaks.service <<'EOF'
Expand Down Expand Up @@ -578,12 +530,79 @@ touch /root/spread-setup-done
EOF
chmod 0755 "$UNPACK_DIR"/usr/lib/snapd/snapd.spread-tests-run-mode-tweaks.sh

snap pack "$UNPACK_DIR" "$TARGET"
rm -rf "$UNPACK_DIR"
}

repack_core_snap_with_tweaks() {
local CORESNAP="$1"
local TARGET="$2"

local UNPACK_DIR="/tmp/core-unpack"
unsquashfs -no-progress -d "$UNPACK_DIR" "$CORESNAP"

mkdir -p "$UNPACK_DIR"/etc/systemd/journald.conf.d
cat <<EOF > "$UNPACK_DIR"/etc/systemd/journald.conf.d/to-console.conf
[Journal]
ForwardToConsole=yes
TTYPath=/dev/ttyS0
MaxLevelConsole=debug
EOF
mkdir -p "$UNPACK_DIR"/etc/systemd/system/snapd.service.d
cat <<EOF > "$UNPACK_DIR"/etc/systemd/system/snapd.service.d/logging.conf
[Service]
Environment=SNAPD_DEBUG_HTTP=7 SNAPD_DEBUG=1 SNAPPY_TESTING=1 SNAPD_CONFIGURE_HOOK_TIMEOUT=30s
StandardOutput=journal+console
StandardError=journal+console
EOF

# TODO: add this to core20+
case "${CORESNAP}" in
core.snap)
;;
core18.snap)
# shellcheck disable=SC2016
sed '/TMPD=/a [ -d /snap/snapd ] || mkdir -p /snap/snapd; ln -sf "${TMPD}" /snap/snapd/current' -i "${UNPACK_DIR}/usr/lib/core18/run-snapd-from-snap"
;;
core*.snap)
# shellcheck disable=SC2016
sed '/SNAPD_BASE_DIR=/a [ -d /snap/snapd ] || mkdir -p /snap/snapd; ln -sf "${SNAPD_BASE_DIR}" /snap/snapd/current' -i "${UNPACK_DIR}/usr/lib/core/run-snapd-from-snap"
;;
*)
echo "Unknown core snap ${CORESNAP}" 1>&2
false
;;
esac

cp "${SPREAD_PATH}"/data/completion/bash/complete.sh "${UNPACK_DIR}"/usr/lib/snapd/complete.sh

snap pack "$UNPACK_DIR" "$TARGET"
snap pack --filename="$TARGET" "$UNPACK_DIR"

rm -rf "$UNPACK_DIR"
}

repack_kernel_snap() {
local TARGET=$1
local VERSION
local UNPACK_DIR
local CHANNEL

VERSION=$(nested_get_version)
if [ "$VERSION" = 16 ]; then
CHANNEL=latest
else
CHANNEL=$VERSION
fi

echo "Repacking kernel snap"
UNPACK_DIR=/tmp/kernel-unpack
snap download --basename=pc-kernel --channel="$CHANNEL/${KERNEL_CHANNEL}" pc-kernel
unsquashfs -no-progress -d "$UNPACK_DIR" pc-kernel.snap
snap pack --filename="$TARGET" "$UNPACK_DIR"

rm -rf pc-kernel.snap "$UNPACK_DIR"
}

# Builds kernel snap with bad kernel.efi, in different ways
# $1: snap we will modify
# $2: target folder for the new snap
Expand Down Expand Up @@ -918,11 +937,6 @@ setup_reflash_magic() {
# need to be seeded to proceed with snap install
snap wait system seed.loaded

# download the snapd snap for all uc systems except uc16
if ! os.query is-core16; then
snap download "--channel=${SNAPD_CHANNEL}" snapd
fi

# we cannot use "snaps.names tool" here because no snaps are installed yet
core_name="core"
if os.query is-core18; then
Expand Down Expand Up @@ -976,14 +990,14 @@ setup_reflash_magic() {
export UBUNTU_IMAGE_SNAP_CMD="$IMAGE_HOME/snap"

if os.query is-core18; then
repack_snapd_snap_with_deb_content "$IMAGE_HOME"
build_snapd_snap "${IMAGE_HOME}"
# FIXME: fetch directly once its in the assertion service
cp "$TESTSLIB/assertions/ubuntu-core-18-amd64.model" "$IMAGE_HOME/pc.model"
elif os.query is-core20; then
repack_snapd_snap_with_deb_content_and_run_mode_firstboot_tweaks "$IMAGE_HOME"
build_snapd_snap_with_run_mode_firstboot_tweaks "$IMAGE_HOME"
cp "$TESTSLIB/assertions/ubuntu-core-20-amd64.model" "$IMAGE_HOME/pc.model"
elif os.query is-core22; then
repack_snapd_snap_with_deb_content_and_run_mode_firstboot_tweaks "$IMAGE_HOME"
build_snapd_snap_with_run_mode_firstboot_tweaks "$IMAGE_HOME"
if os.query is-arm; then
cp "$TESTSLIB/assertions/ubuntu-core-22-arm64.model" "$IMAGE_HOME/pc.model"
else
Expand Down
16 changes: 0 additions & 16 deletions tests/lib/tools/snaps-state
Original file line number Diff line number Diff line change
Expand Up @@ -146,22 +146,6 @@ repack_snapd_deb_into_snap() {
# cleanup
rm -rf core-unpacked
;;
snapd)
# use snapd from edge as a recent snap that should be close to what we will
# have in the snapd deb
snap download snapd --basename=snapd --edge
unsquashfs -d ./snapd-unpacked snapd.snap
rm snapd.snap

# extract all the files from the snapd deb
dpkg-deb -x "$deb_file" ./snapd-unpacked

# repack into the target dir specified
snap pack --filename=snapd-from-deb.snap snapd-unpacked "$target_dir"

# cleanup
rm -rf snapd-unpacked
;;
*)
echo "snaps-state: use either core or snapd snaps for repack, snapd $snap_name not supported"
show_help
Expand Down
2 changes: 1 addition & 1 deletion tests/lib/uc20-recovery.sh
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ transition_to_recover_mode(){

# with the external backend, we do not have the special snapd snap with
# the first-boot run mode tweaks as created from $TESTLIB/prepare.sh's
# repack_snapd_snap_with_deb_content_and_run_mode_firstboot_tweaks func
# build_snapd_snap_with_run_mode_firstboot_tweaks func
# so instead to get the spread gopath and other data needed to continue
# the test, we need to add a .ssh/rc script which copies all of the data
# from /host/ubuntu-data in recover mode to the tmpfs /home, see
Expand Down
3 changes: 1 addition & 2 deletions tests/main/preseed-core20/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ environment:
prepare: |
#shellcheck source=tests/lib/prepare.sh
. "$TESTSLIB"/prepare.sh
snap download "--channel=${SNAPD_CHANNEL}" snapd
repack_snapd_snap_with_deb_content_and_run_mode_firstboot_tweaks /tmp
build_snapd_snap_with_run_mode_firstboot_tweaks /tmp
snap pack systemusers-snap
Expand Down
7 changes: 5 additions & 2 deletions tests/main/preseed-lxd/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ prepare: |
mount /dev/nbd0p1 "$IMAGE_MOUNTPOINT"
# add snapd from this branch into the seed
"$TESTSTOOLS"/snaps-state repack_snapd_deb_into_snap snapd
mv snapd-from-deb.snap snapd.snap
# shellcheck source=tests/lib/prepare.sh
. "$TESTSLIB"/prepare.sh
build_snapd_snap_with_run_mode_firstboot_tweaks .
mv snapd_*.snap snapd.snap
inject_snap_into_seed "$IMAGE_MOUNTPOINT" snapd
if [ ! -x /usr/bin/lxc ]; then
Expand Down
6 changes: 4 additions & 2 deletions tests/main/snapd-without-core/task.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
summary: Ensure the snapd works without core on classic systems

details: |
TODO
# Run only on ubuntu classic because this re-execs. We have a
# separate test for UC18 already and on UC16 we always have a core
# snap so we don't need to test there.
Expand All @@ -21,8 +24,7 @@ execute: |
echo "Create modified snapd snap"
#shellcheck source=tests/lib/prepare.sh
. "$TESTSLIB"/prepare.sh
snap download --edge snapd
repack_snapd_snap_with_deb_content /tmp
build_snapd_snap /tmp
echo "Ensure core is gone so that we can have snapd"
#shellcheck source=tests/lib/pkgdb.sh
Expand Down
12 changes: 9 additions & 3 deletions tests/nested/manual/cloud-init-never-used-not-vuln/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ summary: |
Test that cloud-init is no longer vulnerable on Ubuntu Core with the fix for
CVE-2020-11933 in place.
details: |
TODO
systems: [ubuntu-18.04-64, ubuntu-16.04-64]

environment:
Expand Down Expand Up @@ -88,11 +91,14 @@ execute: |
else
# build the snapd snap for this run
"$TESTSTOOLS"/snaps-state repack_snapd_deb_into_snap snapd
remote.push "$PWD/snapd-from-deb.snap"
# shellcheck source=tests/lib/prepare.sh
. "$TESTSLIB"/prepare.sh
build_snapd_snap .
mv snapd_*.snap snapd.snap
remote.push "$PWD/snapd.snap"
# install the snapd snap
remote.exec "sudo snap install snapd-from-deb.snap --dangerous"
remote.exec "sudo snap install snapd.snap --dangerous"
fi
fi
Expand Down
Loading

0 comments on commit 9a469fe

Please sign in to comment.