tests: Add TrueNAS tests (and tweak testsuite)

Signed-off-by: Jack Bendtsen <jack.bendtsen@mactrix.com>
Signed-off-by: Stuart Espey <stuart.espey@mactrix.com>
This commit is contained in:
Stuart Espey 2025-08-01 19:16:33 -04:00 committed by Stéphane Graber
parent 7770ffadc8
commit b95a9e8bd1
No known key found for this signature in database
GPG Key ID: C638974D64792D67
14 changed files with 338 additions and 22 deletions

View File

@ -24,6 +24,11 @@ Name | Default | Description
`INCUS_SKIP_TESTS` | "" | Space-delimited list of test names to skip
`INCUS_TEST_IMAGE` | "" (busybox test image) | Path to an image tarball to use instead of the default busybox image
`INCUS_TMPFS` | 0 | Sets up a tmpfs for the whole testsuite to run on (fast but needs memory)
`INCUS_TRUENAS_DATASET` | "" | The remote TrueNAS dataset that will contain all the `truenas` pools created whilst running tests and is required, and must exist, when using the `truenas` backend.
`INCUS_TRUENAS_API_KEY` | "" | If set, will be applied as `truenas.api_key` on `truenas` pools.
`INCUS_TRUENAS_CONFIG` | "" | If set, will be applied as `truenas.config` on `truenas` pools.
`INCUS_TRUENAS_HOST` | "" | If set, will be applied as `truenas.host` on `truenas` pools.
`INCUS_TRUENAS_ALLOW_INSECURE` | "" | If set, will be applied as `truenas.allow_insecure` on `truenas` pools.
`INCUS_NIC_SRIOV_PARENT` | "" | Enables SR-IOV NIC tests using the specified parent device
`INCUS_IB_PHYSICAL_PARENT` | "" | Enables Infiniband physical tests using the specified parent device
`INCUS_IB_SRIOV_PARENT` | "" | Enables Infiniband SR-IOV tests using the specified parent device

60
test/backends/truenas.sh Normal file
View File

@ -0,0 +1,60 @@
truenas_setup() {
# shellcheck disable=2039,3043
local INCUS_DIR
INCUS_DIR=$1
echo "==> Setting up TrueNAS backend in ${INCUS_DIR}"
}
truenas_configure() {
# shellcheck disable=2039,3043
local INCUS_DIR
INCUS_DIR=$1
echo "==> Configuring TrueNAS backend in ${INCUS_DIR}"
incus storage create "incustest-$(basename "${INCUS_DIR}")" truenas "$(truenas_source)/$(uuidgen)" "$(truenas_config)" "$(truenas_allow_insecure)" "$(truenas_api_key)"
incus profile device add default root disk path="/" pool="incustest-$(basename "${INCUS_DIR}")"
}
truenas_teardown() {
# shellcheck disable=2039,3043
local INCUS_DIR
INCUS_DIR=$1
echo "==> Tearing down TrueNAS backend in ${INCUS_DIR}"
}
# returns the base truenas source string
truenas_host_dataset() {
if [ -n "${INCUS_TRUENAS_HOST:-}" ]; then
echo "${INCUS_TRUENAS_HOST}:${INCUS_TRUENAS_DATASET}"
else
echo "${INCUS_TRUENAS_DATASET}"
fi
}
# returns the base truenas source string
truenas_source() {
echo "source=$(truenas_host_dataset)"
}
truenas_api_key() {
echo "truenas.api_key=${INCUS_TRUENAS_API_KEY:-}"
}
truenas_config() {
echo "truenas.config=${INCUS_TRUENAS_CONFIG:-}"
}
truenas_allow_insecure() {
echo "truenas.allow_insecure=${INCUS_TRUENAS_ALLOW_INSECURE:-}"
}
call_truenas_tool() {
# usage: call_truenas_tool dataset list -r --no-headers "${truenas_dataset}"
truenas_incus_ctl "--config=${INCUS_TRUENAS_CONFIG:-}" "--allow-insecure=${INCUS_TRUENAS_ALLOW_INSECURE:-0}" "--host=${INCUS_TRUENAS_HOST:-}" "--api-key=${INCUS_TRUENAS_API_KEY:-}" "$@"
}

View File

@ -175,6 +175,13 @@ EOF
volume.size: 25MiB
size: 1GiB
lvm.vg_name: incustest-$(basename "${TEST_DIR}")-${ns}
EOF
fi
if [ "${driver}" = "truenas" ]; then
cat >> "${INCUS_DIR}/preseed.yaml" << EOF
config:
source: $(truenas_host_dataset)/incustest-$(basename "${TEST_DIR}")
truenas.api_key: \"${INCUS_TRUENAS_API_KEY}\"
EOF
fi
if [ "${driver}" = "ceph" ]; then

View File

@ -48,6 +48,10 @@ available_storage_backends() {
fi
done
if [ -n "${INCUS_TRUENAS_DATASET:-}" ] && command -v "truenas_incus_ctl" > /dev/null 2>&1; then
backends="$backends truenas"
fi
echo "$backends"
}

View File

@ -60,6 +60,9 @@ if [ "$INCUS_BACKEND" != "random" ] && ! storage_backend_available "$INCUS_BACKE
elif [ "${INCUS_BACKEND}" = "linstor" ] && [ -z "${INCUS_LINSTOR_CLUSTER:-}" ]; then
echo "LINSTOR storage backend requires that \"INCUS_LINSTOR_CLUSTER\" be set."
exit 1
elif [ "${INCUS_BACKEND}" = "truenas" ] && [ -z "${INCUS_TRUENAS_DATASET:-}" ]; then
echo "TrueNAS storage backend requires that \"INCUS_TRUENAS_DATASET\" be set."
exit 1
fi
echo "Storage backend \"$INCUS_BACKEND\" is not available"
exit 1
@ -68,6 +71,12 @@ echo "==> Using storage backend ${INCUS_BACKEND}"
import_storage_backends
if [ "${INCUS_BACKEND}" = "truenas" ] && { [ "$#" -eq 0 ] || [ "$1" = "all" ] || [ "$1" = "cluster" ]; }; then
# The cluster tests use net-ns which is incompatible with open-iscsi
echo "TrueNAS storage backend does not support the cluster tests. Please specify a list of test suites, or 'standalone'"
exit 1
fi
cleanup() {
# Allow for failures and stop tracing everything
set +ex
@ -350,6 +359,7 @@ if [ "${1:-"all"}" != "cluster" ]; then
run_test test_storage_driver_ceph "ceph storage driver"
run_test test_storage_driver_cephfs "cephfs storage driver"
run_test test_storage_driver_linstor "linstor storage driver"
run_test test_storage_driver_truenas "truenas storage driver"
run_test test_storage_driver_zfs "zfs storage driver"
run_test test_storage_buckets "storage buckets"
run_test test_storage_bucket_export "storage buckets export and import"

View File

@ -238,6 +238,12 @@ ceph.user.name=$(incus storage get "${poolName}" ceph.user.name)
poolExtraConfig="linstor.resource_group.place_count=$(incus storage get "${poolName}" linstor.resource_group.place_count)
linstor.volume.prefix=$(incus storage get "${poolName}" linstor.volume.prefix)
linstor.resource_group.name=$(incus storage get "${poolName}" linstor.resource_group.name)
"
;;
truenas)
poolExtraConfig="$(truenas_config)
$(truenas_allow_insecure)
$(truenas_api_key)
"
;;
esac
@ -298,8 +304,8 @@ test_bucket_recover() {
poolDriver=$(incus storage show "${poolName}" | awk '/^driver:/ {print $2}')
bucketName="bucket123"
# Skip ceph and linstor drivers, as they do not support storage buckets
if [ "${poolDriver}" = "ceph" ] || [ "${poolDriver}" = "linstor" ]; then
# Skip ceph, linstor and truenas drivers, as they do not support storage buckets
if [ "${poolDriver}" = "ceph" ] || [ "${poolDriver}" = "linstor" ] || [ "${poolDriver}" = "truenas" ]; then
return 0
fi

View File

@ -1005,16 +1005,16 @@ test_clustering_storage_single_node() {
driver_config=""
if [ "${poolDriver}" = "btrfs" ]; then
driver_config="size=1GiB"
fi
if [ "${poolDriver}" = "zfs" ]; then
elif [ "${poolDriver}" = "zfs" ]; then
driver_config="size=1GiB"
fi
if [ "${poolDriver}" = "ceph" ]; then
elif [ "${poolDriver}" = "ceph" ]; then
driver_config="source=incustest-$(basename "${TEST_DIR}")-pool1"
fi
if [ "${poolDriver}" = "linstor" ]; then
elif [ "${poolDriver}" = "linstor" ]; then
driver_config="source=incustest-$(basename "${TEST_DIR}" | sed 's/\./__/g')-pool1"
elif [ "${poolDriver}" = "truenas" ]; then
driver_config="$(truenas_source)/incustest-$(basename "${TEST_DIR}")-pool1 $(truenas_config) $(truenas_allow_insecure) $(truenas_api_key)"
fi
driver_config_node="${driver_config}"
if [ "${poolDriver}" = "zfs" ]; then
driver_config_node="${driver_config_node} zfs.pool_name=pool1-$(basename "${TEST_DIR}")-${ns1}"

View File

@ -13,9 +13,12 @@ test_container_move() {
incus project create "${project}"
if [ "${incus_backend}" = "linstor" ]; then
incus storage create "${pool2}" "${incus_backend}" linstor.resource_group.place_count=1
elif [ "$incus_backend" = "truenas" ]; then
incus storage create "${pool2}" "${incus_backend}" "$(truenas_source)/$(uuidgen)" "$(truenas_config)" "$(truenas_allow_insecure)" "$(truenas_api_key)"
else
incus storage create "${pool2}" "${incus_backend}"
fi
incus profile create "${profile}" --project "${project}"
incus profile device add "${profile}" root disk pool="${pool2}" path=/ --project "${project}"

View File

@ -103,7 +103,7 @@ migration() {
# perform existence check for various files.
incus_remote start l2:nonlive
# FIXME: make this backend agnostic
if [ "$incus2_backend" != "lvm" ] && [ "$incus2_backend" != "zfs" ] && [ "$incus2_backend" != "ceph" ] && [ "$incus2_backend" != "linstor" ]; then
if [ "$incus2_backend" != "lvm" ] && [ "$incus2_backend" != "zfs" ] && [ "$incus2_backend" != "ceph" ] && [ "$incus2_backend" != "linstor" ] && [ "$incus2_backend" != "truenas" ]; then
[ -d "${incus2_dir}/containers/nonlive/rootfs" ]
fi
incus_remote stop l2:nonlive --force
@ -120,7 +120,7 @@ migration() {
incus_remote start l2:nonlive
[ -d "${INCUS_DIR}/containers/nonlive2" ]
# FIXME: make this backend agnostic
if [ "$incus2_backend" != "lvm" ] && [ "$incus2_backend" != "zfs" ] && [ "$incus2_backend" != "ceph" ] && [ "$incus2_backend" != "linstor" ]; then
if [ "$incus2_backend" != "lvm" ] && [ "$incus2_backend" != "zfs" ] && [ "$incus2_backend" != "ceph" ] && [ "$incus2_backend" != "linstor" ] && [ "$incus2_backend" != "truenas" ]; then
[ -d "${incus2_dir}/containers/nonlive/rootfs/bin" ]
fi
@ -131,7 +131,7 @@ migration() {
incus_remote copy l1:nonlive2/snap0 l2:nonlive3 --mode=relay
# FIXME: make this backend agnostic
if [ "$incus2_backend" != "lvm" ] && [ "$incus2_backend" != "zfs" ] && [ "$incus2_backend" != "ceph" ] && [ "$incus2_backend" != "linstor" ]; then
if [ "$incus2_backend" != "lvm" ] && [ "$incus2_backend" != "zfs" ] && [ "$incus2_backend" != "ceph" ] && [ "$incus2_backend" != "linstor" ] && [ "$incus2_backend" != "truenas" ]; then
[ -d "${incus2_dir}/containers/nonlive3/rootfs/bin" ]
fi
incus_remote delete l2:nonlive3 --force
@ -250,9 +250,9 @@ migration() {
[ "$(incus info udssr | grep -c snap)" -eq 2 ]
incus delete udssr
if [ "$incus_backend" = "zfs" ]; then
# Test container only copies when zfs.clone_copy is set to false.
incus storage set "incustest-$(basename "${INCUS_DIR}")" zfs.clone_copy false
if [ "$incus_backend" = "zfs" ] || [ "$incus_backend" = "truenas" ]; then
# Test container only copies when zfs|truenas.clone_copy is set to false.
incus storage set "incustest-$(basename "${INCUS_DIR}")" "${incus_backend}.clone_copy" false
incus init testimage cccp
incus snapshot create cccp
incus snapshot create cccp
@ -268,7 +268,7 @@ migration() {
incus delete cccp
incus delete udssr
incus storage unset "incustest-$(basename "${INCUS_DIR}")" zfs.clone_copy
incus storage unset "incustest-$(basename "${INCUS_DIR}")" "${incus_backend}.clone_copy"
fi
incus_remote init testimage l1:c1

View File

@ -44,7 +44,7 @@ snapshots() {
incus copy foo/tester foosnap1
# FIXME: make this backend agnostic
if [ "$incus_backend" != "lvm" ] && [ "${incus_backend}" != "zfs" ] && [ "$incus_backend" != "ceph" ] && [ "$incus_backend" != "linstor" ]; then
if [ "$incus_backend" != "lvm" ] && [ "$incus_backend" != "zfs" ] && [ "$incus_backend" != "ceph" ] && [ "$incus_backend" != "linstor" ] && [ "$incus_backend" != "truenas" ]; then
[ -d "${INCUS_DIR}/containers/foosnap1/rootfs" ]
fi
@ -141,7 +141,7 @@ snap_restore() {
incus storage volume set "${pool}" container/bar user.foo=snap0
# Check parent volume.block.filesystem is copied to snapshot and not from pool.
if [ "$incus_backend" = "lvm" ] || [ "$incus_backend" = "ceph" ]; then
if [ "$incus_backend" = "lvm" ] || [ "$incus_backend" = "ceph" ] || [ "$incus_backend" = "truenas" ]; then
# Change pool volume.block.filesystem setting after creation of instance and before snapshot.
incus storage set "${pool}" volume.block.filesystem=xfs
fi
@ -173,7 +173,7 @@ snap_restore() {
incus storage volume set "${pool}" container/bar user.foo=postsnaps
# Check volume.block.filesystem on storage volume in parent and snapshot match.
if [ "${incus_backend}" = "lvm" ] || [ "${incus_backend}" = "ceph" ]; then
if [ "${incus_backend}" = "lvm" ] || [ "${incus_backend}" = "ceph" ] || [ "${incus_backend}" = "truenas" ]; then
# Change pool volume.block.filesystem setting after creation of instance and before snapshot.
pool=$(incus config profile device get default root pool)
parentFS=$(incus storage volume get "${pool}" container/bar block.filesystem)
@ -189,9 +189,9 @@ snap_restore() {
##########################################################
# Both ZFS and LINSTOR are limited to rollback only to the latest snapshots. Since
# ZFS, LINSTOR and TrueNAS are limited to rollback only to the latest snapshots. Since
# in this case we have a more recent snap1, we can't restore to snap0.
if [ "$incus_backend" != "zfs" ] && [ "$incus_backend" != "linstor" ]; then
if [ "$incus_backend" != "zfs" ] && [ "$incus_backend" != "linstor" ] && [ "$incus_backend" != "truenas" ]; then
restore_and_compare_fs snap0
# Check container config has been restored (limits.cpu is unset)
@ -280,7 +280,7 @@ snap_restore() {
# Start container and then restore snapshot to verify the running state after restore.
incus start bar
if [ "$incus_backend" != "zfs" ] && [ "$incus_backend" != "linstor" ]; then
if [ "$incus_backend" != "zfs" ] && [ "$incus_backend" != "linstor" ] && [ "$incus_backend" != "truenas" ]; then
# see comment above about snap0
restore_and_compare_fs snap0
@ -364,7 +364,9 @@ test_snap_schedule() {
incus restart c1 -f
incus info c1 | grep -q snap1
incus rm -f c1 c2 c3 c4 c5
for i in c1 c2 c3 c4 c5; do
incus rm -f "$i"
done
}
test_snap_volume_db_recovery() {

View File

@ -16,6 +16,8 @@ test_storage() {
storage_volume="${storage_pool}-vol"
if [ "${incus_backend}" = "linstor" ]; then
incus storage create "$storage_pool" "$incus_backend" linstor.resource_group.place_count=1 --description foo
elif [ "${incus_backend}" = "truenas" ]; then
incus storage create "$storage_pool" "$incus_backend" "$(truenas_source)/" "$(truenas_config)" "$(truenas_allow_insecure)" "$(truenas_api_key)" --description foo
else
incus storage create "$storage_pool" "$incus_backend" --description foo
fi
@ -888,6 +890,8 @@ test_storage() {
storage_pool="incustest-$(basename "${INCUS_DIR}")-pool26"
if [ "${incus_backend}" = "linstor" ]; then
incus storage create "$storage_pool" "$incus_backend" linstor.resource_group.place_count=1
elif [ "${incus_backend}" = "truenas" ]; then
incus storage create "$storage_pool" "$incus_backend" "$(truenas_source)/$(basename "${INCUS_DIR}")-pool26" "$(truenas_config)" "$(truenas_allow_insecure)" "$(truenas_api_key)"
else
incus storage create "$storage_pool" "$incus_backend"
fi

View File

@ -0,0 +1,204 @@
test_storage_driver_truenas() {
do_storage_driver_truenas ext4
do_storage_driver_truenas xfs
do_storage_driver_truenas btrfs
}
maybe_list_datasets() {
# full list of datasets and snaps
call_truenas_tool list -r --no-headers "$1"
}
do_storage_driver_truenas() {
filesystem="$1"
if ! command -v "mkfs.${filesystem}" > /dev/null 2>&1; then
echo "==> SKIP: Skipping TrueNAS block mode test on ${filesystem} due to missing tools."
return
fi
# shellcheck disable=2039,3043
local INCUS_STORAGE_DIR incus_backend truenas_dataset truenas_storage_pool
incus_backend=$(storage_backend "$INCUS_DIR")
if [ "$incus_backend" != "truenas" ]; then
return
fi
INCUS_STORAGE_DIR=$(mktemp -d -p "${TEST_DIR}" XXXXXXXXX)
chmod +x "${INCUS_STORAGE_DIR}"
spawn_incus "${INCUS_STORAGE_DIR}" false
truenas_storage_pool="incustest-$(basename "${INCUS_DIR}")"
truenas_dataset=$(incus storage get "${truenas_storage_pool}" truenas.dataset)
# block.filesystem defaults to ext4, but other tests can set this.
incus storage unset incustest-"$(basename "${INCUS_DIR}")" volume.block.filesystem
# Import image into default storage pool.
ensure_import_testimage
fingerprint=$(incus image info testimage | awk '/^Fingerprint/ {print $2}')
# Create non-block container
incus launch testimage c1
maybe_list_datasets "${truenas_dataset}"
# Check created container and image volumes
[ "$(call_truenas_tool dataset list --no-headers -o name "${truenas_dataset}/containers/c1")" = "${truenas_dataset}/containers/c1" ]
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/containers/c1")" = "volume" ]
[ "$(call_truenas_tool dataset list --no-headers -o name "${truenas_dataset}/images/${fingerprint}_ext4")" = "${truenas_dataset}/images/${fingerprint}_ext4" ]
[ "$(call_truenas_tool snapshot list --no-headers -o name "${truenas_dataset}/images/${fingerprint}_ext4@readonly")" = "${truenas_dataset}/images/${fingerprint}_ext4@readonly" ]
# Set block filesystem
incus storage set incustest-"$(basename "${INCUS_DIR}")" volume.block.filesystem "${filesystem}"
incus launch testimage c2
incus config device override c2 root size=11GiB
maybe_list_datasets "${truenas_dataset}"
# Check created truenas volumes
[ "$(call_truenas_tool dataset list --no-headers -o name "${truenas_dataset}/containers/c2")" = "${truenas_dataset}/containers/c2" ]
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/containers/c2")" = "volume" ]
[ "$(call_truenas_tool dataset list --no-headers -o name "${truenas_dataset}/images/${fingerprint}_${filesystem}")" = "${truenas_dataset}/images/${fingerprint}_${filesystem}" ]
[ "$(call_truenas_tool snapshot list --no-headers -o name "${truenas_dataset}/images/${fingerprint}_${filesystem}@readonly")" = "${truenas_dataset}/images/${fingerprint}_${filesystem}@readonly" ]
# Create container in block mode with smaller size override.
incus init testimage c3 -d root,size=5GiB
incus delete -f c3
# Delete image volume
incus storage volume rm incustest-"$(basename "${INCUS_DIR}")" image/"${fingerprint}"
maybe_list_datasets "${truenas_dataset}"
[ "$(call_truenas_tool dataset list --no-headers -o name "${truenas_dataset}/deleted/images/${fingerprint}_${filesystem}")" = "${truenas_dataset}/deleted/images/${fingerprint}_${filesystem}" ]
[ "$(call_truenas_tool snapshot list --no-headers -o name "${truenas_dataset}/deleted/images/${fingerprint}_${filesystem}@readonly")" = "${truenas_dataset}/deleted/images/${fingerprint}_${filesystem}@readonly" ]
incus stop -f c1 c2
# Try renaming instance
incus rename c2 c3
# Create snapshot
incus snapshot create c3 snap0
maybe_list_datasets "${truenas_dataset}"
[ "$(call_truenas_tool list --no-headers -o type "${truenas_dataset}/containers/c3@snapshot-snap0")" = "snapshot" ]
# This should create c11 and c21 as zvols, but c11 is cloned, and c21 is replicated
incus copy c1 c11
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/containers/c11")" = "volume" ]
maybe_list_datasets "${truenas_dataset}"
incus copy c3 c21
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/containers/c21")" = "volume" ]
[ "$(call_truenas_tool list --no-headers -o type "${truenas_dataset}/containers/c21@snapshot-snap0")" = "snapshot" ]
maybe_list_datasets "${truenas_dataset}"
# Create storage volumes
incus storage volume create incustest-"$(basename "${INCUS_DIR}")" vol1
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/custom/default_vol1")" = "volume" ]
[ "$(call_truenas_tool dataset list --no-headers -o incus:content_type "${truenas_dataset}/custom/default_vol1")" = "filesystem" ]
maybe_list_datasets "${truenas_dataset}"
incus storage volume copy incustest-"$(basename "${INCUS_DIR}")"/vol1 incustest-"$(basename "${INCUS_DIR}")"/vol1-clone
[ "$(call_truenas_tool dataset list --no-headers -o incus:content_type "${truenas_dataset}/custom/default_vol1")" = "filesystem" ]
maybe_list_datasets "${truenas_dataset}"
incus storage volume create incustest-"$(basename "${INCUS_DIR}")" vol2 --type=block
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/custom/default_vol2")" = "volume" ]
[ "$(call_truenas_tool dataset list --no-headers -o incus:content_type "${truenas_dataset}/custom/default_vol2")" = "block" ]
maybe_list_datasets "${truenas_dataset}"
incus storage volume copy incustest-"$(basename "${INCUS_DIR}")"/vol2 incustest-"$(basename "${INCUS_DIR}")"/vol2-clone
maybe_list_datasets "${truenas_dataset}"
[ "$(call_truenas_tool dataset list --no-headers -o incus:content_type "${truenas_dataset}/custom/default_vol2")" = "block" ]
incus storage volume attach incustest-"$(basename "${INCUS_DIR}")" vol1 c1 /mnt
incus storage volume attach incustest-"$(basename "${INCUS_DIR}")" vol1 c3 /mnt
incus storage volume attach incustest-"$(basename "${INCUS_DIR}")" vol1 c21 /mnt
incus start c1
incus start c3
incus start c21
incus exec c3 -- touch /mnt/foo
incus exec c21 -- ls /mnt/foo
incus exec c1 -- ls /mnt/foo
incus storage volume detach incustest-"$(basename "${INCUS_DIR}")" vol1 c1
incus storage volume detach incustest-"$(basename "${INCUS_DIR}")" vol1 c3
incus storage volume detach incustest-"$(basename "${INCUS_DIR}")" vol1 c21
! incus exec c3 -- ls /mnt/foo || false
! incus exec c21 -- ls /mnt/foo || false
# Backup and import
incus launch testimage c4
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/containers/c4")" = "volume" ]
incus exec c4 -- touch /root/foo
incus stop -f c4
incus snapshot create c4 snap0
incus export c4 "${INCUS_DIR}/c4.tar.gz"
incus rm -f c4
incus import "${INCUS_DIR}/c4.tar.gz" c4
[ "$(call_truenas_tool dataset list --no-headers -o type "${truenas_dataset}/containers/c4")" = "volume" ]
[ "$(call_truenas_tool list --no-headers -o type "${truenas_dataset}/containers/c4@snapshot-snap0")" = "snapshot" ]
incus start c4
incus exec c4 -- test -f /root/foo
# Snapshot and restore
incus snapshot create c4 snap1
incus exec c4 -- touch /root/bar
incus stop -f c4
incus snapshot restore c4 snap1
incus start c4
incus exec c4 -- test -f /root/foo
! incus exec c4 -- test -f /root/bar || false
[ "$(call_truenas_tool list --no-headers -o type "${truenas_dataset}/containers/c4@snapshot-snap1")" = "snapshot" ]
incus snapshot rename c4 snap1 snap-rename
[ "$(call_truenas_tool list --no-headers -o type "${truenas_dataset}/containers/c4@snapshot-snap-rename")" = "snapshot" ]
incus storage set incustest-"$(basename "${INCUS_DIR}")" volume.size=5GiB
incus launch testimage c5
incus storage unset incustest-"$(basename "${INCUS_DIR}")" volume.size
# restore default back to ext4, otherwise it can affect future tests.
incus storage unset incustest-"$(basename "${INCUS_DIR}")" volume.block.filesystem
# Clean up. TrueNAS create/delete can be very slow, this can cause the default 120s command timeout to be exceeded when doing mass instance deletes.
# FIXME: when deletes aren't so slow, just use `incus rm -f c1 c3 c11 c21 c4 c5`
instances="c1 c3 c11 c21 c4 c5"
for i in $instances; do
incus rm -f "$i"
done
incus storage volume rm incustest-"$(basename "${INCUS_DIR}")" vol1
incus storage volume rm incustest-"$(basename "${INCUS_DIR}")" vol1-clone
incus storage volume rm incustest-"$(basename "${INCUS_DIR}")" vol2
incus storage volume rm incustest-"$(basename "${INCUS_DIR}")" vol2-clone
maybe_list_datasets "${truenas_dataset}"
# shellcheck disable=SC2031
kill_incus "${INCUS_STORAGE_DIR}"
}

View File

@ -27,6 +27,10 @@ test_storage_local_volume_handling() {
fi
fi
if storage_backend_available "truenas"; then
incus storage create "${pool_base}-truenas" truenas "$(truenas_source)/$(uuidgen)" "$(truenas_config)" "$(truenas_allow_insecure)" "$(truenas_api_key)"
fi
incus storage create "${pool_base}-dir" dir
if storage_backend_available "lvm"; then
@ -60,6 +64,10 @@ test_storage_local_volume_handling() {
pool_opts="volume.size=25MiB ceph.osd.pg_num=16"
fi
if [ "$driver" = "truenas" ]; then
pool_opts="$(truenas_source)/$(uuidgen) $(truenas_config) $(truenas_allow_insecure) $(truenas_api_key)"
fi
if [ "$driver" = "lvm" ]; then
pool_opts="volume.size=25MiB"
fi

View File

@ -20,9 +20,12 @@ test_storage_volume_snapshots() {
if [ "${incus_backend}" = "linstor" ]; then
incus storage create "$storage_pool" "$incus_backend" linstor.resource_group.place_count=1
elif [ "${incus_backend}" = "truenas" ]; then
incus storage create "$storage_pool" "$incus_backend" "$(truenas_source)/" "$(truenas_config)" "$(truenas_allow_insecure)" "$(truenas_api_key)"
else
incus storage create "$storage_pool" "$incus_backend"
fi
incus storage volume create "${storage_pool}" "${storage_volume}"
incus launch testimage c1 -s "${storage_pool}"
incus storage volume attach "${storage_pool}" "${storage_volume}" c1 /mnt