2016-08-18 00:15:30 +03:00
#!/bin/bash
#
# Copyright (C) 2016 Jonathan Lebon <jlebon@redhat.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
2017-10-01 16:34:23 +03:00
set -euo pipefail
2016-08-18 00:15:30 +03:00
. ${ commondir } /libtest.sh
. ${ commondir } /libvm.sh
set -x
# SUMMARY: check that RPM scripts are properly handled during package layering
2017-06-29 17:11:25 +03:00
# do a bunch of tests together so that we only have to reboot once
2016-08-18 00:15:30 +03:00
2018-01-19 17:24:09 +03:00
# For the expected semantics of these scripts, see the comments in
# rpmostree-scripts.c.
2017-06-29 17:11:25 +03:00
vm_build_rpm scriptpkg1 \
pre "groupadd -r scriptpkg1" \
pretrans " # http://lists.rpm.org/pipermail/rpm-ecosystem/2016-August/000391.html
2018-01-19 17:24:09 +03:00
echo pretrans should' ve been ignored && exit 1" \
verifyscript "echo verifyscript should've been ignored && exit 1" \
2019-06-07 19:32:01 +03:00
post_args "-p /usr/bin/bash" \
post '
# default shell is sh, but we requested bash; check that rpm-ostree picks it up
interp = $( cat /proc/$$ /comm)
if [ " $interp " != "bash" ] ; then
echo " Expected bash interpreter, got $interp "
exit 1
fi
touch /usr/lib/rpmostreetestinterp
touch /var/lib/rpm-state/scriptpkg1-stamp' \
2017-06-29 17:11:25 +03:00
posttrans " # Firewalld; https://github.com/projectatomic/rpm-ostree/issues/638
. /etc/os-release || :
# See https://github.com/projectatomic/rpm-ostree/pull/647
for path in /tmp /var/tmp; do
if test -f \$ { path} /file-in-host-tmp-not-for-scripts; then
echo found file from host /tmp
exit 1
fi
2018-03-28 00:14:56 +03:00
done ;
test -f /var/lib/rpm-state/scriptpkg1-stamp"
2016-08-18 00:15:30 +03:00
2017-06-29 17:11:25 +03:00
# check that host /tmp doesn't get mounted
2017-02-24 23:48:54 +03:00
vm_cmd touch /tmp/file-in-host-tmp-not-for-scripts
2017-01-17 21:29:48 +03:00
vm_rpmostree pkg-add scriptpkg1
2016-08-18 00:15:30 +03:00
echo "ok pkg-add scriptpkg1"
vm_reboot
vm_assert_layered_pkg scriptpkg1 present
echo "ok pkg scriptpkg1 added"
2017-06-08 18:47:51 +03:00
vm_cmd "test ! -f /usr/scriptpkg1.posttrans"
echo "ok no embarrassing crud leftover"
2016-08-18 00:15:30 +03:00
# let's check that the group was successfully added
vm_cmd getent group scriptpkg1
echo "ok group scriptpkg1 active"
2017-01-10 17:35:58 +03:00
2017-07-02 16:22:33 +03:00
vm_has_files "/usr/lib/rpmostreetestinterp"
echo "ok interp"
2017-08-30 14:16:46 +03:00
# cleanup
vm_rpmostree uninstall scriptpkg1
vm_reboot
# post ordering
vm_build_rpm postorder1 \
post 'touch /usr/share/postorder1.post' \
posttrans 'test -f /usr/share/postorder1.post && test -f /usr/share/postorder2.post'
vm_build_rpm postorder2 \
requires 'postorder1' \
post 'touch /usr/share/postorder2.post' \
posttrans 'test -f /usr/share/postorder1.post && test -f /usr/share/postorder2.post'
vm_rpmostree install postorder{ 1,2}
vm_rpmostree cleanup -p
echo "ok post ordering"
2017-07-02 16:22:33 +03:00
2017-09-06 03:36:17 +03:00
# lua should (currently) fail
vm_build_rpm luapkg \
post_args "-p <lua>" \
post 'posix.stat("/")'
if vm_rpmostree install luapkg 2>err.txt; then
assert_not_reached "lua post?"
fi
assert_file_has_content_literal err.txt "unsupported <lua> script in '%post'"
echo "ok lua %post"
2017-08-30 14:16:46 +03:00
# script expansion
2017-07-13 03:50:08 +03:00
vm_build_rpm scriptpkg2 \
post_args "-e" \
post 'echo %%{_prefix} > /usr/lib/prefixtest.txt'
vm_build_rpm scriptpkg3 \
post 'echo %%{_prefix} > /usr/lib/noprefixtest.txt'
vm_rpmostree pkg-add scriptpkg{ 2,3}
2021-03-06 18:01:02 +03:00
vm_rpmostree ex livefs --allow-replacement
2017-07-13 03:50:08 +03:00
vm_cmd cat /usr/lib/noprefixtest.txt > noprefixtest.txt
assert_file_has_content noprefixtest.txt '%{_prefix}'
vm_cmd cat /usr/lib/prefixtest.txt > prefixtest.txt
assert_file_has_content prefixtest.txt "/usr"
echo "ok script expansion"
2017-08-30 03:15:28 +03:00
# script overrides (also one that expands)
vm_build_rpm rpmostree-lua-override-test \
post_args "-p <lua>" \
post 'posix.stat("/")'
vm_build_rpm rpmostree-lua-override-test-expand \
post_args "-e -p <lua>" \
post 'posix.stat("/")'
vm_rpmostree install rpmostree-lua-override-test{ ,-expand}
2021-03-06 18:01:02 +03:00
vm_rpmostree ex livefs --allow-replacement
2017-08-30 03:15:28 +03:00
vm_cmd cat /usr/share/rpmostree-lua-override-test > lua-override.txt
assert_file_has_content lua-override.txt _install_langs
vm_cmd rpm --eval '%{_install_langs}' > install-langs.txt
vm_cmd cat /usr/share/rpmostree-lua-override-test-expand > lua-override-expand.txt
diff -u install-langs.txt lua-override-expand.txt
echo "ok script override"
2018-11-22 18:15:32 +03:00
vm_rpmostree reset
2017-07-07 17:45:10 +03:00
vm_reboot
2018-07-13 19:22:05 +03:00
vm_rpmostree cleanup -pr
2017-07-07 17:45:10 +03:00
# File triggers are Fedora+
if ! vm_cmd grep -q 'ID=.*centos' /etc/os-release; then
# We use /usr/share/licenses since it's small predictable content
license_combos = "zlib-rpm systemd-tar-rpm sed-tzdata"
license_un_combos = "zlib systemd-rpm"
vm_build_rpm scriptpkg4 \
transfiletriggerin "/usr/share/licenses/zlib /usr/share/licenses/rpm" 'sort >/usr/share/transfiletriggerin-license-zlib-rpm.txt' \
transfiletriggerun "/usr/share/licenses/zlib" 'sort >/usr/share/transfiletriggerun-license-zlib.txt'
vm_build_rpm scriptpkg5 \
transfiletriggerin "/usr/share/licenses/systemd /usr/share/licenses/rpm /usr/share/licenses/tar" 'sort >/usr/share/transfiletriggerin-license-systemd-tar-rpm.txt' \
transfiletriggerun "/usr/share/licenses/systemd /usr/share/licenses/rpm" 'sort >/usr/share/transfiletriggerun-license-systemd-rpm.txt' \
transfiletriggerin2 "/usr/share/licenses/sed /usr/share/licenses/tzdata" 'sort >/usr/share/transfiletriggerin-license-sed-tzdata.txt'
vm_rpmostree pkg-add scriptpkg{ 4,5}
2021-03-06 18:01:02 +03:00
vm_rpmostree ex livefs --allow-replacement
2017-07-07 17:45:10 +03:00
for combo in ${ license_combos } ; do
vm_cmd cat /usr/share/transfiletriggerin-license-${ combo } .txt > transfiletriggerin-license-${ combo } .txt
rm -f transfiletriggerin-fs-${ combo } .txt.tmp
( for path in $( echo ${ combo } | sed -e 's,-, ,g' ) ; do
vm_cmd find /usr/share/licenses/${ path } -type f
done ) | sort > transfiletriggerin-fs-license-${ combo } .txt
diff -u transfiletriggerin-license-${ combo } .txt transfiletriggerin-fs-license-${ combo } .txt
done
for combo in ${ license_un_combos } ; do
vm_cmd test '!' -f /usr/share/licenses/transfiletriggerun-license-${ combo } .txt
done
# We really need a reset command to go back to the base layer
vm_rpmostree uninstall scriptpkg{ 4,5}
echo "ok transfiletriggerin"
fi
2017-12-15 17:32:19 +03:00
# Should work now that we're using --copyup
# https://github.com/projectatomic/rpm-ostree/pull/1171
vm_build_rpm rofiles-copyup \
2018-01-12 19:05:05 +03:00
post "echo XXXcopyupXXX >> /usr/share/rpm-ostree/treefile.json"
2017-12-15 17:32:19 +03:00
vm_rpmostree install rofiles-copyup
2018-01-12 19:05:05 +03:00
vm_cmd cat $( vm_get_deployment_root 0) /usr/share/rpm-ostree/treefile.json > out.txt
assert_file_has_content out.txt "XXXcopyupXXX"
# use posttrans to switch things up
vm_build_rpm rofiles-copyup-overwrite requires rofiles-copyup \
posttrans "echo XXXoverwriteXXX > /usr/share/rpm-ostree/treefile.json"
vm_rpmostree install rofiles-copyup-overwrite
vm_cmd cat $( vm_get_deployment_root 0) /usr/share/rpm-ostree/treefile.json > out.txt
assert_file_has_content out.txt "XXXoverwriteXXX"
assert_not_file_has_content out.txt "XXXcopyupXXX"
vm_rpmostree uninstall rofiles-copyup rofiles-copyup-overwrite
echo "ok copyup scriptlets"
2017-07-20 23:51:40 +03:00
2017-12-06 01:14:18 +03:00
# Test cancellation via having a script hang; we interrupt directly by sending
# SIGINT to the client binary.
2017-09-29 20:09:38 +03:00
vm_build_rpm post-that-hangs \
post "echo entering post-that-hangs-infloop 1>&2; while true; do sleep 1h; done"
2017-12-06 01:14:18 +03:00
background_install_post_that_hangs( ) {
local cursor = " $1 "
# use a systemd transient service as an easy way to run in the background; be
# sure any previous failed instances are cleaned up
vm_cmd systemctl stop vmcheck-install-hang || true
vm_cmd systemctl reset-failed vmcheck-install-hang || true
vm_cmd systemd-run --unit vmcheck-install-hang rpm-ostree install post-that-hangs
if ! vm_wait_content_after_cursor " ${ cursor } " "entering post-that-hangs-infloop" ; then
vm_cmd systemctl stop vmcheck-install-hang || true
assert_not_reached "failed to wait for post-that-hangs"
fi
}
cursor = $( vm_get_journal_cursor)
background_install_post_that_hangs " ${ cursor } "
2017-09-29 20:09:38 +03:00
vm_cmd pkill --signal INT -f "'rpm-ostree install post-that-hangs'"
# Wait for our expected result
vm_wait_content_after_cursor " ${ cursor } " "Txn.*failed.*Running %post for post-that-hangs"
# Forcibly restart now to avoid any races with the txn finally exiting
vm_cmd systemctl restart rpm-ostreed
2017-12-06 01:14:18 +03:00
echo "ok cancel infinite post via SIGINT"
# Test `rpm-ostree cancel` (which is the same as doing a Ctrl-C on the client)
cursor = $( vm_get_journal_cursor)
background_install_post_that_hangs " ${ cursor } "
vm_rpmostree cancel
vm_wait_content_after_cursor " ${ cursor } " "Txn.*failed.*Running %post for post-that-hangs"
# Forcibly restart now to avoid any races with the txn finally exiting
vm_cmd systemctl restart rpm-ostreed
echo "ok cancel infinite post via `rpm-ostree cancel`"
2017-09-29 20:09:38 +03:00
# Test rm -rf /!
Rework vmcheck to use `kola spawn`, move off of PAPR
There's a lot going on here, but essentially:
1. We change the `vmcheck` model so that it always operates on an
immutable base image. It takes that image and dynamically launches a
separate VM for each test using `kola spawn`. This means we can drop
a lot of hacks around re-using the same VMs.
2. Following from 1., `vmoverlay` now takes as input a base image,
overlays the built rpm-ostree bits, then creates a new base image. Of
course, we don't have to do this in CI, because we build FCOS with
the freshly built RPMs (so it uses `SKIP_VMOVERLAY=1`). `vmoverlay`
then will be more for the developer case where one doesn't want to
iterate via `cosa build` to test rpm-ostree changes. I say "will"
because the functionality doesn't exist yet; I'd like to enhance
`cosa dev-overlay` to do this. (Note `vmsync` should still works just
as before too.)
3. `vmcheck` can be run without building the tree first, as
`tests/vmcheck.sh`. The `make vmcheck` target still exists though for
finger compatibility and better meshing with `vmoverlay` in the
developer case.
What's really nice about using kola spawn is that it takes care of a lot
of things for us, such as the qemu command, journal and console
gathering, and SSH.
Similarly to the compose testsuites, we're using parallel here to run
multiple vmcheck tests at once. (On developer laptops, we cap
parallelism at `$(nproc) - 1`).
2019-12-13 20:23:41 +03:00
vm_cmd touch /home/core/somedata /tmp/sometmpfile /var/tmp/sometmpfile
2017-07-20 23:51:40 +03:00
vm_build_rpm rmrf post "rm --no-preserve-root -rf / &>/dev/null || true"
if vm_rpmostree install rmrf 2>err.txt; then
assert_not_reached "rm -rf / worked? Uh oh."
fi
Rework vmcheck to use `kola spawn`, move off of PAPR
There's a lot going on here, but essentially:
1. We change the `vmcheck` model so that it always operates on an
immutable base image. It takes that image and dynamically launches a
separate VM for each test using `kola spawn`. This means we can drop
a lot of hacks around re-using the same VMs.
2. Following from 1., `vmoverlay` now takes as input a base image,
overlays the built rpm-ostree bits, then creates a new base image. Of
course, we don't have to do this in CI, because we build FCOS with
the freshly built RPMs (so it uses `SKIP_VMOVERLAY=1`). `vmoverlay`
then will be more for the developer case where one doesn't want to
iterate via `cosa build` to test rpm-ostree changes. I say "will"
because the functionality doesn't exist yet; I'd like to enhance
`cosa dev-overlay` to do this. (Note `vmsync` should still works just
as before too.)
3. `vmcheck` can be run without building the tree first, as
`tests/vmcheck.sh`. The `make vmcheck` target still exists though for
finger compatibility and better meshing with `vmoverlay` in the
developer case.
What's really nice about using kola spawn is that it takes care of a lot
of things for us, such as the qemu command, journal and console
gathering, and SSH.
Similarly to the compose testsuites, we're using parallel here to run
multiple vmcheck tests at once. (On developer laptops, we cap
parallelism at `$(nproc) - 1`).
2019-12-13 20:23:41 +03:00
vm_cmd test -f /home/core/somedata -a -f /etc/passwd -a -f /tmp/sometmpfile -a -f /var/tmp/sometmpfile
2017-07-20 23:51:40 +03:00
# This is the error today, we may improve it later
2021-03-21 16:30:48 +03:00
assert_file_has_content err.txt 'error: Sanity-checking final rootfs:.*bwrap(/usr/bin/true)'
2017-10-06 21:43:39 +03:00
echo "ok impervious to rm -rf post"
2017-09-20 18:11:09 +03:00
2020-12-07 21:42:23 +03:00
cursor = $( vm_get_journal_cursor)
vm_build_rpm post-query-rpmdb post "rpm -q bash"
if vm_rpmostree install post-query-rpmdb; then
assert_not_reached "Ran rpm -q bash in %post"
fi
vm_assert_journal_has_content " $cursor " 'rpm-ostree(post-query-rpmdb.post).*package bash is not installed'
echo "ok post that calls rpm -q"
2017-11-09 22:24:15 +03:00
# capabilities
vm_build_rpm test-cap-drop post "capsh --print > /usr/share/rpmostree-capsh.txt"
vm_rpmostree install test-cap-drop
2021-03-06 18:01:02 +03:00
vm_rpmostree ex livefs --allow-replacement
2017-11-09 22:24:15 +03:00
vm_cmd cat /usr/share/rpmostree-capsh.txt > caps.txt
assert_not_file_has_content caps.test '^Current: =.*cap_sys_admin'
2017-12-15 17:32:19 +03:00
# See also rofiles-copyup above
2017-09-20 18:11:09 +03:00
vm_build_rpm etc-mutate post "truncate -s 0 /etc/selinux/config"
2017-12-15 17:32:19 +03:00
vm_rpmostree install etc-mutate
vm_rpmostree uninstall etc-mutate
2017-09-20 18:11:09 +03:00
2017-12-15 18:24:54 +03:00
# SYSTEMD_OFFLINE
vm_build_rpm test-systemd-offline post 'test "${SYSTEMD_OFFLINE}" = 1'
vm_rpmostree install test-systemd-offline
vm_rpmostree uninstall test-systemd-offline
2017-09-20 18:11:09 +03:00
# Ensure this is reset; at least in the Vagrant box with
# fedora-atomic:fedora/26/x86_64/atomic-host
# Version: 26.131 (2017-09-19 22:29:04)
# Commit: 98088cb6ed2a4b3f7e4e7bf6d34f9e137c296bc43640b4c1967631f22fe1802f
# it starts out modified - the modification is just deletion of trailing
# whitespace.
vm_cmd cp /{ usr/,} etc/selinux/config
vm_build_rpm etc-copy post " cp /etc/selinux/config{,.new}
echo '# etc-copy comment' >> /etc/selinux/config.new
mv /etc/selinux/config{ .new,} "
vm_rpmostree install etc-copy
root = $( vm_get_deployment_root 0)
vm_cmd cat $root /etc/selinux/config > new-config.txt
assert_file_has_content new-config.txt etc-copy
vm_rpmostree cleanup -p
echo "ok etc rofiles"