Skip to content

Commit

Permalink
bin: Port more tests to Incus
Browse files Browse the repository at this point in the history
Signed-off-by: Stéphane Graber <[email protected]>
  • Loading branch information
stgraber committed Oct 26, 2023
1 parent 69d1b91 commit ff037c0
Show file tree
Hide file tree
Showing 8 changed files with 398 additions and 507 deletions.
111 changes: 111 additions & 0 deletions bin/test-incus-cpu-vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#!/bin/sh
set -eux

cleanup() {
echo ""
if [ "${FAIL}" = "1" ]; then
echo "Test failed"
exit 1
fi

echo "Test passed"
exit 0
}

architecture="$(uname -m)"

if [ "${architecture}" != "x86_64" ] && [ "${architecture}" != "s390x" ]; then
echo "Skipping test as CPU hotplugging not supported on ${architecture}"
fi

FAIL=1
trap cleanup EXIT HUP INT TERM

# Install test dependencies
apt-get remove --purge cloud-init --yes
apt-get install --yes curl iperf3 jq

# Install Incus
curl -sL https://pkgs.zabbly.com/get/incus-daily | sh

waitVMAgent() (
set +x
# shellcheck disable=SC3043
local vmName="$1"
for i in $(seq 90) # Wait up to 90s.
do
if incus info "${vmName}" | grep -qF 127.0.0.1; then
return 0 # Success.
fi

sleep 1
done

echo "VM ${vmName} agent not running after ${i}s"
return 1 # Failed.
)

# Configure Incus
incus network create incusbr0
incus profile device add default eth0 nic network=incusbr0

poolName="vmpool$$"
poolDriver=dir

echo "==> Create storage pool using driver ${poolDriver}"
incus storage create "${poolName}" "${poolDriver}"

echo "==> Create ephemeral VM and boot"
incus launch images:ubuntu/22.04 v1 --vm -s "${poolName}" --ephemeral
waitVMAgent v1
incus info v1

# Get number of CPUs
# shellcheck disable=SC2010
cpuCount="$(ls /sys/devices/system/cpu | grep -Ec 'cpu[[:digit:]]+')"

# VMs should have only 1 CPU per default
[ "$(incus exec v1 -- ls /sys/devices/system/cpu | grep -Ec 'cpu[[:digit:]]+')" -eq "1" ]

# Set valid CPU limits (low to high)
for i in $(seq 2 "${cpuCount}"); do
incus config set v1 limits.cpu="${i}"
[ "$(incus exec v1 -- ls /sys/devices/system/cpu | grep -Ec 'cpu[[:digit:]]+')" -eq "${i}" ]
done

# Try setting more CPUs than available
! incus config set v1 limits.cpu="$(( cpuCount + 1 ))" || false

# Set valid CPU limits (high to low)
for i in $(seq "${cpuCount}" -1 1); do
incus config set v1 limits.cpu="${i}"
[ "$(incus exec v1 -- ls /sys/devices/system/cpu | grep -Ec 'cpu[[:digit:]]+')" -eq "${i}" ]
done

# Try doing pinning while VM is running (shouldn't work)
! incus config set v1 limits.cpu=1,2 || false

# Set max CPU count
incus config set v1 limits.cpu="${cpuCount}"
[ "$(incus exec v1 -- ls /sys/devices/system/cpu | grep -Ec 'cpu[[:digit:]]+')" -eq "${cpuCount}" ]

# Unset CPU limit
incus config unset v1 limits.cpu

# Unsetting the limit should leave the VM with 1 CPU
[ "$(incus exec v1 -- ls /sys/devices/system/cpu | grep -Ec 'cpu[[:digit:]]+')" -eq "1" ]

echo "==> Stopping and deleting ephemeral VM"
# Stop VM and check its deleted.
incus stop -f v1
! incus info v1 || false

incus profile device remove default eth0

echo "==> Deleting storage pool"
incus storage delete "${poolName}"

echo "==> Deleting storage pool"
incus network delete incusbr0

FAIL=0
139 changes: 139 additions & 0 deletions bin/test-incus-guestapi-vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/bin/sh
set -eux

cleanup() {
echo ""
if [ "${FAIL}" = "1" ]; then
echo "Test failed"
exit 1
fi

echo "Test passed"
exit 0
}

FAIL=1
trap cleanup EXIT HUP INT TERM

# Install test dependencies
apt-get remove --purge cloud-init --yes
apt-get install --yes curl iperf3 jq

# Install Incus
curl -sL https://pkgs.zabbly.com/get/incus-daily | sh

waitVMAgent() (
set +x
# shellcheck disable=SC3043
local vmName="$1"
for i in $(seq 90) # Wait up to 90s.
do
if incus info "${vmName}" | grep -qF 127.0.0.1; then
return 0 # Success.
fi

sleep 1
done

echo "VM ${vmName} agent not running after ${i}s"
return 1 # Failed.
)

# Configure Incus
incus network create incusbr0
incus profile device add default eth0 nic network=incusbr0

poolName="vmpool$$"
poolDriver=dir

echo "==> Create storage pool using driver ${poolDriver}"
incus storage create "${poolName}" "${poolDriver}"

echo "==> Create VM and boot"
incus init images:ubuntu/22.04/cloud v1 --vm -s "${poolName}"
incus start v1
waitVMAgent v1
incus info v1

# Install curl
incus exec v1 -- sh -c "apt-get update && apt-get install --no-install-recommends --yes curl"

echo "==> Checking guestapi is working"

# guestapi is enabled by default and should work
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/devices | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/config | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/meta-data | grep -q '#cloud-config'

# Run sync before forcefully restarting the VM otherwise the filesystem will be corrupted.
incus exec v1 -- "sync"
incus restart -f v1
waitVMAgent v1

# guestapi should be running after restart
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/devices | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/config | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/meta-data | grep -q '#cloud-config'

# Disable guestapi
incus config set v1 security.guestapi false

echo "==> Checking guestapi is not working"

! incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 || false

incus exec v1 -- "sync"
incus restart -f v1
waitVMAgent v1

# guestapi should not be running after restart
! incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 || false

echo "==> Checking guestapi can be enabled live"

# Enable guestapi
incus config set v1 security.guestapi true

# guestapi should be running after the config is enabled
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0 | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/devices | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/config | jq
incus exec v1 -- curl -s --unix-socket /dev/incus/sock http://custom.socket/1.0/meta-data | grep -q '#cloud-config'

# test instance Ready state
incus exec v1 -- curl -s --unix-socket /dev/incus/sock -X PATCH -d '{"state":"Ready"}' http://custom.socket/1.0
[ "$(incus config get v1 volatile.last_state.ready)" = "true" ]

incus exec v1 -- curl -s --unix-socket /dev/incus/sock -X PATCH -d '{"state":"Started"}' http://custom.socket/1.0
[ "$(incus config get v1 volatile.last_state.ready)" = "false" ]

incus exec v1 -- curl -s --unix-socket /dev/incus/sock -X PATCH -d '{"state":"Ready"}' http://custom.socket/1.0
[ "$(incus config get v1 volatile.last_state.ready)" = "true" ]
incus stop -f v1
sleep 5
[ "$(incus config get v1 volatile.last_state.ready)" = "false" ]

# Test nested VM functionality.
incus start v1
waitVMAgent v1

# Configure to use the proxy
curl https://pkgs.zabbly.com/get/incus-daily | incus exec v1 -- sh
incus exec v1 -- incus admin init --auto
incus exec v1 -- incus launch images:ubuntu/22.04/cloud v1v1 --vm
sleep 30
incus exec v1 -- incus info v1v1 | grep -F RUNNING

echo "==> Deleting VM"
incus delete -f v1
incus profile device remove default eth0

echo "==> Deleting storage pool"
incus storage delete "${poolName}"

echo "==> Deleting storage pool"
incus network delete incusbr0

FAIL=0
88 changes: 88 additions & 0 deletions bin/test-incus-interception
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/sh
set -eu

cleanup() {
echo ""
if [ "${FAIL}" = "1" ]; then
echo "Test failed"
exit 1
fi

echo "Test passed"
exit 0
}

FAIL=1
trap cleanup EXIT HUP INT TERM

# Install test dependencies
apt-get remove --purge cloud-init --yes
apt-get install --yes curl iperf3 jq

# Install Incus
curl -sL https://pkgs.zabbly.com/get/incus-daily | sh

# Configure Incus
incus admin init --auto

# Test
set -x

incus launch images:ubuntu/20.04 c1
sleep 10
incus exec c1 -- apt-get install --no-install-recommends --yes attr fuse2fs

## setxattr
incus exec c1 -- touch xattr-test
! incus exec c1 -- setfattr -n trusted.overlay.opaque -v y xattr-test || false
incus config set c1 security.syscalls.intercept.setxattr true
incus restart c1 -f
incus exec c1 -- setfattr -n trusted.overlay.opaque -v y xattr-test
[ "$(getfattr --only-values --absolute-names -n trusted.overlay.opaque /var/lib/incus/containers/c1/rootfs/root/xattr-test)" = "y" ]

## mknod
! incus exec c1 -- mknod mknod-test c 1 3 || false
incus config set c1 security.syscalls.intercept.mknod true
incus restart c1 -f

## Relative path
incus exec c1 -- mknod mknod-test c 1 3

## Absolute path on tmpfs
incus exec c1 -- mknod /dev/mknod-test c 1 3

## Absolute path on rootfs
incus exec c1 -- mknod /root/mknod-test1 c 1 3

## bpf (needs 5.9 or higher)
incus config set c1 security.syscalls.intercept.bpf=true security.syscalls.intercept.bpf.devices=true
incus restart c1 -f

## mount
truncate -s 10G loop.img
LOOP=$(losetup -f --show loop.img)
incus config device add c1 loop unix-block source="${LOOP}" path=/dev/sda
incus exec c1 -- mkfs.ext4 /dev/sda
! incus exec c1 -- mount /dev/sda /mnt || false
incus config set c1 security.syscalls.intercept.mount=true

incus config set c1 security.syscalls.intercept.mount.allowed=ext4
incus restart c1 -f
incus exec c1 -- mount /dev/sda /mnt
[ "$(incus exec c1 -- stat --format=%u:%g /mnt)" = "65534:65534" ]
incus exec c1 -- umount /mnt

incus config set c1 security.syscalls.intercept.mount.shift=true
incus exec c1 -- mount /dev/sda /mnt
[ "$(incus exec c1 -- stat --format=%u:%g /mnt)" = "0:0" ]
incus exec c1 -- umount /mnt

incus config unset c1 security.syscalls.intercept.mount.allowed
incus config set c1 security.syscalls.intercept.mount.fuse=ext4=fuse2fs
incus restart c1 -f

incus exec c1 -- mount /dev/sda /mnt
[ "$(incus exec c1 -- stat --format=%u:%g /mnt)" = "0:0" ]
incus exec c1 -- umount /mnt

FAIL=0
Loading

0 comments on commit ff037c0

Please sign in to comment.