2019-07-24 16:29:06 -04:00
|
|
|
test_container_devices_disk() {
|
2025-07-30 23:09:11 -04:00
|
|
|
ensure_import_testimage
|
|
|
|
|
ensure_has_localhost_remote "${INCUS_ADDR}"
|
2019-07-24 16:29:06 -04:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus init testimage foo
|
2019-07-24 16:29:06 -04:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
test_container_devices_disk_shift
|
|
|
|
|
test_container_devices_disk_subpath
|
|
|
|
|
test_container_devices_raw_mount_options
|
|
|
|
|
test_container_devices_disk_ceph
|
|
|
|
|
test_container_devices_disk_cephfs
|
|
|
|
|
test_container_devices_disk_socket
|
|
|
|
|
test_container_devices_disk_char
|
2025-08-28 19:32:35 +02:00
|
|
|
test_container_devices_disk_tmpfs
|
2019-07-24 16:29:06 -04:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus delete -f foo
|
2019-07-24 16:29:06 -04:00
|
|
|
}
|
|
|
|
|
|
2023-12-06 16:47:03 -05:00
|
|
|
test_container_devices_disk_shift() {
|
2025-07-30 23:09:11 -04:00
|
|
|
# shellcheck disable=2039,3043
|
|
|
|
|
local incus_backend
|
|
|
|
|
incus_backend=$(storage_backend "$INCUS_DIR")
|
|
|
|
|
|
|
|
|
|
if [ -n "${INCUS_IDMAPPED_MOUNTS_DISABLE:-}" ]; then
|
2023-12-06 16:47:03 -05:00
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
if [ "${incus_backend}" = "zfs" ]; then
|
|
|
|
|
# ZFS 2.2 is required for idmapped mounts support.
|
|
|
|
|
zfs_version=$(zfs --version | grep -m 1 '^zfs-' | cut -d '-' -f 2)
|
|
|
|
|
if [ "$(printf '%s\n' "$zfs_version" "2.2" | sort -V | head -n1)" = "$zfs_version" ]; then
|
|
|
|
|
if [ "$zfs_version" != "2.2" ]; then
|
|
|
|
|
echo "ZFS version is less than 2.2. Skipping idmapped mounts tests."
|
|
|
|
|
return
|
|
|
|
|
else
|
|
|
|
|
echo "ZFS version is 2.2. Idmapped mounts are supported with ZFS."
|
|
|
|
|
fi
|
|
|
|
|
else
|
|
|
|
|
echo "ZFS version is greater than 2.2. Idmapped mounts are supported with ZFS."
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Test basic shifting
|
|
|
|
|
mkdir -p "${TEST_DIR}/shift-source"
|
|
|
|
|
touch "${TEST_DIR}/shift-source/a"
|
|
|
|
|
chown 123:456 "${TEST_DIR}/shift-source/a"
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus start foo
|
|
|
|
|
incus config device add foo idmapped_mount disk source="${TEST_DIR}/shift-source" path=/mnt
|
|
|
|
|
[ "$(incus exec foo -- stat /mnt/a -c '%u:%g')" = "65534:65534" ] || false
|
|
|
|
|
incus config device remove foo idmapped_mount
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus config device add foo idmapped_mount disk source="${TEST_DIR}/shift-source" path=/mnt shift=true
|
|
|
|
|
[ "$(incus exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus stop foo -f
|
|
|
|
|
incus start foo
|
|
|
|
|
[ "$(incus exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
|
|
|
|
|
incus config device remove foo idmapped_mount
|
|
|
|
|
incus stop foo -f
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
# Test shifted custom volumes
|
|
|
|
|
POOL=$(incus profile device get default root pool)
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
# Cannot set both security.shifted and security.unmapped.
|
|
|
|
|
! incus storage volume create "${POOL}" foo-shift security.shifted=true security.unmapped=true || false
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus storage volume create "${POOL}" foo-shift security.shifted=true
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
# Cannot set both security.shifted and security.unmapped.
|
|
|
|
|
! incus storage volume set "${POOL}" foo-shift security.unmapped=true || false
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus start foo
|
|
|
|
|
incus launch testimage foo-priv -c security.privileged=true
|
|
|
|
|
incus launch testimage foo-isol1 -c security.idmap.isolated=true
|
|
|
|
|
incus launch testimage foo-isol2 -c security.idmap.isolated=true
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus config device add foo shifted disk pool="${POOL}" source=foo-shift path=/mnt
|
|
|
|
|
incus config device add foo-priv shifted disk pool="${POOL}" source=foo-shift path=/mnt
|
|
|
|
|
incus config device add foo-isol1 shifted disk pool="${POOL}" source=foo-shift path=/mnt
|
|
|
|
|
incus config device add foo-isol2 shifted disk pool="${POOL}" source=foo-shift path=/mnt
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus exec foo -- touch /mnt/a
|
|
|
|
|
incus exec foo -- chown 123:456 /mnt/a
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
[ "$(incus exec foo -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
|
|
|
|
|
[ "$(incus exec foo-priv -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
|
|
|
|
|
[ "$(incus exec foo-isol1 -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
|
|
|
|
|
[ "$(incus exec foo-isol2 -- stat /mnt/a -c '%u:%g')" = "123:456" ] || false
|
2023-12-06 16:47:03 -05:00
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
incus delete -f foo-priv foo-isol1 foo-isol2
|
|
|
|
|
incus config device remove foo shifted
|
|
|
|
|
incus storage volume delete "${POOL}" foo-shift
|
|
|
|
|
incus stop foo -f
|
2023-12-06 16:47:03 -05:00
|
|
|
}
|
|
|
|
|
|
2019-11-10 13:54:28 -06:00
|
|
|
test_container_devices_raw_mount_options() {
|
2025-07-30 23:09:11 -04:00
|
|
|
configure_loop_device loop_file_1 loop_device_1
|
|
|
|
|
# shellcheck disable=SC2154
|
|
|
|
|
mkfs.vfat "${loop_device_1}"
|
|
|
|
|
|
|
|
|
|
incus launch testimage foo-priv -c security.privileged=true
|
|
|
|
|
|
|
|
|
|
incus config device add foo-priv loop_raw_mount_options disk source="${loop_device_1}" path=/mnt
|
|
|
|
|
[ "$(incus exec foo-priv -- stat /mnt -c '%u:%g')" = "0:0" ] || false
|
|
|
|
|
incus exec foo-priv -- touch /mnt/foo
|
|
|
|
|
incus config device remove foo-priv loop_raw_mount_options
|
|
|
|
|
|
|
|
|
|
incus config device add foo-priv loop_raw_mount_options disk source="${loop_device_1}" path=/mnt raw.mount.options=uid=123,gid=456,ro
|
|
|
|
|
[ "$(incus exec foo-priv -- stat /mnt -c '%u:%g')" = "123:456" ] || false
|
|
|
|
|
! incus exec foo-priv -- touch /mnt/foo || false
|
|
|
|
|
incus config device remove foo-priv loop_raw_mount_options
|
|
|
|
|
|
|
|
|
|
incus stop foo-priv -f
|
|
|
|
|
incus config device add foo-priv loop_raw_mount_options disk source="${loop_device_1}" path=/mnt raw.mount.options=uid=123,gid=456,ro
|
|
|
|
|
incus start foo-priv
|
|
|
|
|
[ "$(incus exec foo-priv -- stat /mnt -c '%u:%g')" = "123:456" ] || false
|
|
|
|
|
! incus exec foo-priv -- touch /mnt/foo || false
|
|
|
|
|
incus config device remove foo-priv loop_raw_mount_options
|
|
|
|
|
|
|
|
|
|
incus delete -f foo-priv
|
|
|
|
|
# shellcheck disable=SC2154
|
|
|
|
|
deconfigure_loop_device "${loop_file_1}" "${loop_device_1}"
|
2019-11-10 13:54:28 -06:00
|
|
|
}
|
2019-11-12 18:58:04 -06:00
|
|
|
|
|
|
|
|
test_container_devices_disk_ceph() {
|
2025-07-30 23:09:11 -04:00
|
|
|
# shellcheck disable=SC2039,3043
|
|
|
|
|
local INCUS_BACKEND
|
|
|
|
|
|
|
|
|
|
INCUS_BACKEND=$(storage_backend "$INCUS_DIR")
|
|
|
|
|
if ! [ "${INCUS_BACKEND}" = "ceph" ]; then
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
RBD_POOL_NAME=incustest-$(basename "${INCUS_DIR}")-disk
|
|
|
|
|
ceph osd pool create "${RBD_POOL_NAME}" 1
|
|
|
|
|
rbd create --pool "${RBD_POOL_NAME}" --size 50M my-volume
|
|
|
|
|
RBD_DEVICE=$(rbd map --pool "${RBD_POOL_NAME}" my-volume)
|
|
|
|
|
mkfs.ext4 -m0 "${RBD_DEVICE}"
|
|
|
|
|
rbd unmap "${RBD_DEVICE}"
|
|
|
|
|
|
|
|
|
|
incus launch testimage ceph-disk -c security.privileged=true
|
|
|
|
|
incus config device add ceph-disk rbd disk source=ceph:"${RBD_POOL_NAME}"/my-volume ceph.user_name=admin ceph.cluster_name=ceph path=/ceph
|
|
|
|
|
incus exec ceph-disk -- stat /ceph/lost+found
|
|
|
|
|
incus restart ceph-disk --force
|
|
|
|
|
incus exec ceph-disk -- stat /ceph/lost+found
|
|
|
|
|
incus delete -f ceph-disk
|
|
|
|
|
ceph osd pool rm "${RBD_POOL_NAME}" "${RBD_POOL_NAME}" --yes-i-really-really-mean-it
|
2019-11-12 18:58:04 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
test_container_devices_disk_cephfs() {
|
2025-07-30 23:09:11 -04:00
|
|
|
# shellcheck disable=SC2039,3043
|
|
|
|
|
local INCUS_BACKEND
|
|
|
|
|
|
|
|
|
|
INCUS_BACKEND=$(storage_backend "$INCUS_DIR")
|
|
|
|
|
if [ "${INCUS_BACKEND}" != "ceph" ] || [ -z "${INCUS_CEPH_CEPHFS:-}" ]; then
|
|
|
|
|
return
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
incus launch testimage ceph-fs -c security.privileged=true
|
|
|
|
|
incus config device add ceph-fs fs disk source=cephfs:"${INCUS_CEPH_CEPHFS}"/ ceph.user_name=admin ceph.cluster_name=ceph path=/cephfs
|
|
|
|
|
incus exec ceph-fs -- stat /cephfs
|
|
|
|
|
incus restart ceph-fs --force
|
|
|
|
|
incus exec ceph-fs -- stat /cephfs
|
|
|
|
|
incus delete -f ceph-fs
|
2019-11-12 18:58:04 -06:00
|
|
|
}
|
2021-12-15 14:29:43 +00:00
|
|
|
|
|
|
|
|
test_container_devices_disk_socket() {
|
2025-07-30 23:09:11 -04:00
|
|
|
incus start foo
|
|
|
|
|
incus config device add foo unix-socket disk source="${INCUS_DIR}/unix.socket" path=/root/incus.sock
|
|
|
|
|
[ "$(incus exec foo -- stat /root/incus.sock -c '%F')" = "socket" ] || false
|
|
|
|
|
incus restart -f foo
|
|
|
|
|
[ "$(incus exec foo -- stat /root/incus.sock -c '%F')" = "socket" ] || false
|
|
|
|
|
incus config device remove foo unix-socket
|
|
|
|
|
incus stop foo -f
|
2021-12-15 14:29:43 +00:00
|
|
|
}
|
2022-07-04 09:04:47 +01:00
|
|
|
|
|
|
|
|
test_container_devices_disk_char() {
|
2025-07-30 23:09:11 -04:00
|
|
|
incus start foo
|
|
|
|
|
incus config device add foo char disk source=/dev/zero path=/root/zero
|
|
|
|
|
[ "$(incus exec foo -- stat /root/zero -c '%F')" = "character special file" ] || false
|
|
|
|
|
incus restart -f foo
|
|
|
|
|
[ "$(incus exec foo -- stat /root/zero -c '%F')" = "character special file" ] || false
|
|
|
|
|
incus config device remove foo char
|
|
|
|
|
incus stop foo -f
|
2022-07-04 09:04:47 +01:00
|
|
|
}
|
2024-08-08 02:03:55 -04:00
|
|
|
|
2025-08-28 19:32:35 +02:00
|
|
|
test_container_devices_disk_tmpfs() {
|
|
|
|
|
incus config device add foo tmp disk source=tmpfs: path=/mnt/tmp
|
|
|
|
|
incus start foo
|
|
|
|
|
[ "$(incus exec foo -- stat -f -c '%T' /mnt/tmp)" = "tmpfs" ] || false
|
|
|
|
|
incus stop -f foo
|
|
|
|
|
incus config device remove foo tmp
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-08 02:03:55 -04:00
|
|
|
test_container_devices_disk_subpath() {
|
2025-07-30 23:09:11 -04:00
|
|
|
POOL=$(incus profile device get default root pool)
|
|
|
|
|
|
|
|
|
|
# Create a test volume and main container
|
|
|
|
|
incus storage volume create "${POOL}" foo
|
|
|
|
|
incus launch testimage foo-main
|
|
|
|
|
incus config device add foo-main foo disk pool="${POOL}" source=foo path=/foo
|
|
|
|
|
|
|
|
|
|
# Create some entries
|
2025-09-01 13:28:36 +02:00
|
|
|
incus exec foo-main -- mkdir /foo/path1 /foo/path2 /foo/path3
|
|
|
|
|
incus exec foo-main -- ln -s /etc /foo/path4
|
|
|
|
|
incus exec foo-main -- ln -s path1 /foo/path5
|
2025-07-30 23:09:11 -04:00
|
|
|
echo path1 | incus file push - foo-main/foo/path1/hello
|
|
|
|
|
echo path2 | incus file push - foo-main/foo/path2/hello
|
2025-09-01 13:28:36 +02:00
|
|
|
echo path3 | incus file push - foo-main/foo/path3/hello
|
2025-07-30 23:09:11 -04:00
|
|
|
|
|
|
|
|
# Create some test containers
|
|
|
|
|
incus create testimage foo-path1
|
|
|
|
|
incus config device add foo-path1 foo disk pool="${POOL}" source=foo/path1 path=/foo
|
|
|
|
|
|
|
|
|
|
incus create testimage foo-path2
|
|
|
|
|
incus config device add foo-path2 foo disk pool="${POOL}" source=foo/path2 path=/foo
|
|
|
|
|
|
|
|
|
|
incus create testimage foo-path3
|
2025-09-01 13:28:36 +02:00
|
|
|
incus config device add foo-path3 foo disk pool="${POOL}" source=foo/path3/hello path=/foo/hello
|
2025-07-30 23:09:11 -04:00
|
|
|
|
|
|
|
|
incus create testimage foo-path4
|
|
|
|
|
incus config device add foo-path4 foo disk pool="${POOL}" source=foo/path4 path=/foo
|
|
|
|
|
|
2025-09-01 13:28:36 +02:00
|
|
|
incus create testimage foo-path5
|
|
|
|
|
incus config device add foo-path5 foo disk pool="${POOL}" source=foo/path5 path=/foo
|
|
|
|
|
|
2025-07-30 23:09:11 -04:00
|
|
|
# Validation
|
|
|
|
|
incus start foo-path1
|
|
|
|
|
incus start foo-path2
|
2025-09-01 13:28:36 +02:00
|
|
|
incus start foo-path3
|
|
|
|
|
! incus start foo-path4 || false
|
|
|
|
|
incus start foo-path5
|
2025-07-30 23:09:11 -04:00
|
|
|
|
|
|
|
|
[ "$(incus file pull foo-path1/foo/hello -)" = "path1" ]
|
|
|
|
|
[ "$(incus file pull foo-path2/foo/hello -)" = "path2" ]
|
2025-09-01 13:28:36 +02:00
|
|
|
[ "$(incus file pull foo-path3/foo/hello -)" = "path3" ]
|
|
|
|
|
[ "$(incus file pull foo-path5/foo/hello -)" = "path1" ]
|
2025-07-30 23:09:11 -04:00
|
|
|
|
|
|
|
|
# Cleanup
|
2025-09-01 13:28:36 +02:00
|
|
|
incus delete -f foo-main foo-path1 foo-path2 foo-path3 foo-path4 foo-path5
|
2025-07-30 23:09:11 -04:00
|
|
|
incus storage volume delete "${POOL}" foo
|
2024-08-08 02:03:55 -04:00
|
|
|
}
|