Skip to content

Commit 77e6c38

Browse files
author
Ramkumar Chinchani
committed
test: add a erofs test
Signed-off-by: Ramkumar Chinchani <[email protected]>
1 parent ca4e173 commit 77e6c38

File tree

5 files changed

+179
-14
lines changed

5 files changed

+179
-14
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,6 @@ require (
289289

290290
replace (
291291
github.com/opencontainers/umoci => github.com/project-stacker/umoci v0.0.0-20240906174318-e9397ba4ced0
292-
machinerun.io/atomfs => github.com/rchincha/atomfs v0.0.0-20241118222046-f23b7d3df267
292+
machinerun.io/atomfs => github.com/rchincha/atomfs v0.0.0-20241118224201-3b5276847a13
293293
stackerbuild.io/stacker-bom => github.com/project-stacker/stacker-bom v0.0.0-20240509203427-4d685e046780
294294
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,8 +818,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
818818
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
819819
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
820820
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
821-
github.com/rchincha/atomfs v0.0.0-20241118222046-f23b7d3df267 h1:m+sM2UvDXMCRIl5e+6zQsw37KRceg0tEcuvPxQ69BSc=
822-
github.com/rchincha/atomfs v0.0.0-20241118222046-f23b7d3df267/go.mod h1:woheEy3EVXE+AFLGwmBRSMtmcOKBM71qiDEYaq7Nwng=
821+
github.com/rchincha/atomfs v0.0.0-20241118224201-3b5276847a13 h1:PZWE0mq+wI6zqUsV1pA0yUmhkl3UWs0I7duypR92NQw=
822+
github.com/rchincha/atomfs v0.0.0-20241118224201-3b5276847a13/go.mod h1:woheEy3EVXE+AFLGwmBRSMtmcOKBM71qiDEYaq7Nwng=
823823
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
824824
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
825825
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=

install-build-deps.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ installdeps_ubuntu() {
4343
squashfs-tools
4444
squashfuse
4545
libarchive-tools
46+
erofs-utils erofsfuse
4647
)
4748

4849
case "$VERSION_ID" in

test/atomfs-erofs.bats

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
load helpers
2+
3+
function setup() {
4+
stacker_setup
5+
}
6+
7+
function teardown() {
8+
cleanup
9+
}
10+
11+
function verity_checkusedloops() {
12+
# search for loopdevices which have backing files with the current
13+
# BATS_TEST_DIRNAME value and complain if they're present.
14+
local usedloops="" found="" x=""
15+
for ((x=0; x<5; x++)); do
16+
usedloops=$(losetup -a | grep $BATS_TEST_DIRNAME || echo)
17+
if [ -n "$usedloops" ]; then
18+
found=1
19+
udevadm settle
20+
else
21+
return 0
22+
fi
23+
done
24+
echo "found used loops in testdir=$BATS_TEST_DIRNAME :$usedloops" >&3
25+
[ $found = 1 ]
26+
}
27+
28+
function basic_test() {
29+
require_privilege priv
30+
local verity_arg=$1
31+
32+
cat > stacker.yaml <<"EOF"
33+
test:
34+
from:
35+
type: oci
36+
url: ${{BUSYBOX_OCI}}
37+
run: |
38+
touch /hello
39+
EOF
40+
stacker build --layer-type=erofs $verity_arg --substitute BUSYBOX_OCI=${BUSYBOX_OCI}
41+
mkdir mountpoint
42+
stacker internal-go atomfs mount test-erofs mountpoint
43+
44+
[ -f mountpoint/hello ]
45+
stacker internal-go atomfs umount mountpoint
46+
}
47+
48+
@test "--no-verity works" {
49+
basic_test --no-verity
50+
verity_checkusedloops
51+
}
52+
53+
@test "mount + umount works" {
54+
basic_test
55+
56+
# last layer shouldn't exist any more, since it is unique
57+
manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:)
58+
last_layer_num=$(($(cat oci/blobs/sha256/$manifest | jq -r '.layers | length')-1))
59+
last_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[$last_layer].digest | cut -f2 -d:)
60+
[ ! -b "/dev/mapper/$last_layer_hash-verity" ]
61+
verity_checkusedloops
62+
}
63+
64+
@test "mount + umount + mount a tree of images works" {
65+
require_privilege priv
66+
cat > stacker.yaml <<"EOF"
67+
base:
68+
from:
69+
type: oci
70+
url: ${{BUSYBOX_OCI}}
71+
run: touch /base
72+
a:
73+
from:
74+
type: built
75+
tag: base
76+
run: touch /a
77+
b:
78+
from:
79+
type: built
80+
tag: base
81+
run: touch /b
82+
c:
83+
from:
84+
type: built
85+
tag: base
86+
run: touch /c
87+
EOF
88+
stacker build --layer-type=erofs --substitute BUSYBOX_OCI=${BUSYBOX_OCI}
89+
90+
mkdir a
91+
stacker internal-go atomfs mount a-erofs a
92+
[ -f a/a ]
93+
94+
mkdir b
95+
stacker internal-go atomfs mount b-erofs b
96+
[ -f b/b ]
97+
98+
cat /proc/self/mountinfo
99+
echo "mountinfo after b^"
100+
101+
stacker internal-go atomfs umount b
102+
103+
# first layer should still exist since a is still mounted
104+
manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:)
105+
first_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[0].digest | cut -f2 -d:)
106+
[ ! -b "/dev/mapper/$last_layer_hash-verity" ]
107+
108+
mkdir c
109+
stacker internal-go atomfs mount c-erofs c
110+
[ -f c/c ]
111+
112+
cat /proc/self/mountinfo
113+
echo "mountinfo after c^"
114+
115+
stacker internal-go atomfs umount a
116+
117+
cat /proc/self/mountinfo
118+
echo "mountinfo after umount a^"
119+
120+
# first layer should still exist since c is still mounted
121+
manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:)
122+
first_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[0].digest | cut -f2 -d:)
123+
[ ! -b "/dev/mapper/$last_layer_hash-verity" ]
124+
125+
# c should still be ok
126+
[ -f c/c ]
127+
[ -f c/bin/sh ]
128+
stacker internal-go atomfs umount c
129+
130+
# c's last layer shouldn't exist any more, since it is unique
131+
manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:)
132+
last_layer_num=$(($(cat oci/blobs/sha256/$manifest | jq -r '.layers | length')-1))
133+
last_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[$last_layer].digest | cut -f2 -d:)
134+
[ ! -b "/dev/mapper/$last_layer_hash-verity" ]
135+
verity_checkusedloops
136+
}
137+
138+
@test "bad existing verity device is rejected" {
139+
require_privilege priv
140+
cat > stacker.yaml <<"EOF"
141+
test:
142+
from:
143+
type: oci
144+
url: ${{BUSYBOX_OCI}}
145+
run: |
146+
touch /hello
147+
EOF
148+
stacker build --layer-type=erofs --substitute BUSYBOX_OCI=${BUSYBOX_OCI}
149+
150+
manifest=$(cat oci/index.json | jq -r .manifests[0].digest | cut -f2 -d:)
151+
first_layer_hash=$(cat oci/blobs/sha256/$manifest | jq -r .layers[0].digest | cut -f2 -d:)
152+
devname="$first_layer_hash-verity"
153+
154+
# make an evil device and fake it as an existing verity device
155+
dd if=/dev/random of=mydev bs=50K count=1
156+
root_hash=$(veritysetup format mydev mydev.hash | grep "Root hash:" | awk '{print $NF}')
157+
echo "root hash $root_hash"
158+
veritysetup open mydev "$devname" mydev.hash "$root_hash"
159+
160+
mkdir mountpoint
161+
bad_stacker internal-go atomfs mount test-erofs mountpoint | grep "invalid root hash"
162+
veritysetup close "$devname"
163+
verity_checkusedloops
164+
}

test/helpers.bash

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@ if [ "$(id -u)" != "0" ]; then
88
exit 1
99
fi
1010

11+
function give_user_ownership() {
12+
if [ "$PRIVILEGE_LEVEL" = "priv" ]; then
13+
return
14+
fi
15+
if [ -z "$SUDO_UID" ]; then
16+
echo "PRIVILEGE_LEVEL=$PRIVILEGE_LEVEL but empty SUDO_USER"
17+
exit 1
18+
fi
19+
chown -R "$SUDO_USER:$SUDO_USER" "$@"
20+
}
21+
1122
function skip_if_no_unpriv_overlay {
1223
local wdir=""
1324
# use a workdir to ensure no side effects to the caller
@@ -80,17 +91,6 @@ function stacker_setup() {
8091
chown -R $SUDO_USER:$SUDO_USER .
8192
}
8293

83-
function give_user_ownership() {
84-
if [ "$PRIVILEGE_LEVEL" = "priv" ]; then
85-
return
86-
fi
87-
if [ -z "$SUDO_UID" ]; then
88-
echo "PRIVILEGE_LEVEL=$PRIVILEGE_LEVEL but empty SUDO_USER"
89-
exit 1
90-
fi
91-
chown -R "$SUDO_USER:$SUDO_USER" "$@"
92-
}
93-
9494
function cleanup() {
9595
cd "$ROOT_DIR/test"
9696
umount_under "$TEST_TMPDIR"

0 commit comments

Comments
 (0)