#!/bin/sh set -e testdir=$(dirname "$(readlink -f "$0")") . "$testdir/.env" usage() { cat <] -f -q [...] test/env [] -C -t [...] Run in a pre-packaged container with all the packages required for running the test suite installed. Options: -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 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 -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 Infix RAUC bundle to use for upgrade tests. -q 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 -t 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 } 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 (cd "$envdir/qeneth/" && $qeneth generate && $qeneth start) INFAMY_ARGS="$INFAMY_ARGS $envdir/qeneth/topology.dot" cat <"$envdir/bin/qeneth" #!/bin/sh set -x cd $envdir/qeneth && exec $testdir/qeneth/qeneth "\$@" EOF chmod +x "$envdir/bin/qeneth" } name() { nm=infamy id=0 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 "$name" } # Global options containerize=yes [ -c /dev/kvm ] && kvm="--device=/dev/kvm" files= while getopts "cCDf:hiKp:q:t:" opt; do case ${opt} in 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) INFAMY_ARGS="$INFAMY_ARGS -p $OPTARG" ;; q) qenethdir="$OPTARG" network="--sysctl net.ipv6.conf.all.disable_ipv6=0" ;; 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 # shellcheck disable=SC2016 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 VIRTUAL_ENV_DISABLE_PROMPT=yes \ --env PROMPT_DIRTRIM="$ixdir" \ --env PS1="$(build_ps1)" \ --expose 9001-9010 --publish-all \ --hostname "$(name)" \ --name "$(name)" \ $interactive \ --rm \ --security-opt seccomp=unconfined \ $network \ --tty \ --volume "$ixdir":"$ixdir" \ --workdir "$ixdir/test" \ $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 exec "$@"