#!/usr/bin/env bash # Play a match locally, in the container. # # ./run.sh # default training scenario # ./run.sh data/scenarios/TrainingScenarios/2-Ambush.mms # HUMAN=TraineeA ./run.sh # # then open http://localhost:8080/ and pick the seat's client (one app per # seat, at /) # # Ctrl-C stops the container. This runs the real image with a generated launch # manifest and no upload targets, so it exercises the same entrypoint, init, # watch and exit scripts a real match does. # # This is the interactive entry point, for a person at a terminal. For something # that has to start a match, wait for it and stop it again, use # ./scripts/arena.sh - same image, same manifest, same caps, detached. # # The manifest and the resource caps come from scripts/lib/common.sh, so the two # scripts cannot drift. set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" # shellcheck source=lib/common.sh . "$ROOT/scripts/lib/common.sh" SCENARIO="${1:-TrainingScenarios/1-FirstRun.mms}" # relative to the scenario library HUMAN="${HUMAN:-}" PORT_WS="${PORT_WS:-8080}" NAME="${CONTAINER_NAME:-arena-dev}" require_cmd jq docker # Capped like every other start. Two JVMs of headroom on a laptop is not a # kindness: an uncapped match takes the whole machine, and it also measures a # shape nothing is deployed on. ARENA_CPUS / ARENA_MEMORY / ARENA_PIDS move # them within bounds; nothing removes them. arena_resolve_caps # IMAGE_SELECTOR is a tag or whatever scripts/image.sh accepts. Empty is the # versions.env composition, which is what this always did. IMAGE="$(arena_resolve_image "${IMAGE_SELECTOR:-}")" # The name collision this always caught, plus the one it did not: an arena # container already running under some other name. Three JVMs twice over is the # failure worth refusing. arena_require_none_running "./scripts/arena.sh down stops it" || exit 1 if docker ps -a --format '{{.Names}}' | grep -qx "$NAME"; then echo "ERROR: a container named '$NAME' already exists." >&2 echo " docker rm -f $NAME removes it" >&2 exit 1 fi MANIFEST="$(mktemp)" trap 'rm -f "$MANIFEST"' EXIT arena_write_manifest "$IMAGE" "$SCENARIO" "$HUMAN" "$MANIFEST" MOUNTS=( -v "$MANIFEST:/run/dev-manifest.json:ro" ) SCRIPTS_NOTE="baked into the image" # container/ is COPYed into the image, so editing an init, watch or exit script # normally means a rebuild before the change has any effect - and a stale image # fails in exactly the way the old code did, which is a confusing place to lose # time. LIVE_SCRIPTS=1 mounts the working copy over them, turning a rebuild into # a restart. # # Off by default: a plain ./run.sh should test what was actually built, or it # stops being evidence that the image works. if [ "${LIVE_SCRIPTS:-0}" = "1" ]; then MOUNTS+=( -v "$ROOT/container:/opt/arena/container:ro" ) SCRIPTS_NOTE="live from ./container (LIVE_SCRIPTS=1)" fi cat <