mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 09:13:01 +02:00
GitHub Actions sets $CI=true; treat it like -r so parallel jobs don't all try to claim "infamy0" and clobber each other.
281 lines
6.6 KiB
Bash
Executable File
281 lines
6.6 KiB
Bash
Executable File
#!/bin/sh
|
|
set -e
|
|
|
|
testdir=$(dirname "$(readlink -f "$0")")
|
|
. "$testdir/.env"
|
|
|
|
usage()
|
|
{
|
|
cat <<EOF
|
|
usage: test/env [-cDhiKr] -f <IMAGE> -q <QENETH-DIR> <COMMAND> [<ARGS>...]
|
|
test/env [-cDhiKr] -C -t <TOPOLOGY> <COMMAND> [<ARGS>...]
|
|
|
|
Run <COMMAND> in a pre-packaged container with all the packages
|
|
required for running the test suite installed.
|
|
|
|
Options:
|
|
|
|
-b <BASE-DIR>
|
|
Use this directory as the top-level bind mount inside the container.
|
|
If not specified, Infix's top directory is used.
|
|
|
|
-c
|
|
Clean up cruft, lingering images, old containers, unused volumes.
|
|
Used by GitHub action to prevent issues with running tests.
|
|
|
|
-C
|
|
Don't containerize the command, run it directly in the current
|
|
namespaces
|
|
|
|
-D
|
|
Prefer Docker over podman. This is implied when -t is specified,
|
|
as podman does not allow the necessary network permissions to be
|
|
granted to the container
|
|
|
|
-f <IMAGE>
|
|
Specify images required for test, squashfs image is required
|
|
if testing with kernel. bios and disk image is required if
|
|
testing with bios.
|
|
|
|
-h
|
|
Show this help message
|
|
|
|
-i
|
|
Interactive mode, e.g., 'make test-sh'
|
|
|
|
-K
|
|
Even if /dev/kvm is usable, do not map it the container. This is
|
|
useful to see how tests will run in a CI setting, where KVM is
|
|
typically not available
|
|
|
|
-p <BUNDLE>
|
|
Infix RAUC bundle to use for upgrade tests.
|
|
|
|
-q <QENETH-DIR>
|
|
Directory containing a topology.dot.in, suitable for consumption
|
|
by qeneth. A copy of this network is created, and launched. The
|
|
resulting topology is used as the default physical topology when
|
|
running tests
|
|
|
|
-r
|
|
Use random container names instead of "infamyN". Useful for the
|
|
unit tests running in CI environments which may see occasional
|
|
name clashes for "infamy0" due to race conditions.
|
|
|
|
-t <TOPOLOGY>
|
|
Rather than starting a qeneth network, attach to this existing
|
|
topology. If the command is containerized, it will be launched
|
|
in the host's network namespace
|
|
|
|
EOF
|
|
}
|
|
|
|
get_base_img()
|
|
{
|
|
local files="$1"
|
|
local base_img_file
|
|
base_img_file=$(echo "$files" | tr ' ' '\n' | grep -- '.qcow2$')
|
|
echo "$envdir/qeneth/$(basename "$base_img_file")"
|
|
}
|
|
|
|
start_topology()
|
|
{
|
|
qenethdir="$1"
|
|
files="$*"
|
|
|
|
[ "$files" ] || { true && return; }
|
|
[ "$qenethdir" ] || { true && return; }
|
|
|
|
rm -rf "$envdir/qeneth"
|
|
cp -a "$qenethdir" "$envdir/qeneth"
|
|
# Map files in to qeneth
|
|
for f in $files; do
|
|
filename="$(basename "$f")"
|
|
file=$(readlink -f "$f")
|
|
ln -sf "$file" "$envdir/qeneth/$filename"
|
|
done
|
|
|
|
base_img_qcow2=$(get_base_img "$files")
|
|
base_img_disk="${base_img_qcow2%.qcow2}.disk"
|
|
|
|
test_img_disk="${base_img_qcow2%.qcow2}-test.disk"
|
|
test_img_qcow2="${test_img_disk%.disk}.qcow2"
|
|
|
|
qemu-img convert -f qcow2 -O raw "$base_img_qcow2" "$base_img_disk"
|
|
$testdir/inject-test-mode -b "$base_img_disk" -o "$test_img_disk"
|
|
qemu-img convert -f raw -O qcow2 "$test_img_disk" "$test_img_qcow2"
|
|
|
|
img_name=$(basename $test_img_qcow2)
|
|
sed -i "s/qn_image=\".*\"/qn_image=\"$img_name\"/" "$envdir/qeneth/topology.dot.in"
|
|
|
|
(cd "$envdir/qeneth/" && $qeneth generate && $qeneth start)
|
|
INFAMY_ARGS="$INFAMY_ARGS $envdir/qeneth/topology.dot"
|
|
cat <<EOF >"$envdir/bin/qeneth"
|
|
#!/bin/sh
|
|
cd $envdir/qeneth && exec $testdir/qeneth/qeneth "\$@"
|
|
EOF
|
|
chmod +x "$envdir/bin/qeneth"
|
|
}
|
|
|
|
name()
|
|
{
|
|
nm=infamy
|
|
id=0
|
|
|
|
if [ -n "$random" ] || [ -n "$CI" ]; then
|
|
# Let podman/docker allocate random hostname and container name
|
|
return
|
|
fi
|
|
|
|
names=$($(runner) ps -f name='infamy.*' --format '{{.Names}}')
|
|
while true; do
|
|
name="$nm$id"
|
|
unset hit
|
|
for n in $names; do
|
|
if [ "$name" = "$n" ]; then
|
|
hit=true
|
|
break;
|
|
fi
|
|
done
|
|
|
|
if [ -n "$hit" ]; then
|
|
id=$((id + 1))
|
|
continue
|
|
fi
|
|
break;
|
|
done
|
|
|
|
echo "--hostname $name --name $name"
|
|
}
|
|
|
|
# Global options
|
|
containerize=yes
|
|
[ -c /dev/kvm ] && kvm="--device=/dev/kvm"
|
|
files=
|
|
basedir="$ixdir"
|
|
|
|
while getopts "b:cCDf:hiKp:q:rt:" opt; do
|
|
case ${opt} in
|
|
b)
|
|
basedir="$OPTARG"
|
|
;;
|
|
c)
|
|
$(runner) image prune -af
|
|
$(runner) volume prune -f
|
|
$(runner) container prune -f
|
|
exit 0
|
|
;;
|
|
C)
|
|
containerize=
|
|
;;
|
|
D)
|
|
runners="docker podman"
|
|
;;
|
|
f)
|
|
files="$files $OPTARG"
|
|
;;
|
|
h)
|
|
usage && exit 0
|
|
;;
|
|
i)
|
|
interactive=--interactive
|
|
;;
|
|
K)
|
|
kvm=
|
|
;;
|
|
p)
|
|
version=$(unsquashfs -cat $OPTARG manifest.raucm | awk -F'=' '/^version=/ {print $2}')
|
|
INFAMY_ARGS="$INFAMY_ARGS -p $OPTARG"
|
|
;;
|
|
q)
|
|
qenethdir="$OPTARG"
|
|
network="--sysctl net.ipv6.conf.all.disable_ipv6=0"
|
|
;;
|
|
r)
|
|
random=true
|
|
;;
|
|
t)
|
|
topology="$OPTARG"
|
|
network="--network host --volume $topology:$topology:ro"
|
|
runners="docker podman"
|
|
;;
|
|
*)
|
|
>&2 echo "Unknown option -$opt"
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ "$containerize" ]; then
|
|
volumes="--volume $basedir:$basedir --workdir=$ixdir/test"
|
|
case "$(runner)" in
|
|
docker)
|
|
volumes="$volumes --env HOST_CHOWN_PATH=$ixdir/test"
|
|
volumes="$volumes --env HOST_CHOWN_UID=$(id -u)"
|
|
volumes="$volumes --env HOST_CHOWN_GID=$(id -g)"
|
|
;;
|
|
podman)
|
|
;;
|
|
esac
|
|
|
|
mkdir -p "$HOME/.infix"
|
|
touch "$HOME/.infix/.ash_history"
|
|
|
|
# shellcheck disable=SC2016,SC2046,SC2086,SC2119
|
|
exec $(runner) run \
|
|
--cap-add=NET_RAW \
|
|
--cap-add=NET_ADMIN \
|
|
--device=/dev/net/tun \
|
|
--env PYTHONHASHSEED=${PYTHONHASHSEED:-$(shuf -i 0-$(((1 << 32) - 1)) -n 1)} \
|
|
--env PYTHONPYCACHEDIR=/tmp/__pycache__ \
|
|
--env VIRTUAL_ENV_DISABLE_PROMPT=yes \
|
|
--env INFAMY_ARGS="$INFAMY_ARGS" \
|
|
--env INFAMY_EXTRA_ARGS="$INFAMY_EXTRA_ARGS" \
|
|
--env PROMPT_DIRTRIM="$ixdir" \
|
|
--env NINEPM_PROJ_CONFIG="$NINEPM_PROJ_CONFIG" \
|
|
--env QENETH_PATH="$testdir/templates:$testdir" \
|
|
--env PS1="$(build_ps1)" \
|
|
--env VERSION="$version" \
|
|
$extra_env \
|
|
--expose 9001-9010 --publish-all \
|
|
-v "$HOME/.infix/.ash_history":/root/.ash_history \
|
|
$(name) \
|
|
$interactive \
|
|
--rm \
|
|
--security-opt seccomp=unconfined \
|
|
$network \
|
|
--tty \
|
|
$volumes \
|
|
$kvm \
|
|
$INFIX_TEST \
|
|
"$0" -C "$@"
|
|
else
|
|
if [ ! -f ~/.9pm.rc ]; then
|
|
cat <<-EOF >~/.9pm.rc
|
|
# Generated by Infix env
|
|
SSH_OPTS: "-o StrictHostKeyChecking=no"
|
|
LOG_PATH: "$logdir"
|
|
EOF
|
|
fi
|
|
fi
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
if [ $# -lt 1 ]; then
|
|
usage && exit 1
|
|
fi
|
|
|
|
# shellcheck disable=SC1091
|
|
. "$envdir/bin/activate"
|
|
export PYTHONPATH="$testdir"
|
|
INFAMY_ARGS="$INFAMY_ARGS -y $envdir/yangdir"
|
|
start_topology "$qenethdir" "$files"
|
|
[ "$topology" ] && INFAMY_ARGS="$INFAMY_ARGS $topology"
|
|
export INFAMY_ARGS
|
|
if [ -n "$INFAMY_EXTRA_ARGS" ]; then
|
|
exec "$@" -o="$INFAMY_EXTRA_ARGS"
|
|
fi
|
|
|
|
exec "$@"
|