Skip to content

Commit ec1b82d

Browse files
committed
tests: zfs: add native zfs encryption tests
This primarily ensures that we correctly load the dataset keys when importing a pool, and if we can't import the dataset that the storage pool is correctly tagged as UNAVAILABLE. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 11831e9 commit ec1b82d

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

test/suites/storage_driver_zfs.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_storage_driver_zfs() {
55

66
do_zfs_cross_pool_copy
77
do_zfs_delegate
8+
do_zfs_encryption
89
}
910

1011
do_zfs_delegate() {
@@ -45,6 +46,84 @@ do_zfs_delegate() {
4546
incus delete -f c1
4647
}
4748

49+
do_zfs_encryption() {
50+
# shellcheck disable=2039,3043
51+
local INCUS_STORAGE_DIR incus_backend
52+
53+
incus_backend=$(storage_backend "$INCUS_DIR")
54+
if [ "$incus_backend" != "zfs" ]; then
55+
return
56+
fi
57+
58+
if ! zfs --help | grep -q '^\s\+load-key\b'; then
59+
echo "==> SKIP: Skipping ZFS encryption tests as installed version doesn't support it"
60+
return
61+
fi
62+
63+
INCUS_STORAGE_DIR="$(mktemp -d -p "${TEST_DIR}" XXXXXXXXX)"
64+
chmod +x "${INCUS_STORAGE_DIR}"
65+
spawn_incus "${INCUS_STORAGE_DIR}" false
66+
67+
# shellcheck disable=3043
68+
local zpool_name zpool_keyfile zpool_vdev
69+
# Create a new pool. incus storage create doesn't support setting up
70+
# encrypted datasets, so we need to create the pool ourselves.
71+
configure_loop_device zpool_file zpool_vdev
72+
zpool_name="$(mktemp -u incus-zpool-XXXXXXXXX)"
73+
zpool_keyfile="$(mktemp -p "${TEST_DIR}" incus-zpool-keyfile.XXXXXXXXX)"
74+
echo "dummy-passphrase" >"$zpool_keyfile"
75+
76+
zpool create \
77+
-O encryption=on \
78+
-O keyformat=passphrase \
79+
-O keylocation="file://$zpool_keyfile" \
80+
"$zpool_name" "$zpool_vdev"
81+
82+
incus storage create zpool_encrypted zfs source="$zpool_name"
83+
84+
# Make sure that incus sees that the pool is imported.
85+
zfs get -H -o name,property,value keystatus "$zpool_name" | grep -q "$zpool_name\tkeystatus\tavailable"
86+
incus storage list -f csv -c nDs | grep -q "zpool_encrypted,zfs,CREATED"
87+
88+
# Shut down Incus to force the pool to get exported. The shutdown needs to be
89+
# clean for this test to work, so we wait for it to finish.
90+
incus admin shutdown
91+
92+
# The pool should be exported now.
93+
! zpool status "$zpool_name" 2>/dev/null
94+
95+
# Restart Incus.
96+
incus admin waitready
97+
98+
# The keys should've been re-imported automatically by Incus.
99+
zfs get -H -o name,property,value keystatus "$zpool_name" | grep -q "$zpool_name\tkeystatus\tavailable"
100+
incus storage list -f csv -c nDs | grep -q "zpool_encrypted,zfs,CREATED"
101+
102+
# Now we reconfigure the dataset so that the encryption key is provided via
103+
# an interactive prompt. Incus cannot handle this, so we should expect the
104+
# pool to remain unimported and the storage pool should be reported as
105+
# UNAVAILABLE.
106+
zfs set keylocation=prompt "$zpool_name"
107+
108+
# Shut down Incus to force the pool to get exported. The shutdown needs to be
109+
# clean for this test to work, so we wait for it to finish.
110+
incus admin shutdown
111+
112+
# The pool should be exported now.
113+
! zpool status "$zpool_name" 2>/dev/null
114+
115+
# Restart Incus.
116+
incus admin waitready
117+
118+
# The pool should still not be imported, and Incus should report the storage
119+
# pool as UNAVAILABLE.
120+
! zpool status "$zpool_name" 2>/dev/null
121+
incus storage list -f csv -c nDs | grep -q "zpool_encrypted,zfs,UNAVAILABLE"
122+
123+
# shellcheck disable=SC2031
124+
kill_incus "${INCUS_STORAGE_DIR}"
125+
}
126+
48127
do_zfs_cross_pool_copy() {
49128
# shellcheck disable=2039,3043
50129
local INCUS_STORAGE_DIR incus_backend

0 commit comments

Comments
 (0)