it-vm-userns.sh RawHistoryFolder
1#!/usr/bin/env bash
2# SPDX-License-Identifier: MIT
3#
4# Run the VM integration tests WITHOUT root: inside a user + network namespace
5# the process is "root" with CAP_NET_ADMIN over a private network stack, which is
6# enough for TAP devices, nftables and the DNS forwarder on the TAP address.
7# Only /dev/kvm access (group kvm) and the Firecracker binary are needed. The
8# jailer needs real root, so it is switched off here (see README: this tests the
9# whole driver except the jailer's chroot, uid drop and cgroups).
10#
11# scripts/it-vm-userns.sh [go test args]
12#
13# Environment: FIRECRACKER (default: firecracker in PATH), IMAGE_DIR (directory
14# with vmlinux and base.ext4, default tmp/image). Outbound internet from the
15# private namespace is not available: the tests do not need it.
16set -euo pipefail
17root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
18cd "$root"
19fc=${FIRECRACKER:-$(command -v firecracker || true)}
20[ -x "${fc:-}" ] || { echo "firecracker not found: set FIRECRACKER" >&2; exit 1; }
21img=${IMAGE_DIR:-$root/tmp/image}
22# Two separate namespaces: the VM tests leave TAP devices behind when they fail,
23# and the packet-level firewall test must start from a clean network stack.
24rc=0
25unshare --user --map-root-user --net bash -c '
26 ip link set lo up
27 # A default route, so that forwarded packets reach the firewall instead of
28 # being answered "network unreachable" by the routing table: the drops the
29 # network test sees are then the nftables policy.
30 ip link add dummy0 type dummy
31 ip addr add 192.0.2.1/24 dev dummy0
32 ip link set dummy0 up
33 ip route add default via 192.0.2.254 dev dummy0
34 export GOWORK=off ERMITE_RUNNER_IT_VM=1 \
35 ERMITE_RUNNER_ISOLATION=vm ERMITE_RUNNER_IMAGE="$1" \
36 ERMITE_RUNNER_FIRECRACKER="$2" ERMITE_RUNNER_JAILER_MODE=off \
37 ERMITE_RUNNER_LOCK_FILE="${TMPDIR:-/tmp}/ermite-runner-it-$$.lock"
38 shift 2
39 exec go test -count=1 -v -timeout 10m ./internal/sandbox/integration "$@"
40' _ "$img" "$fc" "$@" || rc=$?
41# The packet-level firewall test needs only a namespace, not Firecracker.
42unshare --user --map-root-user --net bash -c '
43 ip link set lo up
44 GOWORK=off ERMITE_RUNNER_IT_NET=1 exec go test -count=1 -v -timeout 10m -run TwoGuests ./internal/netpolicy
45' || rc=$?
46exit $rc