2011-10-13 00:46:23 +04:00
# Source library for shell script tests
#
# Copyright (C) 2011 Colin Walters <walters@verbum.org>
#
2018-01-30 22:26:26 +03:00
# SPDX-License-Identifier: LGPL-2.0+
#
2011-11-10 22:17:04 +04:00
# 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.
2011-10-13 00:46:23 +04:00
#
2011-11-10 22:17:04 +04:00
# This library is distributed in the hope that it will be useful,
2011-10-13 00:46:23 +04:00
# but WITHOUT ANY WARRANTY; without even the implied warranty of
2011-11-10 22:17:04 +04:00
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
2011-10-13 00:46:23 +04:00
#
2011-11-10 22:17:04 +04:00
# 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.
2011-10-13 00:46:23 +04:00
2017-04-24 18:01:20 +03:00
dn = $( dirname $0 )
2016-03-31 20:29:44 +03:00
if [ -n " ${ G_TEST_SRCDIR :- } " ] ; then
test_srcdir = " ${ G_TEST_SRCDIR } /tests "
else
test_srcdir = $( dirname $0 )
fi
if [ -n " ${ G_TEST_BUILDDIR :- } " ] ; then
test_builddir = " ${ G_TEST_BUILDDIR } /tests "
else
test_builddir = $( dirname $0 )
fi
2017-04-24 21:40:06 +03:00
. ${ test_srcdir } /libtest-core.sh
2016-03-02 18:28:04 +03:00
2019-06-13 23:57:17 +03:00
# Array of expressions to execute when exiting. Each expression should
# be a single string (quoting if necessary) that will be eval'd. To add
# a command to run on exit, append to the libtest_exit_cmds array like
# libtest_exit_cmds+=(expr).
libtest_exit_cmds = ( )
run_exit_cmds( ) {
for expr in " ${ libtest_exit_cmds [@] } " ; do
eval " ${ expr } " || true
done
}
trap run_exit_cmds EXIT
2021-04-18 14:16:45 +03:00
report_err ( ) {
local exit_status = " $? "
{ { local BASH_XTRACEFD = 3; } 2> /dev/null
echo " Unexpected nonzero exit status $exit_status while running: $BASH_COMMAND " >& 2
} 3> /dev/null
}
trap report_err ERR
2018-06-28 14:10:13 +03:00
save_core( ) {
if [ -e core ] ; then
cp core " $test_srcdir /core "
fi
}
2019-06-13 23:57:17 +03:00
libtest_exit_cmds += ( save_core)
2018-06-28 14:10:13 +03:00
2013-05-01 23:26:21 +04:00
test_tmpdir = $( pwd )
2011-10-13 00:46:23 +04:00
2016-03-18 15:43:53 +03:00
# Sanity check that we're in a tmpdir that has
# just .testtmp (created by tap-driver for `make check`,
# or nothing at all (as ginstest-runner does)
if ! test -f .testtmp; then
files = $( ls)
if test -n " ${ files } " ; then
2016-03-31 19:52:57 +03:00
ls -l
2016-03-18 15:43:53 +03:00
assert_not_reached " test tmpdir= ${ test_tmpdir } is not empty; run this test via \`make check TESTS=\`, not directly "
fi
2016-03-31 19:52:57 +03:00
# Remember that this is an acceptable test $(pwd), for the benefit of
# C and JS tests which may source this file again
touch .testtmp
2016-03-02 18:05:08 +03:00
fi
2016-03-02 18:28:04 +03:00
# Also, unbreak `tar` inside `make check`...Automake will inject
# TAR_OPTIONS: --owner=0 --group=0 --numeric-owner presumably so that
# tarballs are predictable, except we don't want this in our tests.
unset TAR_OPTIONS
2016-02-19 19:58:08 +03:00
# Don't flag deployments as immutable so that test harnesses can
# easily clean up.
export OSTREE_SYSROOT_DEBUG = mutable-deployments
2021-04-19 20:00:20 +03:00
# By default, don't use a cache directory since it makes the tests racy.
# Tests that are explicitly testing the cache operation should unset
# this.
export OSTREE_SKIP_CACHE = 1
2019-06-19 17:49:32 +03:00
export TEST_GPG_KEYID_1 = "7FCA23D8472CDAFA"
export TEST_GPG_KEYFPR_1 = "5E65DE75AB1C501862D476347FCA23D8472CDAFA"
export TEST_GPG_KEYID_2 = "D8228CFECA950D41"
export TEST_GPG_KEYFPR_2 = "7B3B1020D74479687FDB2273D8228CFECA950D41"
export TEST_GPG_KEYID_3 = "0D15FAE7DF444D67"
export TEST_GPG_KEYFPR_3 = "7D29CF060B8269CDF63BFBDD0D15FAE7DF444D67"
2015-02-23 21:02:37 +03:00
2019-06-19 19:51:47 +03:00
# GPG when creating signatures demands a private writable
2015-02-23 21:02:37 +03:00
# homedir in order to create lockfiles. Work around
# this by copying locally.
2016-03-02 18:28:04 +03:00
echo " Copying gpghome to ${ test_tmpdir } "
2016-03-31 20:29:44 +03:00
cp -a " ${ test_srcdir } /gpghome " ${ test_tmpdir }
2016-06-12 12:51:11 +03:00
chmod -R u+w " ${ test_tmpdir } "
2019-06-19 19:51:47 +03:00
chmod 700 " ${ test_tmpdir } /gpghome "
2015-02-23 21:02:37 +03:00
export TEST_GPG_KEYHOME = ${ test_tmpdir } /gpghome
export OSTREE_GPG_HOME = ${ test_tmpdir } /gpghome/trusted
2013-09-03 05:43:49 +04:00
2017-09-28 21:57:33 +03:00
assert_has_setfattr( ) {
if ! which setfattr 2>/dev/null; then
fatal "no setfattr available to determine xattr support"
fi
}
_have_selinux_relabel = ''
have_selinux_relabel( ) {
assert_has_setfattr
if test " ${ _have_selinux_relabel } " = '' ; then
pushd ${ test_tmpdir }
echo testlabel > testlabel.txt
selinux_xattr = security.selinux
if getfattr --encoding= base64 -n ${ selinux_xattr } testlabel.txt >label.txt 2>err.txt; then
label = $( grep -E -e " ^ ${ selinux_xattr } = " < label.txt | sed -e " s, ${ selinux_xattr } =,, " )
if setfattr -n ${ selinux_xattr } -v ${ label } testlabel.txt 2>err.txt; then
echo " SELinux enabled in $( pwd ) , and have privileges to relabel "
_have_selinux_relabel = yes
else
sed -e 's/^/# /' < err.txt >& 2
echo "Found SELinux label, but unable to set (Unprivileged Docker?)"
_have_selinux_relabel = no
fi
else
sed -e 's/^/# /' < err.txt >& 2
echo "Unable to retrieve SELinux label, assuming disabled"
_have_selinux_relabel = no
fi
popd
fi
test ${ _have_selinux_relabel } = yes
}
# just globally turn off xattrs if we can't manipulate security xattrs; this is
# the case for overlayfs -- really, we should only enforce this for tests that
# use bare repos; separate from other tests that should check for user xattrs
# support
# see https://github.com/ostreedev/ostree/issues/758
# and https://github.com/ostreedev/ostree/pull/1217
echo -n checking for xattrs...
if ! have_selinux_relabel; then
export OSTREE_SYSROOT_DEBUG = " ${ OSTREE_SYSROOT_DEBUG } ,no-xattrs "
export OSTREE_NO_XATTRS = 1
fi
2017-03-24 17:35:59 +03:00
echo done
2016-01-27 19:44:10 +03:00
if test -n " ${ OT_TESTS_DEBUG :- } " ; then
2011-11-09 14:28:13 +04:00
set -x
fi
2016-12-08 20:50:20 +03:00
# This is substituted by the build for installed tests
BUILT_WITH_ASAN = ""
2021-02-03 17:48:49 +03:00
if test -n " ${ ASAN_OPTIONS :- } " ; then
BUILT_WITH_ASAN = 1
fi
2016-12-08 20:50:20 +03:00
2016-01-27 19:44:10 +03:00
if test -n " ${ OT_TESTS_VALGRIND :- } " ; then
2016-06-10 14:28:08 +03:00
CMD_PREFIX = " env G_SLICE=always-malloc OSTREE_SUPPRESS_SYNCFS=1 valgrind -q --error-exitcode=1 --leak-check=full --num-callers=30 --suppressions= ${ test_srcdir } /glib.supp --suppressions= ${ test_srcdir } /ostree.supp "
2015-06-02 05:34:14 +03:00
else
2016-06-17 16:43:51 +03:00
# In some cases the LD_PRELOAD may cause obscure problems,
# e.g. right now it breaks for me with -fsanitize=address, so
# let's allow users to skip it.
2016-12-08 20:50:20 +03:00
if test -z " ${ OT_SKIP_READDIR_RAND :- } " && test -z " ${ BUILT_WITH_ASAN :- } " ; then
2016-06-17 16:43:51 +03:00
CMD_PREFIX = " env LD_PRELOAD= ${ test_builddir } /libreaddir-rand.so "
else
CMD_PREFIX = ""
fi
2012-05-04 18:04:32 +04:00
fi
2016-12-30 22:18:34 +03:00
if test -n " ${ OSTREE_UNINSTALLED :- } " ; then
OSTREE_HTTPD = ${ OSTREE_UNINSTALLED } /ostree-trivial-httpd
else
2017-05-04 22:58:07 +03:00
# trivial-httpd is now in $libexecdir by default, which we don't
# know at this point. Fortunately, libtest.sh is also in
# $libexecdir, so make an educated guess. If it's not found, assume
# it's still runnable as "ostree trivial-httpd".
if [ -x " ${ test_srcdir } /../../libostree/ostree-trivial-httpd " ] ; then
OSTREE_HTTPD = " ${ CMD_PREFIX } ${ test_srcdir } /../../libostree/ostree-trivial-httpd "
else
OSTREE_HTTPD = " ${ CMD_PREFIX } ostree trivial-httpd "
fi
2016-12-30 22:18:34 +03:00
fi
2017-06-12 20:59:33 +03:00
files_are_hardlinked( ) {
2017-06-29 04:39:16 +03:00
inode1 = $( stat -c %i $1 )
inode2 = $( stat -c %i $2 )
test -n " ${ inode1 } " && test -n " ${ inode2 } "
[ " ${ inode1 } " = = " ${ inode2 } " ]
2017-06-12 20:59:33 +03:00
}
2016-04-22 19:39:54 +03:00
assert_files_hardlinked( ) {
2017-06-29 04:39:16 +03:00
if ! files_are_hardlinked " $1 " " $2 " ; then
2017-01-17 18:16:31 +03:00
fatal " Files ' $1 ' and ' $2 ' are not hardlinked "
2016-04-22 19:39:54 +03:00
fi
}
2011-11-01 06:42:14 +04:00
setup_test_repository ( ) {
mode = $1
shift
2011-10-15 08:45:07 +04:00
2011-11-01 06:42:14 +04:00
oldpwd = ` pwd `
2011-10-15 09:22:42 +04:00
2017-03-26 12:03:47 +03:00
COMMIT_ARGS = ""
if [ $mode = = "bare-user-only" ] ; then
COMMIT_ARGS = "--owner-uid=0 --owner-gid=0 --no-xattrs --canonical-permissions"
fi
2011-11-09 03:11:42 +04:00
cd ${ test_tmpdir }
2017-09-28 21:56:17 +03:00
rm -rf repo
2017-03-24 17:35:59 +03:00
if test -n " ${ mode } " ; then
ostree_repo_init repo --mode= ${ mode }
2011-11-09 03:11:42 +04:00
else
2017-03-24 17:35:59 +03:00
ostree_repo_init repo
2011-11-09 03:11:42 +04:00
fi
2017-03-24 17:35:59 +03:00
ot_repo = " --repo= $( pwd ) /repo "
export OSTREE = " ${ CMD_PREFIX } ostree ${ ot_repo } "
2011-11-09 03:11:42 +04:00
cd ${ test_tmpdir }
2017-09-19 20:37:58 +03:00
local oldumask = " $( umask ) "
umask 022
2017-09-28 21:56:17 +03:00
rm -rf files
2011-10-15 09:22:42 +04:00
mkdir files
cd files
2011-11-01 06:42:14 +04:00
ot_files = ` pwd `
2011-10-15 09:22:42 +04:00
export ht_files
2011-11-01 06:42:14 +04:00
ln -s nosuchfile somelink
2011-10-15 09:22:42 +04:00
echo first > firstfile
2011-11-09 03:11:42 +04:00
cd ${ test_tmpdir } /files
2017-03-26 12:03:47 +03:00
$OSTREE commit ${ COMMIT_ARGS } -b test2 -s "Test Commit 1" -m "Commit body first"
2011-11-09 03:11:42 +04:00
2011-10-15 09:22:42 +04:00
mkdir baz
echo moo > baz/cow
2017-06-02 17:09:23 +03:00
echo mooro > baz/cowro
chmod 600 baz/cowro
2011-10-15 09:22:42 +04:00
echo alien > baz/saucer
mkdir baz/deeper
echo hi > baz/deeper/ohyeah
2017-06-02 17:09:23 +03:00
echo hix > baz/deeper/ohyeahx
chmod 755 baz/deeper/ohyeahx
2011-11-01 06:42:14 +04:00
ln -s nonexistent baz/alink
2011-10-15 09:22:42 +04:00
mkdir baz/another/
echo x > baz/another/y
2017-09-19 20:37:58 +03:00
umask " ${ oldumask } "
2011-10-15 09:22:42 +04:00
2011-11-09 03:11:42 +04:00
cd ${ test_tmpdir } /files
2017-03-26 12:03:47 +03:00
$OSTREE commit ${ COMMIT_ARGS } -b test2 -s "Test Commit 2" -m "Commit body second"
2011-11-04 07:08:28 +04:00
$OSTREE fsck -q
2011-11-01 06:42:14 +04:00
cd $oldpwd
2011-10-15 08:45:07 +04:00
}
2017-03-24 17:35:59 +03:00
# A wrapper which also possibly disables xattrs for CI testing
ostree_repo_init( ) {
repo = $1
shift
${ CMD_PREFIX } ostree --repo= ${ repo } init " $@ "
if test -n " ${ OSTREE_NO_XATTRS :- } " ; then
echo -e 'disable-xattrs=true\n' >> ${ repo } /config
fi
}
2017-10-30 21:17:10 +03:00
# The original one; use setup_fake_remote_repo2 for newer code,
# down the line we'll try to port tests.
2011-11-01 04:24:38 +04:00
setup_fake_remote_repo1( ) {
2018-03-14 17:36:48 +03:00
mode = $1 ; shift
commit_opts = ${ 1 :- }
[ $# -eq 0 ] || shift
2011-11-01 04:24:38 +04:00
oldpwd = ` pwd `
mkdir ostree-srv
cd ostree-srv
mkdir gnomerepo
2017-03-24 17:35:59 +03:00
ostree_repo_init gnomerepo --mode= $mode
2011-11-01 04:24:38 +04:00
mkdir gnomerepo-files
cd gnomerepo-files
echo first > firstfile
mkdir baz
echo moo > baz/cow
echo alien > baz/saucer
2015-04-30 10:36:27 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /ostree-srv/gnomerepo commit $commit_opts --add-metadata-string version = 3.0 -b main -s "A remote commit" -m "Some Commit body"
2011-11-01 04:24:38 +04:00
mkdir baz/deeper
2015-04-30 10:36:27 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /ostree-srv/gnomerepo commit $commit_opts --add-metadata-string version = 3.1 -b main -s "Add deeper"
2011-11-01 04:24:38 +04:00
echo hi > baz/deeper/ohyeah
mkdir baz/another/
echo x > baz/another/y
2015-04-30 10:36:27 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /ostree-srv/gnomerepo commit $commit_opts --add-metadata-string version = 3.2 -b main -s "The rest"
2011-11-01 04:24:38 +04:00
cd ..
rm -rf gnomerepo-files
cd ${ test_tmpdir }
mkdir ${ test_tmpdir } /httpd
cd httpd
2013-07-06 00:12:10 +04:00
ln -s ${ test_tmpdir } /ostree-srv ostree
2018-03-14 17:36:48 +03:00
${ OSTREE_HTTPD } --autoexit --log-file $( pwd ) /httpd.log --daemonize -p ${ test_tmpdir } /httpd-port " $@ "
2013-07-06 00:12:10 +04:00
port = $( cat ${ test_tmpdir } /httpd-port)
echo " http://127.0.0.1: ${ port } " > ${ test_tmpdir } /httpd-address
2011-11-01 04:24:38 +04:00
cd ${ oldpwd }
2011-11-04 07:08:28 +04:00
2015-03-03 15:13:54 +03:00
export OSTREE = " ${ CMD_PREFIX } ostree --repo=repo "
2011-11-01 04:24:38 +04:00
}
2013-06-29 19:45:53 +04:00
2017-10-30 21:17:10 +03:00
# Newer version of the above with more "real" data
setup_fake_remote_repo2( ) {
mode = $1
commit_opts = ${ 2 :- }
args = ${ 3 :- }
shift
oldpwd = ` pwd `
mkdir ostree-srv
cd ostree-srv
mkdir repo
ostree_repo_init repo --mode= $mode
# Backcompat
ln -sr repo gnomerepo
# Initialize content
mkdir files
cd files
mkdir -p usr/{ etc,bin,lib,share}
ln -sr usr/bin bin
ln -sr usr/lib lib
tar xf ${ test_srcdir } /fah-deltadata-old.tar.xz
remote_ref = exampleos/42/x86_64/main
cd ..
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /ostree-srv/repo commit \
--consume $commit_opts --add-metadata-string version = 42.0 -b ${ remote_ref } \
--tree= dir = files
test '!' -d files
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /ostree-srv/repo checkout -U ${ remote_ref } files
( cd files && tar xf ${ test_srcdir } /fah-deltadata-new.tar.xz)
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /ostree-srv/repo commit \
--consume $commit_opts --add-metadata-string version = 42.1 -b ${ remote_ref } \
--tree= dir = files
# And serve via HTTP
cd ${ test_tmpdir }
mkdir ${ test_tmpdir } /httpd
cd httpd
ln -s ${ test_tmpdir } /ostree-srv ostree
${ OSTREE_HTTPD } --autoexit --log-file $( pwd ) /httpd.log --daemonize -p ${ test_tmpdir } /httpd-port $args
port = $( cat ${ test_tmpdir } /httpd-port)
echo " http://127.0.0.1: ${ port } " > ${ test_tmpdir } /httpd-address
cd ${ oldpwd }
export OSTREE = " ${ CMD_PREFIX } ostree --repo=repo "
}
2013-09-01 01:04:48 +04:00
setup_os_boot_syslinux( ) {
# Stub syslinux configuration
mkdir -p sysroot/boot/loader.0
ln -s loader.0 sysroot/boot/loader
touch sysroot/boot/loader/syslinux.cfg
# And a compatibility symlink
mkdir -p sysroot/boot/syslinux
ln -s ../loader/syslinux.cfg sysroot/boot/syslinux/syslinux.cfg
}
2013-09-01 15:07:17 +04:00
setup_os_boot_uboot( ) {
# Stub U-Boot configuration
mkdir -p sysroot/boot/loader.0
ln -s loader.0 sysroot/boot/loader
touch sysroot/boot/loader/uEnv.txt
# And a compatibility symlink
ln -s loader/uEnv.txt sysroot/boot/uEnv.txt
}
2016-04-01 14:51:18 +03:00
setup_os_boot_grub2( ) {
grub2_options = $1
mkdir -p sysroot/boot/grub2/
ln -s ../loader/grub.cfg sysroot/boot/grub2/grub.cfg
export OSTREE_BOOT_PARTITION = "/boot"
case " $grub2_options " in
*ostree-grub-generator*)
cp ${ test_srcdir } /ostree-grub-generator ${ test_tmpdir }
chmod +x ${ test_tmpdir } /ostree-grub-generator
export OSTREE_GRUB2_EXEC = ${ test_tmpdir } /ostree-grub-generator
; ;
esac
}
2019-02-15 00:18:01 +03:00
setup_os_boot_configured_bootloader( ) {
bootloader_keyval = $1
${ CMD_PREFIX } ostree --repo= sysroot/ostree/repo config set ${ bootloader_keyval }
}
2013-06-29 19:45:53 +04:00
setup_os_repository ( ) {
mode = $1
shift
2017-08-04 22:58:41 +03:00
bootmode = $1
shift
2017-08-15 18:22:21 +03:00
bootdir = ${ 1 :- usr /lib/modules/3.6.0 }
2013-06-29 19:45:53 +04:00
oldpwd = ` pwd `
cd ${ test_tmpdir }
mkdir testos-repo
if test -n " $mode " ; then
2017-03-24 17:35:59 +03:00
ostree_repo_init testos-repo --mode= ${ mode }
2013-06-29 19:45:53 +04:00
else
2017-03-24 17:35:59 +03:00
ostree_repo_init testos-repo
2013-06-29 19:45:53 +04:00
fi
cd ${ test_tmpdir }
mkdir osdata
cd osdata
2017-08-19 03:51:10 +03:00
kver = 3.6.0
mkdir -p usr/bin ${ bootdir } usr/lib/modules/${ kver } usr/share usr/etc
2017-08-15 18:22:21 +03:00
kernel_path = ${ bootdir } /vmlinuz
2017-08-19 03:51:10 +03:00
initramfs_path = ${ bootdir } /initramfs.img
2019-10-29 23:45:29 +03:00
# the HMAC file is only in /usr/lib/modules
hmac_path = usr/lib/modules/${ kver } /.vmlinuz.hmac
2017-08-15 18:22:21 +03:00
# /usr/lib/modules just uses "vmlinuz", since the version is in the module
# directory name.
if [ [ $bootdir != usr/lib/modules/* ] ] ; then
2017-08-19 03:51:10 +03:00
kernel_path = ${ kernel_path } -${ kver }
initramfs_path = ${ bootdir } /initramfs-${ kver } .img
2017-08-15 18:22:21 +03:00
fi
echo "a kernel" > ${ kernel_path }
echo "an initramfs" > ${ initramfs_path }
2019-10-29 23:45:29 +03:00
echo "an hmac file" > ${ hmac_path }
2017-08-15 18:22:21 +03:00
bootcsum = $( cat ${ kernel_path } ${ initramfs_path } | sha256sum | cut -f 1 -d ' ' )
2013-06-29 19:45:53 +04:00
export bootcsum
2021-03-11 04:36:13 +03:00
bootable_flag = ""
2017-08-04 22:58:41 +03:00
# Add the checksum for legacy dirs (/boot, /usr/lib/ostree-boot), but not
# /usr/lib/modules.
2017-08-15 18:22:21 +03:00
if [ [ $bootdir != usr/lib/modules/* ] ] ; then
mv ${ kernel_path } { ,-${ bootcsum } }
mv ${ initramfs_path } { ,-${ bootcsum } }
2021-03-11 04:36:13 +03:00
else
bootable_flag = "--bootable"
2017-08-04 22:58:41 +03:00
fi
2013-06-29 19:45:53 +04:00
echo "an executable" > usr/bin/sh
echo "some shared data" > usr/share/langs.txt
echo "a library" > usr/lib/libfoo.so.0
ln -s usr/bin bin
cat > usr/etc/os-release <<EOF
NAME = TestOS
VERSION = 42
ID = testos
VERSION_ID = 42
PRETTY_NAME = "TestOS 42"
EOF
echo "a config file" > usr/etc/aconfigfile
mkdir -p usr/etc/NetworkManager
echo "a default daemon file" > usr/etc/NetworkManager/nm.conf
2013-10-15 22:11:43 +04:00
mkdir -p usr/etc/testdirectory
echo "a default daemon file" > usr/etc/testdirectory/test
2013-06-29 19:45:53 +04:00
2021-05-07 17:42:37 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /testos-repo commit ${ bootable_flag } --add-metadata-string version = 1.0.9 -b testos/buildmain/x86_64-runtime -s "Build"
2017-08-15 18:22:21 +03:00
2014-02-21 03:25:56 +04:00
# Ensure these commits have distinct second timestamps
sleep 2
2013-06-29 19:45:53 +04:00
echo "a new executable" > usr/bin/sh
2021-05-07 17:42:37 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /testos-repo commit ${ bootable_flag } --add-metadata-string version = 1.0.10 -b testos/buildmain/x86_64-runtime -s "Build"
2013-06-29 19:45:53 +04:00
2014-01-19 02:42:24 +04:00
cd ${ test_tmpdir }
2019-10-31 20:09:36 +03:00
rm -rf osdata-devel
mkdir osdata-devel
tar -C osdata -cf - . | tar -C osdata-devel -xf -
2014-01-19 02:42:24 +04:00
cd osdata-devel
mkdir -p usr/include
echo "a development header" > usr/include/foo.h
2021-05-07 17:42:37 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /testos-repo commit ${ bootable_flag } --add-metadata-string version = 1.0.9 -b testos/buildmain/x86_64-devel -s "Build"
2014-01-19 02:42:24 +04:00
2015-03-03 15:13:54 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /testos-repo fsck -q
2013-06-29 19:45:53 +04:00
cd ${ test_tmpdir }
mkdir sysroot
2015-07-14 20:30:05 +03:00
export OSTREE_SYSROOT = sysroot
${ CMD_PREFIX } ostree admin init-fs sysroot
checkout: Add SELinux labeling for checkout, use in deploy
This is a variant of the efforts in https://github.com/ostreedev/ostree/pull/741
Working on `rpm-ostree livefs`, I realized though I needed to just
check out *new* files directly into the live `/etc` (and possibly
delete obsolete files).
The way the current `/etc` merge works is fundamentally different from
that. So my plan currently is to probably do something like:
- Compute diff
- Check out each *new* file individually (as a copy)
- Optionally delete obsolete files
Also, a few other things become more important - in the current deploy code, we
copy all of the files, then relabel them. But we shouldn't expose to *live*
systems the race conditions of doing that, plus we should only relabel files we
checked out.
By converting the deploy's /etc code to use this, we fix the same TODO item
there around atomically having the label set up as we create files. And further,
if we kill the `/var` relabeling which I think is unnecessary since Anaconda
does it, we could delete large chunks of code there.
In the implementation, there are two types of things: regular files, and
symlinks. For regular files, in the `O_TMPFILE` case, we have the ability to
do *everything* atomically (including SELinux labeling) before linking it into
place. So let's just use that. For symlinks, we use `setfscreatecon()`.
Closes: #797
Approved by: jlebon
2017-04-14 20:17:15 +03:00
if test -n " ${ OSTREE_NO_XATTRS :- } " ; then
echo -e 'disable-xattrs=true\n' >> sysroot/ostree/repo/config
fi
2015-07-14 20:30:05 +03:00
${ CMD_PREFIX } ostree admin os-init testos
2013-06-29 19:45:53 +04:00
2013-09-01 15:07:17 +04:00
case $bootmode in
"syslinux" )
setup_os_boot_syslinux
; ;
"uboot" )
setup_os_boot_uboot
; ;
2016-04-01 14:51:18 +03:00
*grub2*)
setup_os_boot_grub2 " ${ bootmode } "
2019-02-15 00:18:01 +03:00
; ;
sysroot\. bootloader*)
setup_os_boot_configured_bootloader " ${ bootmode } "
2016-04-01 14:51:18 +03:00
; ;
2013-09-01 15:07:17 +04:00
esac
2017-08-15 18:22:21 +03:00
2014-02-21 03:25:56 +04:00
cd ${ test_tmpdir }
mkdir ${ test_tmpdir } /httpd
cd httpd
ln -s ${ test_tmpdir } ostree
2016-12-30 22:18:34 +03:00
${ OSTREE_HTTPD } --autoexit --daemonize -p ${ test_tmpdir } /httpd-port
2014-02-21 03:25:56 +04:00
port = $( cat ${ test_tmpdir } /httpd-port)
echo " http://127.0.0.1: ${ port } " > ${ test_tmpdir } /httpd-address
cd ${ oldpwd }
2013-06-29 19:45:53 +04:00
}
2020-05-17 17:27:45 +03:00
timestamp_of_commit( )
{
date --date= " $( ostree --repo= $1 show $2 | grep -Ee '^Date: ' | sed -e 's,^Date: *,,' ) " '+%s'
}
2013-06-29 19:45:53 +04:00
os_repository_new_commit ( )
{
2016-01-27 19:44:10 +03:00
boot_checksum_iteration = ${ 1 :- 0 }
content_iteration = ${ 2 :- 0 }
2021-05-07 17:42:37 +03:00
branch = ${ 3 :- testos /buildmain/x86_64-runtime }
2019-03-01 17:16:55 +03:00
export version = ${ 4 :- $( date " +%Y%m%d. ${ content_iteration } " ) }
2013-09-20 16:09:06 +04:00
echo " BOOT ITERATION: $boot_checksum_iteration "
2013-06-29 19:45:53 +04:00
cd ${ test_tmpdir } /osdata
2017-08-19 03:51:10 +03:00
kver = 3.6.0
if test -f usr/lib/modules/${ kver } /vmlinuz; then
bootdir = usr/lib/modules/${ kver }
2017-08-15 18:22:21 +03:00
else
if test -d usr/lib/ostree-boot; then
bootdir = usr/lib/ostree-boot
else
bootdir = boot
fi
2017-08-04 22:58:41 +03:00
fi
rm ${ bootdir } /*
2017-08-15 18:22:21 +03:00
kernel_path = ${ bootdir } /vmlinuz
2017-08-19 03:51:10 +03:00
initramfs_path = ${ bootdir } /initramfs.img
2017-08-15 18:22:21 +03:00
if [ [ $bootdir != usr/lib/modules/* ] ] ; then
2017-08-19 03:51:10 +03:00
kernel_path = ${ kernel_path } -${ kver }
initramfs_path = ${ bootdir } /initramfs-${ kver } .img
2017-08-15 18:22:21 +03:00
fi
echo " new: a kernel ${ boot_checksum_iteration } " > ${ kernel_path }
echo " new: an initramfs ${ boot_checksum_iteration } " > ${ initramfs_path }
bootcsum = $( cat ${ kernel_path } ${ initramfs_path } | sha256sum | cut -f 1 -d ' ' )
2013-06-29 19:45:53 +04:00
export bootcsum
2017-08-15 18:22:21 +03:00
if [ [ $bootdir != usr/lib/modules/* ] ] ; then
mv ${ kernel_path } { ,-${ bootcsum } }
mv ${ initramfs_path } { ,-${ bootcsum } }
fi
2013-06-29 19:45:53 +04:00
echo "a new default config file" > usr/etc/a-new-default-config-file
mkdir -p usr/etc/new-default-dir
echo "a new default dir and file" > usr/etc/new-default-dir/moo
2013-10-04 02:33:18 +04:00
echo " content iteration ${ content_iteration } " > usr/bin/content-iteration
2017-05-03 18:36:48 +03:00
${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /testos-repo commit --add-metadata-string " version= ${ version } " -b $branch -s "Build"
2020-05-17 17:27:45 +03:00
if ${ CMD_PREFIX } ostree --repo= ${ test_tmpdir } /testos-repo rev-parse ${ branch } 2>/dev/null; then
prevdate = $( timestamp_of_commit ${ test_tmpdir } /testos-repo " ${ branch } " ^)
newdate = $( timestamp_of_commit ${ test_tmpdir } /testos-repo " ${ branch } " )
if [ $(( ${ prevdate } > ${ newdate } )) = 1 ] ; then
fatal " clock skew detected writing commits: prev= ${ prevdate } new= ${ newdate } "
fi
fi
2013-06-29 19:45:53 +04:00
cd ${ test_tmpdir }
}
2016-03-31 13:06:05 +03:00
2017-09-18 20:58:54 +03:00
_have_user_xattrs = ''
have_user_xattrs( ) {
2017-09-28 21:57:33 +03:00
assert_has_setfattr
2017-09-18 20:58:54 +03:00
if test " ${ _have_user_xattrs } " = '' ; then
touch test-xattrs
if setfattr -n user.testvalue -v somevalue test-xattrs 2>/dev/null; then
_have_user_xattrs = yes
else
_have_user_xattrs = no
fi
rm -f test-xattrs
fi
test ${ _have_user_xattrs } = yes
}
2017-09-28 21:57:33 +03:00
# Usage: if ! skip_one_without_user_xattrs; then ... more tests ...; fi
2017-08-29 19:02:18 +03:00
skip_one_without_user_xattrs ( ) {
2017-09-18 20:58:54 +03:00
if ! have_user_xattrs; then
2017-08-29 19:02:18 +03:00
echo "ok # SKIP - this test requires xattr support"
return 0
else
return 1
fi
}
2016-03-31 13:06:05 +03:00
skip_without_user_xattrs ( ) {
2017-09-18 20:58:54 +03:00
if ! have_user_xattrs; then
2016-07-27 18:40:05 +03:00
skip "this test requires xattr support"
2017-09-18 20:58:54 +03:00
fi
2016-03-31 13:06:05 +03:00
}
2016-03-31 15:44:27 +03:00
2019-12-29 16:25:24 +03:00
_have_systemd_and_libmount = ''
have_systemd_and_libmount( ) {
if test " ${ _have_systemd_and_libmount } " = '' ; then
if [ $( ostree --version | grep -c -e '- systemd' -e '- libmount' ) -eq 2 ] ; then
_have_systemd_and_libmount = yes
else
_have_systemd_and_libmount = no
fi
fi
test ${ _have_systemd_and_libmount } = yes
}
2017-09-26 19:41:07 +03:00
# Skip unless SELinux is disabled, or we can relabel.
# Default Docker has security.selinux xattrs, but returns
# EOPNOTSUPP when trying to set them, even to the existing value.
# https://github.com/ostreedev/ostree/pull/759
# https://github.com/ostreedev/ostree/pull/1217
skip_without_no_selinux_or_relabel ( ) {
2017-09-28 21:57:33 +03:00
if ! have_selinux_relabel; then
skip "this test requires xattr support"
2017-09-26 19:41:07 +03:00
fi
}
2017-09-18 21:29:16 +03:00
# https://brokenpi.pe/tools/strace-fault-injection
_have_strace_fault_injection = ''
have_strace_fault_injection( ) {
if test " ${ _have_strace_fault_injection } " = '' ; then
if strace -P ${ test_srcdir } /libtest-core.sh -e inject = read:retval= 0 cat ${ test_srcdir } /libtest-core.sh >out.txt &&
test '!' -s out.txt; then
_have_strace_fault_injection = yes
else
_have_strace_fault_injection = no
fi
rm -f out.txt
fi
test ${ _have_strace_fault_injection } = yes
}
skip_one_without_strace_fault_injection( ) {
if ! have_strace_fault_injection; then
echo "ok # SKIP this test requires strace fault injection"
return 0
fi
return 1
}
2016-03-31 15:44:27 +03:00
skip_without_fuse ( ) {
2016-07-27 18:40:05 +03:00
fusermount --version >/dev/null 2>& 1 || skip "no fusermount"
2016-03-31 15:44:27 +03:00
2016-07-27 18:40:05 +03:00
capsh --print | grep -q 'Bounding set.*[^a-z]cap_sys_admin' || \
skip "No cap_sys_admin in bounding set, can't use FUSE"
2016-03-31 15:44:27 +03:00
2016-07-27 18:40:05 +03:00
[ -w /dev/fuse ] || skip "no write access to /dev/fuse"
[ -e /etc/mtab ] || skip "no /etc/mtab"
2016-03-31 15:44:27 +03:00
}
2016-03-31 20:46:16 +03:00
2016-08-25 19:14:21 +03:00
has_gpgme ( ) {
2019-07-30 02:16:57 +03:00
local ret
2017-02-17 18:22:43 +03:00
${ CMD_PREFIX } ostree --version > version.txt
2019-07-30 02:16:57 +03:00
grep -q -e '- gpgme' version.txt
ret = $?
2017-02-17 18:22:43 +03:00
rm -f version.txt
2019-07-30 02:16:57 +03:00
return ${ ret }
}
skip_without_gpgme( ) {
if ! has_gpgme; then
skip "no gpg support compiled in"
fi
2016-08-25 19:14:21 +03:00
}
2019-06-17 23:25:22 +03:00
# Find an appropriate gpg program to use. We want one that has the
# --generate-key, --quick-set-expire and --quick-add-key options. The
# gpg program to use is returend.
which_gpg ( ) {
local gpg
local gpg_options
local needed_options = (
--generate-key
--quick-set-expire
--quick-add-key
)
local opt
# Prefer gpg2 in case gpg refers to gpg1
if which gpg2 & >/dev/null; then
gpg = gpg2
elif which gpg & >/dev/null; then
gpg = gpg
else
# Succeed but don't return anything.
return 0
fi
# Make sure all the needed options are available
gpg_options = $( ${ gpg } --dump-options) || return 0
for opt in ${ needed_options [*] } ; do
grep -q -x -e " ${ opt } " <<< " ${ gpg_options } " || return 0
done
# Found an appropriate gpg
echo ${ gpg }
}
2019-11-17 20:02:13 +03:00
libtest_cleanup_gpg ( ) {
local gpg_homedir = ${ 1 :- ${ test_tmpdir } /gpghome }
gpg-connect-agent --homedir " ${ gpg_homedir } " killagent /bye || true
}
libtest_exit_cmds += ( libtest_cleanup_gpg)
2020-04-16 19:43:43 +03:00
has_sign_ed25519 ( ) {
2019-08-02 02:20:33 +03:00
local ret
${ CMD_PREFIX } ostree --version > version.txt
2020-04-16 19:43:43 +03:00
grep -q -e '- sign-ed25519' version.txt
2019-08-02 02:20:33 +03:00
ret = $?
rm -f version.txt
return ${ ret }
}
2020-04-23 16:24:53 +03:00
skip_without_sign_ed25519( ) {
if ! has_sign_ed25519; then
skip "no ed25519 support compiled in"
fi
}
2019-11-17 20:02:13 +03:00
# Keys for ed25519 signing tests
ED25519PUBLIC =
ED25519SEED =
ED25519SECRET =
2019-08-02 02:20:33 +03:00
2019-11-17 20:02:13 +03:00
gen_ed25519_keys ( )
{
# Generate private key in PEM format
pemfile = " $( mktemp -p ${ test_tmpdir } ed25519_XXXXXX.pem) "
openssl genpkey -algorithm ed25519 -outform PEM -out " ${ pemfile } "
# Based on: http://openssl.6102.n7.nabble.com/ed25519-key-generation-td73907.html
# Extract the private and public parts from generated key.
ED25519PUBLIC = " $( openssl pkey -outform DER -pubout -in ${ pemfile } | tail -c 32 | base64) "
ED25519SEED = " $( openssl pkey -outform DER -in ${ pemfile } | tail -c 32 | base64) "
# Secret key is concantination of SEED and PUBLIC
ED25519SECRET = " $( echo ${ ED25519SEED } ${ ED25519PUBLIC } | base64 -d | base64 -w 0) "
echo "Generated ed25519 keys:"
echo " public: ${ ED25519PUBLIC } "
echo " seed: ${ ED25519SEED } "
}
gen_ed25519_random_public( )
{
openssl genpkey -algorithm ED25519 | openssl pkey -outform DER | tail -c 32 | base64
2016-03-31 20:46:16 +03:00
}
2017-06-02 17:09:23 +03:00
is_bare_user_only_repo ( ) {
grep -q 'mode=bare-user-only' $1 /config
}
2017-06-05 18:32:52 +03:00
# Given a path to a file in a repo for a ref, print its checksum
ostree_file_path_to_checksum( ) {
repo = $1
ref = $2
path = $3
$CMD_PREFIX ostree --repo= $repo ls -C $ref $path | awk '{ print $5 }'
}
2017-05-19 01:12:33 +03:00
# Given an object checksum, print its relative file path
ostree_checksum_to_relative_object_path( ) {
repo = $1
checksum = $2
if grep -Eq -e '^mode=archive' ${ repo } /config; then suffix = z; else suffix = '' ; fi
echo objects/${ checksum : 0 : 2 } /${ checksum : 2 } .file${ suffix }
}
2017-06-12 20:59:33 +03:00
# Given a path to a file in a repo for a ref, print the (relative) path to its
# object
ostree_file_path_to_relative_object_path( ) {
repo = $1
ref = $2
path = $3
checksum = $( ostree_file_path_to_checksum $repo $ref $path )
test -n " ${ checksum } "
2017-05-19 01:12:33 +03:00
ostree_checksum_to_relative_object_path ${ repo } ${ checksum }
2017-06-12 20:59:33 +03:00
}
2017-06-05 18:32:52 +03:00
# Given a path to a file in a repo for a ref, print the path to its object
ostree_file_path_to_object_path( ) {
2017-06-12 20:59:33 +03:00
repo = $1
ref = $2
path = $3
relpath = $( ostree_file_path_to_relative_object_path $repo $ref $path )
echo ${ repo } /${ relpath }
2017-06-05 18:32:52 +03:00
}
2017-06-13 20:55:53 +03:00
# Assert ref $2 in repo $1 has checksum $3.
assert_ref ( ) {
assert_streq $( ${ CMD_PREFIX } ostree rev-parse --repo= $1 $2 ) $3
}
# Assert no ref named $2 is present in repo $1.
assert_not_ref ( ) {
if ${ CMD_PREFIX } ostree rev-parse --repo= $1 $2 2>/dev/null; then
fatal " rev-parse $2 unexpectedly succeeded! "
fi
}
2018-07-05 19:30:05 +03:00
assert_fail ( ) {
set +e
$@
if [ $? = 0 ] ; then
echo 1>& 2 " $@ did not fail " ; exit 1
fi
set -euo pipefail
}