2020-05-29 19:51:20 +03:00
#!/usr/bin/env bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh
2021-04-09 20:39:41 +03:00
set -eux
2020-05-29 19:51:20 +03:00
set -o pipefail
2020-07-20 18:43:18 +03:00
export SYSTEMD_LOG_LEVEL = debug
2020-07-10 12:30:33 +03:00
cleanup( )
{
if [ -z " ${ image_dir } " ] ; then
return
fi
rm -rf " ${ image_dir } "
}
2020-05-29 19:51:20 +03:00
cd /tmp
2020-07-10 12:30:33 +03:00
image_dir = " $( mktemp -d -t -p /tmp tmp.XXXXXX) "
if [ -z " ${ image_dir } " ] || [ ! -d " ${ image_dir } " ] ; then
echo "mktemp under /tmp failed"
exit 1
2020-05-29 19:51:20 +03:00
fi
2020-07-10 12:30:33 +03:00
trap cleanup EXIT
2020-08-28 16:17:31 +03:00
cp /usr/share/minimal* " ${ image_dir } / "
image = " ${ image_dir } /minimal_0 "
2021-04-09 20:49:32 +03:00
roothash = " $( cat " ${ image } .roothash " ) "
os_release = " $( test -e /etc/os-release && echo /etc/os-release || echo /usr/lib/os-release) "
systemd-dissect --json= short " ${ image } .raw " | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
systemd-dissect " ${ image } .raw " | grep -q -F "MARKER=1"
systemd-dissect " ${ image } .raw " | grep -q -F -f <( sed 's/"//g' " $os_release " )
mv " ${ image } .verity " " ${ image } .fooverity "
mv " ${ image } .roothash " " ${ image } .foohash "
systemd-dissect --json= short " ${ image } .raw " --root-hash= " ${ roothash } " --verity-data= " ${ image } .fooverity " | grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"'
systemd-dissect " ${ image } .raw " --root-hash= " ${ roothash } " --verity-data= " ${ image } .fooverity " | grep -q -F "MARKER=1"
systemd-dissect " ${ image } .raw " --root-hash= " ${ roothash } " --verity-data= " ${ image } .fooverity " | grep -q -F -f <( sed 's/"//g' " $os_release " )
mv " ${ image } .fooverity " " ${ image } .verity "
mv " ${ image } .foohash " " ${ image } .roothash "
mkdir -p " ${ image_dir } /mount " " ${ image_dir } /mount2 "
systemd-dissect --mount " ${ image } .raw " " ${ image_dir } /mount "
grep -q -F -f " $os_release " " ${ image_dir } /mount/usr/lib/os-release "
grep -q -F -f " $os_release " " ${ image_dir } /mount/etc/os-release "
grep -q -F "MARKER=1" " ${ image_dir } /mount/usr/lib/os-release "
2020-07-08 21:57:31 +03:00
# Verity volume should be shared (opened only once)
2021-04-09 20:49:32 +03:00
systemd-dissect --mount " ${ image } .raw " " ${ image_dir } /mount2 "
verity_count = $( find /dev/mapper/ -name "*verity*" | wc -l)
2020-07-08 21:57:31 +03:00
# In theory we should check that count is exactly one. In practice, libdevmapper
# randomly and unpredictably fails with an unhelpful EINVAL when a device is open
# (and even mounted and in use), so best-effort is the most we can do for now
2021-04-09 20:49:32 +03:00
if [ " ${ verity_count } " -lt 1 ] ; then
2020-07-08 21:57:31 +03:00
echo " Verity device ${ image } .raw not found in /dev/mapper/ "
exit 1
fi
2021-04-09 20:49:32 +03:00
umount " ${ image_dir } /mount "
umount " ${ image_dir } /mount2 "
2020-05-29 19:51:20 +03:00
2021-04-23 18:17:26 +03:00
systemd-run -P -p RootImage = " ${ image } .raw " cat /usr/lib/os-release | grep -q -F "MARKER=1"
2021-04-09 20:49:32 +03:00
mv " ${ image } .verity " " ${ image } .fooverity "
mv " ${ image } .roothash " " ${ image } .foohash "
2021-04-23 18:17:26 +03:00
systemd-run -P -p RootImage = " ${ image } .raw " -p RootHash = " ${ image } .foohash " -p RootVerity = " ${ image } .fooverity " cat /usr/lib/os-release | grep -q -F "MARKER=1"
2020-09-22 13:36:38 +03:00
# Let's use the long option name just here as a test
2021-04-23 18:17:26 +03:00
systemd-run -P --property RootImage = " ${ image } .raw " --property RootHash = " ${ roothash } " --property RootVerity = " ${ image } .fooverity " cat /usr/lib/os-release | grep -q -F "MARKER=1"
2021-04-09 20:49:32 +03:00
mv " ${ image } .fooverity " " ${ image } .verity "
mv " ${ image } .foohash " " ${ image } .roothash "
2020-07-15 19:54:12 +03:00
2020-07-10 18:01:15 +03:00
# Make a GPT disk on the fly, with the squashfs as partition 1 and the verity hash tree as partition 2
machine = " $( uname -m) "
if [ " ${ machine } " = "x86_64" ] ; then
root_guid = 4f68bce3-e8cd-4db1-96e7-fbcaf984b709
verity_guid = 2c7357ed-ebd2-46d9-aec1-23d437ec2bf5
2021-09-28 17:49:16 +03:00
signature_guid = 41092b05-9fc8-4523-994f-2def0408b176
2020-10-18 17:41:34 +03:00
architecture = "x86-64"
2020-07-10 18:01:15 +03:00
elif [ " ${ machine } " = "i386" ] || [ " ${ machine } " = "i686" ] || [ " ${ machine } " = "x86" ] ; then
root_guid = 44479540-f297-41b2-9af7-d131d5f0458a
verity_guid = d13c5d3b-b5d1-422a-b29f-9454fdc89d76
2021-09-28 17:49:16 +03:00
signature_guid = 5996fc05-109c-48de-808b-23fa0830b676
2020-10-18 17:41:34 +03:00
architecture = "x86"
2020-07-10 18:01:15 +03:00
elif [ " ${ machine } " = "aarch64" ] || [ " ${ machine } " = "aarch64_be" ] || [ " ${ machine } " = "armv8b" ] || [ " ${ machine } " = "armv8l" ] ; then
root_guid = b921b045-1df0-41c3-af44-4c6f280d3fae
verity_guid = df3300ce-d69f-4c92-978c-9bfb0f38d820
2021-09-28 17:49:16 +03:00
signature_guid = 6db69de6-29f4-4758-a7a5-962190f00ce3
2020-10-18 17:41:34 +03:00
architecture = "arm64"
2020-07-10 18:01:15 +03:00
elif [ " ${ machine } " = "arm" ] ; then
root_guid = 69dad710-2ce4-4e3c-b16c-21a1d49abed3
verity_guid = 7386cdf2-203c-47a9-a498-f2ecce45a2d6
2021-09-28 17:49:16 +03:00
signature_guid = 42b0455f-eb11-491d-98d3-56145ba9d037
2020-10-18 17:41:34 +03:00
architecture = "arm"
2020-07-10 18:01:15 +03:00
elif [ " ${ machine } " = "ia64" ] ; then
root_guid = 993d8d3d-f80e-4225-855a-9daf8ed7ea97
verity_guid = 86ed10d5-b607-45bb-8957-d350f23d0571
2021-09-28 17:49:16 +03:00
signature_guid = e98b36ee-32ba-4882-9b12-0ce14655f46a
2020-10-18 17:41:34 +03:00
architecture = "ia64"
elif [ " ${ machine } " = "ppc64le" ] ; then
# There's no support of PPC in the discoverable partitions specification yet, so skip the rest for now
echo OK >/testok
exit 0
2020-07-20 18:43:18 +03:00
else
echo " Unexpected uname -m: ${ machine } in testsuite-50.sh, please fix me "
exit 1
2020-07-10 18:01:15 +03:00
fi
# du rounds up to block size, which is more helpful for partitioning
2021-04-09 20:49:32 +03:00
root_size = " $( du -k " ${ image } .raw " | cut -f1) "
verity_size = " $( du -k " ${ image } .verity " | cut -f1) "
2021-09-28 17:49:16 +03:00
signature_size = 4
2020-07-10 18:01:15 +03:00
# 4MB seems to be the minimum size blkid will accept, below that probing fails
2021-09-28 17:49:16 +03:00
dd if = /dev/zero of = " ${ image } .gpt " bs = 512 count = $(( 8192 + root_size*2+verity_size*2+signature_size*2))
2020-07-10 18:01:15 +03:00
# sfdisk seems unhappy if the size overflows into the next unit, eg: 1580KiB will be interpreted as 1MiB
# so do some basic rounding up if the minimal image is more than 1 MB
2021-04-09 20:49:32 +03:00
if [ " ${ root_size } " -ge 1024 ] ; then
root_size = " $(( root_size/1024 + 1 )) MiB "
2020-07-10 18:01:15 +03:00
else
root_size = " ${ root_size } KiB "
fi
2021-04-09 20:49:32 +03:00
verity_size = " $(( verity_size * 2 )) KiB "
2021-09-28 17:49:16 +03:00
signature_size = " $(( signature_size * 2 )) KiB "
2021-10-07 02:26:26 +03:00
HAVE_OPENSSL = 0
if systemctl --version | grep -q -- +OPENSSL ; then
HAVE_OPENSSL = 1
# Unfortunately OpenSSL insists on reading some config file, hence provide one with mostly placeholder contents
cat >> " ${ image } .openssl.cnf " <<EOF
2021-09-28 17:49:16 +03:00
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
C = DE
ST = Test State
L = Test Locality
O = Org Name
OU = Org Unit Name
CN = Common Name
emailAddress = test@email.com
EOF
2021-10-07 02:26:26 +03:00
# Create key pair
openssl req -config " ${ image } .openssl.cnf " -new -x509 -newkey rsa:1024 -keyout " ${ image } .key " -out " ${ image } .crt " -days 365 -nodes
# Sign Verity root hash with it
openssl smime -sign -nocerts -noattr -binary -in " ${ image } .roothash " -inkey " ${ image } .key " -signer " ${ image } .crt " -outform der -out " ${ image } .roothash.p7s "
# Generate signature partition JSON data
echo '{"rootHash":"' " ${ roothash } " '","signature":"' " $( base64 -w 0 < " ${ image } .roothash.p7s " ) " '"}' > " ${ image } .verity-sig "
# Pad it
truncate -s " ${ signature_size } " " ${ image } .verity-sig "
# Register certificate in the (userspace) verity key ring
mkdir -p /run/verity.d
ln -s " ${ image } .crt " /run/verity.d/ok.crt
fi
2021-09-28 17:49:16 +03:00
2021-04-09 20:49:32 +03:00
# Construct a UUID from hash
# input: 11111111222233334444555566667777
# output: 11111111-2222-3333-4444-555566667777
uuid = " $( head -c 32 " ${ image } .roothash " | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.+)/\1-\2-\3-\4-\5/' ) "
echo -e " label: gpt\nsize= ${ root_size } , type= ${ root_guid } , uuid= ${ uuid } " | sfdisk " ${ image } .gpt "
uuid = " $( tail -c 32 " ${ image } .roothash " | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.+)/\1-\2-\3-\4-\5/' ) "
echo -e " size= ${ verity_size } , type= ${ verity_guid } , uuid= ${ uuid } " | sfdisk " ${ image } .gpt " --append
2021-10-07 02:26:26 +03:00
if [ " ${ HAVE_OPENSSL } " -eq 1 ] ; then
echo -e " size= ${ signature_size } , type= ${ signature_guid } " | sfdisk " ${ image } .gpt " --append
fi
2021-04-09 20:49:32 +03:00
sfdisk --part-label " ${ image } .gpt " 1 "Root Partition"
sfdisk --part-label " ${ image } .gpt " 2 "Verity Partition"
2021-10-07 02:26:26 +03:00
if [ " ${ HAVE_OPENSSL } " -eq 1 ] ; then
sfdisk --part-label " ${ image } .gpt " 3 "Signature Partition"
fi
2021-04-09 20:49:32 +03:00
loop = " $( losetup --show -P -f " ${ image } .gpt " ) "
dd if = " ${ image } .raw " of = " ${ loop } p1 "
dd if = " ${ image } .verity " of = " ${ loop } p2 "
2021-10-07 02:26:26 +03:00
if [ " ${ HAVE_OPENSSL } " -eq 1 ] ; then
dd if = " ${ image } .verity-sig " of = " ${ loop } p3 "
fi
2021-04-09 20:49:32 +03:00
losetup -d " ${ loop } "
2020-07-10 18:01:15 +03:00
2020-08-12 00:32:19 +03:00
# Derive partition UUIDs from root hash, in UUID syntax
2021-04-09 20:49:32 +03:00
ROOT_UUID = " $( systemd-id128 -u show " $( head -c 32 " ${ image } .roothash " ) " -u | tail -n 1 | cut -b 6-) "
VERITY_UUID = " $( systemd-id128 -u show " $( tail -c 32 " ${ image } .roothash " ) " -u | tail -n 1 | cut -b 6-) "
2020-07-10 18:01:15 +03:00
2021-04-21 17:35:21 +03:00
systemd-dissect --json= short --root-hash " ${ roothash } " " ${ image } .gpt " | grep -q '{"rw":"ro","designator":"root","partition_uuid":"' " $ROOT_UUID " '","partition_label":"Root Partition","fstype":"squashfs","architecture":"' " $architecture " '","verity":"yes",'
systemd-dissect --json= short --root-hash " ${ roothash } " " ${ image } .gpt " | grep -q '{"rw":"ro","designator":"root-verity","partition_uuid":"' " $VERITY_UUID " '","partition_label":"Verity Partition","fstype":"DM_verity_hash","architecture":"' " $architecture " '","verity":null,'
2021-04-09 20:49:32 +03:00
systemd-dissect --root-hash " ${ roothash } " " ${ image } .gpt " | grep -q -F "MARKER=1"
systemd-dissect --root-hash " ${ roothash } " " ${ image } .gpt " | grep -q -F -f <( sed 's/"//g' " $os_release " )
2020-08-12 00:32:19 +03:00
2021-04-09 20:49:32 +03:00
systemd-dissect --root-hash " ${ roothash } " --mount " ${ image } .gpt " " ${ image_dir } /mount "
grep -q -F -f " $os_release " " ${ image_dir } /mount/usr/lib/os-release "
grep -q -F -f " $os_release " " ${ image_dir } /mount/etc/os-release "
grep -q -F "MARKER=1" " ${ image_dir } /mount/usr/lib/os-release "
umount " ${ image_dir } /mount "
2020-07-10 18:01:15 +03:00
2020-09-22 13:36:38 +03:00
# add explicit -p MountAPIVFS=yes once to test the parser
2021-04-23 18:17:26 +03:00
systemd-run -P -p RootImage = " ${ image } .gpt " -p RootHash = " ${ roothash } " -p MountAPIVFS = yes cat /usr/lib/os-release | grep -q -F "MARKER=1"
2020-07-15 19:54:12 +03:00
2021-04-23 18:17:26 +03:00
systemd-run -P -p RootImage = " ${ image } .raw " -p RootImageOptions = "root:nosuid,dev home:ro,dev ro,noatime" mount | grep -F "squashfs" | grep -q -F "nosuid"
systemd-run -P -p RootImage = " ${ image } .gpt " -p RootImageOptions = "root:ro,noatime root:ro,dev" mount | grep -F "squashfs" | grep -q -F "noatime"
2020-06-29 15:19:31 +03:00
2021-04-09 20:49:32 +03:00
mkdir -p " ${ image_dir } /result "
2020-09-22 13:36:38 +03:00
cat >/run/systemd/system/testservice-50a.service <<EOF
2020-06-29 15:19:31 +03:00
[ Service]
Type = oneshot
2020-09-22 13:36:38 +03:00
ExecStart = bash -c "mount >/run/result/a"
2020-08-14 20:50:46 +03:00
BindPaths = ${ image_dir } /result:/run/result
TemporaryFileSystem = /run
2020-06-29 15:19:31 +03:00
RootImage = ${ image } .raw
2020-08-14 20:50:46 +03:00
RootImageOptions = root:ro,noatime home:ro,dev relatime,dev
2020-06-29 15:19:31 +03:00
RootImageOptions = nosuid,dev
EOF
systemctl start testservice-50a.service
2021-04-09 20:49:32 +03:00
grep -F "squashfs" " ${ image_dir } /result/a " | grep -q -F "noatime"
grep -F "squashfs" " ${ image_dir } /result/a " | grep -q -F -v "nosuid"
2020-06-29 15:19:31 +03:00
2020-09-22 13:36:38 +03:00
cat >/run/systemd/system/testservice-50b.service <<EOF
2020-06-29 15:19:31 +03:00
[ Service]
Type = oneshot
2020-09-22 13:36:38 +03:00
ExecStart = bash -c "mount >/run/result/b"
2020-08-14 20:50:46 +03:00
BindPaths = ${ image_dir } /result:/run/result
TemporaryFileSystem = /run
2020-06-29 15:19:31 +03:00
RootImage = ${ image } .gpt
2020-08-14 20:50:46 +03:00
RootImageOptions = root:ro,noatime,nosuid home:ro,dev nosuid,dev
RootImageOptions = home:ro,dev nosuid,dev,%%foo
2020-09-22 13:36:38 +03:00
# this is the default, but let's specify once to test the parser
MountAPIVFS = yes
2020-06-29 15:19:31 +03:00
EOF
systemctl start testservice-50b.service
2021-04-09 20:49:32 +03:00
grep -F "squashfs" " ${ image_dir } /result/b " | grep -q -F "noatime"
2020-06-29 15:19:31 +03:00
2020-09-22 13:36:38 +03:00
# Check that specifier escape is applied %%foo → %foo
2020-06-29 15:19:31 +03:00
busctl get-property org.freedesktop.systemd1 /org/freedesktop/systemd1/unit/testservice_2d50b_2eservice org.freedesktop.systemd1.Service RootImageOptions | grep -F "nosuid,dev,%foo"
2020-07-31 17:06:15 +03:00
# Now do some checks with MountImages, both by itself, with options and in combination with RootImage, and as single FS or GPT image
2021-04-23 18:17:26 +03:00
systemd-run -P -p MountImages = " ${ image } .gpt:/run/img1 ${ image } .raw:/run/img2 " cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
systemd-run -P -p MountImages = " ${ image } .gpt:/run/img1 ${ image } .raw:/run/img2 " cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
systemd-run -P -p MountImages = " ${ image } .gpt:/run/img1 ${ image } .raw:/run/img2:nosuid,dev " mount | grep -F "squashfs" | grep -q -F "nosuid"
systemd-run -P -p MountImages = " ${ image } .gpt:/run/img1:root:nosuid ${ image } .raw:/run/img2:home:suid " mount | grep -F "squashfs" | grep -q -F "nosuid"
systemd-run -P -p MountImages = " ${ image } .raw:/run/img2\:3 " cat /run/img2:3/usr/lib/os-release | grep -q -F "MARKER=1"
systemd-run -P -p MountImages = " ${ image } .raw:/run/img2\:3:nosuid " mount | grep -F "squashfs" | grep -q -F "nosuid"
systemd-run -P -p TemporaryFileSystem = /run -p RootImage = " ${ image } .raw " -p MountImages = " ${ image } .gpt:/run/img1 ${ image } .raw:/run/img2 " cat /usr/lib/os-release | grep -q -F "MARKER=1"
systemd-run -P -p TemporaryFileSystem = /run -p RootImage = " ${ image } .raw " -p MountImages = " ${ image } .gpt:/run/img1 ${ image } .raw:/run/img2 " cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1"
systemd-run -P -p TemporaryFileSystem = /run -p RootImage = " ${ image } .gpt " -p RootHash = " ${ roothash } " -p MountImages = " ${ image } .gpt:/run/img1 ${ image } .raw:/run/img2 " cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1"
2020-07-31 17:06:15 +03:00
cat >/run/systemd/system/testservice-50c.service <<EOF
2020-07-14 18:18:41 +03:00
[ Service]
2020-07-31 17:06:15 +03:00
MountAPIVFS = yes
2020-07-14 18:18:41 +03:00
TemporaryFileSystem = /run
RootImage = ${ image } .raw
2020-07-31 17:06:15 +03:00
MountImages = ${ image } .gpt:/run/img1:root:noatime:home:relatime
MountImages = ${ image } .raw:/run/img2\: 3:nosuid
2020-09-22 13:36:38 +03:00
ExecStart = bash -c "cat /run/img1/usr/lib/os-release >/run/result/c"
ExecStart = bash -c "cat /run/img2:3/usr/lib/os-release >>/run/result/c"
ExecStart = bash -c "mount >>/run/result/c"
2020-07-31 17:06:15 +03:00
BindPaths = ${ image_dir } /result:/run/result
2020-07-14 18:18:41 +03:00
Type = oneshot
EOF
2020-07-31 17:06:15 +03:00
systemctl start testservice-50c.service
2021-04-09 20:49:32 +03:00
grep -q -F "MARKER=1" " ${ image_dir } /result/c "
grep -F "squashfs" " ${ image_dir } /result/c " | grep -q -F "noatime"
grep -F "squashfs" " ${ image_dir } /result/c " | grep -q -F -v "nosuid"
2020-07-14 18:18:41 +03:00
2021-01-21 21:37:40 +03:00
# Adding a new mounts at runtime works if the unit is in the active state,
# so use Type=notify to make sure there's no race condition in the test
2021-04-08 01:09:55 +03:00
cat >/run/systemd/system/testservice-50d.service <<EOF
2021-01-21 21:37:40 +03:00
[ Service]
RuntimeMaxSec = 300
Type = notify
RemainAfterExit = yes
MountAPIVFS = yes
PrivateTmp = yes
ExecStart = /bin/sh -c 'systemd-notify --ready; while ! grep -q -F MARKER /tmp/img/usr/lib/os-release; do sleep 0.1; done; mount | grep -F "/tmp/img" | grep -q -F "nosuid"'
EOF
systemctl start testservice-50d.service
2021-04-09 20:49:32 +03:00
systemctl mount-image --mkdir testservice-50d.service " ${ image } .raw " /tmp/img root:nosuid
2021-01-21 21:37:40 +03:00
while systemctl show -P SubState testservice-50d.service | grep -q running
do
sleep 0.1
done
systemctl is-active testservice-50d.service
2021-02-22 15:20:33 +03:00
# ExtensionImages will set up an overlay
2021-04-23 18:17:26 +03:00
systemd-run -P --property ExtensionImages = /usr/share/app0.raw --property RootImage = " ${ image } .raw " cat /opt/script0.sh | grep -q -F "extension-release.app0"
systemd-run -P --property ExtensionImages = /usr/share/app0.raw --property RootImage = " ${ image } .raw " cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
systemd-run -P --property ExtensionImages = "/usr/share/app0.raw /usr/share/app1.raw" --property RootImage = " ${ image } .raw " cat /opt/script0.sh | grep -q -F "extension-release.app0"
systemd-run -P --property ExtensionImages = "/usr/share/app0.raw /usr/share/app1.raw" --property RootImage = " ${ image } .raw " cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
2021-07-22 22:41:34 +03:00
systemd-run -P --property ExtensionImages = "/usr/share/app0.raw /usr/share/app1.raw" --property RootImage = " ${ image } .raw " cat /opt/script1.sh | grep -q -F "extension-release.app2"
2021-04-23 18:17:26 +03:00
systemd-run -P --property ExtensionImages = "/usr/share/app0.raw /usr/share/app1.raw" --property RootImage = " ${ image } .raw " cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1"
2021-02-22 15:20:33 +03:00
cat >/run/systemd/system/testservice-50e.service <<EOF
[ Service]
MountAPIVFS = yes
TemporaryFileSystem = /run
RootImage = ${ image } .raw
ExtensionImages = /usr/share/app0.raw /usr/share/app1.raw:nosuid
2021-03-08 13:28:40 +03:00
# Relevant only for sanitizer runs
UnsetEnvironment = LD_PRELOAD
2021-02-22 15:20:33 +03:00
ExecStart = /bin/bash -c '/opt/script0.sh | grep ID'
ExecStart = /bin/bash -c '/opt/script1.sh | grep ID'
Type = oneshot
RemainAfterExit = yes
EOF
systemctl start testservice-50e.service
systemctl is-active testservice-50e.service
2020-09-22 13:36:38 +03:00
echo OK >/testok
2020-05-29 19:51:20 +03:00
exit 0