@@ -5,6 +5,7 @@ test_storage_driver_zfs() {
5
5
6
6
do_zfs_cross_pool_copy
7
7
do_zfs_delegate
8
+ do_zfs_encryption
8
9
}
9
10
10
11
do_zfs_delegate () {
@@ -45,6 +46,84 @@ do_zfs_delegate() {
45
46
incus delete -f c1
46
47
}
47
48
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 -Eq " $zpool_name \s+keystatus\s+available"
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. Note that the shutdown
89
+ # needs to be clean for this test to work.
90
+ shutdown_incus " ${INCUS_STORAGE_DIR} "
91
+
92
+ # The pool should be exported now.
93
+ ! zpool status " $zpool_name " 2> /dev/null
94
+
95
+ # Restart Incus.
96
+ respawn_incus " ${INCUS_STORAGE_DIR} "
97
+
98
+ # The keys should've been re-imported automatically by Incus.
99
+ zfs get -H -o name,property,value keystatus " $zpool_name " | grep -Eq " $zpool_name \s+keystatus\s+available"
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
+ shutdown_incus " ${INCUS_STORAGE_DIR} "
111
+
112
+ # The pool should be exported now.
113
+ ! zpool status " $zpool_name " 2> /dev/null
114
+
115
+ # Restart Incus.
116
+ respawn_incus " ${INCUS_STORAGE_DIR} "
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
+
48
127
do_zfs_cross_pool_copy () {
49
128
# shellcheck disable=2039,3043
50
129
local INCUS_STORAGE_DIR incus_backend
0 commit comments