Loading deploy/bootstrap.sh +38 −4 Changes for deploy/bootstrap.sh: 38 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ # through the handshake address instead of modern forwarding # (default: legacy18). Read once at Velocity start, so changing it # means re-running this script and restarting the proxy. # FELIS_VELOCITY_XMX maximum heap of the Velocity proxy, as <n>M or <n>G (default: 1G; # at least 256M). docs/operations.md sizes it by player count. # FELIS_VELOCITY_FORK_JAR path to a Felis-Legacy Velocity fork build to install as the # proxy instead of the stock download (default: unset, stock). # FELIS_VELOCITY_FORK_JAR_SHA256 expected sha256 of that jar. REQUIRED whenever the jar Loading Loading @@ -91,9 +93,9 @@ # FELIS_WORLDS_HOST_PATH node directory holding the world volumes (on the k3s this # installer provisions: /var/lib/rancher/k3s/storage). Setting it # enables the daily retention reaper, which archives and then deletes # worlds idle beyond the retention window, and grants the reaper's # uid (1000) traverse access to that root — k3s ships it 0700 # root:root (default: unset = no reaper) # worlds idle beyond the retention window; the reaper reads that # root as root, so it keeps k3s's own 0700 root:root # (default: unset = no reaper) # FELIS_REGISTRY_STORAGE / FELIS_UPLOADS_STORAGE / FELIS_BACKUP_STORAGE capacity the # registry, uploads and world-archive PVCs request on first install # (defaults: 10Gi, 5Gi, 10Gi). An existing claim keeps its size; on Loading Loading @@ -170,6 +172,9 @@ FELIS_BACKUP_STORAGE="${FELIS_BACKUP_STORAGE:-}" # from its volumeName. Left unset, no reaper CronJob renders and archives accumulate until # the backup PVC fills (then backups fail loudly; nothing is deleted). FELIS_WORLDS_HOST_PATH="${FELIS_WORLDS_HOST_PATH:-}" # k3s's local-path provisioner root. It appears with the first volume the provisioner # creates, which on a fresh install is after the reaper's PV has been applied. K3S_STORAGE_ROOT="/var/lib/rancher/k3s/storage" # Control-plane database backups (felis db backup): a daily timer bundles pg_dump with the # /etc/felis state a rebuild needs, and every upgrade that has migrations to apply snapshots # the database first (felis migrate up). The directory sits outside /var/lib/rancher on Loading Loading @@ -211,6 +216,7 @@ FELIS_NANO_PROXY_CIDR="${FELIS_NANO_PROXY_CIDR:-}" # needs this. Overridable because adding a second 1.8 backend otherwise means editing this # script; it is still a restart-time list, not one that follows the CRs. FELIS_LEGACY_FORWARDING_SERVERS="${FELIS_LEGACY_FORWARDING_SERVERS:-legacy18}" FELIS_VELOCITY_XMX="${FELIS_VELOCITY_XMX:-1G}" # The Go tarball is unpacked and run as root, so the default version is pinned by the sha256 # go.dev/dl publishes for each architecture install_go_toolchain handles. Move all three # together; any other FELIS_GO_VERSION has to bring its own FELIS_GO_SHA256. Loading Loading @@ -703,6 +709,24 @@ validate_settings() { pinned|latest) ;; *) die "FELIS_GAME_STACK must be pinned or latest (got '${FELIS_GAME_STACK}')" ;; esac [ "$(heap_megabytes "$FELIS_VELOCITY_XMX")" -ge 256 ] \ || die "FELIS_VELOCITY_XMX must be a heap size of at least 256M, written <n>M or <n>G (got '${FELIS_VELOCITY_XMX}')" } # heap_megabytes prints a JVM heap size written <n>M or <n>G in megabytes, or 0 for any # other spelling. heap_megabytes() { local n="${1%?}" case "$n" in ""|*[!0-9]*|0*) echo 0; return ;; esac # Six digits of gigabytes is far past any host; the cap keeps the arithmetic in range. [ "${#n}" -le 6 ] || { echo 0; return; } case "$1" in *[Mm]) echo "$n" ;; *[Gg]) echo "$((n * 1024))" ;; *) echo 0 ;; esac } # validate_offsite_settings checks the FELIS_OFFSITE_* inputs before anything is Loading Loading @@ -2371,6 +2395,10 @@ install_velocity_service() { # sees it -- unquoted, that spelling would hand java a stray "legacy112" argument and the unit # would not start. Quoting keeps the whole property one argv item. local legacy_forwarding_servers="${FELIS_LEGACY_FORWARDING_SERVERS}" # -Xms stays at 512M so a small proxy does not reserve its whole ceiling up front, unless # the ceiling itself is lower (the JVM refuses an initial heap above the maximum). local xmx="$FELIS_VELOCITY_XMX" xms="512M" [ "$(heap_megabytes "$xmx")" -ge 512 ] || xms="$xmx" cat > "$VELOCITY_SERVICE" <<EOF [Unit] Description=Felis Velocity proxy (Mojang authentication + modern forwarding) Loading @@ -2382,7 +2410,7 @@ Type=simple User=${VELOCITY_USER} Group=${VELOCITY_USER} WorkingDirectory=${VELOCITY_DIR} ExecStart=${JRE_DIR}/bin/java -Xms512M -Xmx1G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -Dmojang.sessionserver=http://${api_ip}:8081/session/minecraft/hasJoined "-Dfelis.legacy-forwarding.servers=${legacy_forwarding_servers}" -jar ${VELOCITY_DIR}/velocity.jar ExecStart=${JRE_DIR}/bin/java -Xms${xms} -Xmx${xmx} -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -Dmojang.sessionserver=http://${api_ip}:8081/session/minecraft/hasJoined "-Dfelis.legacy-forwarding.servers=${legacy_forwarding_servers}" -jar ${VELOCITY_DIR}/velocity.jar Restart=on-failure RestartSec=5 NoNewPrivileges=yes Loading Loading @@ -3330,8 +3358,14 @@ deploy_bundle() { # through a static hostPath PV, so the host directory keeps k3s's own 0700 root:root and # needs no extra grant. It must exist, though: the PV declares type Directory. if [ ! -d "$FELIS_WORLDS_HOST_PATH" ]; then if [ "$FELIS_WORLDS_HOST_PATH" = "$K3S_STORAGE_ROOT" ]; then # The provisioner would create it moments later with this same 0700 root:root; # creating it now keeps a fresh install from warning about its own default. install -d -m 0700 -o root -g root "$FELIS_WORLDS_HOST_PATH" else warn "worlds root ${FELIS_WORLDS_HOST_PATH} does not exist yet; the reaper CronJob cannot start until it does (hostPath type Directory)" fi fi manifest_args+=(--worlds-host-path "$FELIS_WORLDS_HOST_PATH" --archive-local-path "$FELIS_ARCHIVE_LOCAL_PATH") fi local size Loading deploy/bootstrap_test.sh +33 −3 Changes for deploy/bootstrap_test.sh: 33 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -875,6 +875,8 @@ run_bundle_flags() { # backup-pvc worlds-host-path myManifests() { printf "%s\n" "$@"; } setfacl() { printf "SETFACL %s\n" "$*"; } chmod() { printf "CHMOD %s\n" "$*"; } install() { printf "INSTALL %s\n" "$*"; } K3S_STORAGE_ROOT="${K3S_STORAGE_ROOT_T:-/var/lib/rancher/k3s/storage}" node_global_cidrs() { printf "203.0.113.7/32\n2001:db8::7/128\n"; } pvc_size() { case "$2" in registry) printf "20Gi\n" ;; esac; } run_bundle() { Loading Loading @@ -935,6 +937,14 @@ missing="/tmp/felis-worlds-root-must-not-exist-$$" out="$(run_bundle_flags felis-backups "$missing")" expect "a missing worlds root is warned about, not silently skipped" "WARN: worlds root $missing does not exist yet" "$out" # On a fresh install the k3s default root does not exist until the provisioner's first # volume; the installer creates it with k3s's own mode instead of warning about its default. out="$(K3S_STORAGE_ROOT_T="$missing" run_bundle_flags felis-backups "$missing")" expect "a missing k3s storage root is created with k3s's mode" "INSTALL -d -m 0700 -o root -g root $missing" "$out" case "$out" in *WARN*) echo "FAIL: the installer's own default root must not be warned about: $out"; fails=$((fails + 1)) ;; esac # The reaper reads the root as root with DAC_OVERRIDE through a static PV, so an existing # root is left exactly as k3s shipped it: uid 1000 is now the game servers' uid, and a # traverse grant for it on the node's storage root would serve nothing but them. Loading Loading @@ -1709,15 +1719,15 @@ esac # felis-api's transactions) when restarted, so a rerun that changed none of them must leave # them running, and one that changed a thing must still restart it. vsblock="$(awk '/^install_velocity_service\(\) \{/,/^}/' "$BS"; awk '/^velocity_fingerprint\(\) \{/,/^}/' "$BS")" vsblock="$(awk '/^install_velocity_service\(\) \{/,/^}/' "$BS"; awk '/^velocity_fingerprint\(\) \{/,/^}/' "$BS"; awk '/^heap_megabytes\(\) \{/,/^}/' "$BS")" [ -n "$vsblock" ] || { echo "FAIL: no install_velocity_service found in $BS"; exit 1; } vdir="$(mktemp -d)" mkdir -p "$vdir/v/plugins/felis-link" "$vdir/jre" printf 'jar\n' > "$vdir/v/velocity.jar" printf 'plugin\n' > "$vdir/v/plugins/felis-velocity.jar" printf 'JAVA_VERSION="25"\n' > "$vdir/jre/release" run_velocity_service() { # is-active(0|1) ACTIVE="$1" VELOCITY_SERVICE="$vdir/unit" VELOCITY_DIR="$vdir/v" JRE_DIR="$vdir/jre" \ run_velocity_service() { # is-active(0|1) [heap] ACTIVE="$1" FELIS_VELOCITY_XMX="${2:-1G}" VELOCITY_SERVICE="$vdir/unit" VELOCITY_DIR="$vdir/v" JRE_DIR="$vdir/jre" \ VELOCITY_FINGERPRINT="$vdir/fp" VELOCITY_USER=felis-velocity FELIS_GAME_PORT=25565 \ FELIS_LEGACY_FORWARDING_SERVERS='' bash -c ' set -Eeuo pipefail Loading @@ -1734,6 +1744,7 @@ run_velocity_service() { # is-active(0|1) } out="$(run_velocity_service 1)" expect "a proxy with no recorded start is restarted" "SYSTEMCTL restart felis-velocity" "$out" expect "the default heap is 512M..1G" "java -Xms512M -Xmx1G " "$(cat "$vdir/unit")" [ -s "$vdir/fp" ] && echo "PASS the restart records what the proxy runs" \ || { echo "FAIL no fingerprint was recorded after the restart"; fails=$((fails + 1)); } out="$(run_velocity_service 1)" Loading @@ -1747,6 +1758,10 @@ expect "a changed plugin jar restarts the proxy" "SYSTEMCTL restart felis-veloci expect "a stopped proxy is started whatever the fingerprint" "SYSTEMCTL restart felis-velocity" "$(run_velocity_service 0)" printf 'JAVA_VERSION="25.0.1"\n' > "$vdir/jre/release" expect "a patched JRE restarts the proxy" "SYSTEMCTL restart felis-velocity" "$(run_velocity_service 1)" expect "a new heap size restarts the proxy" "SYSTEMCTL restart felis-velocity" "$(run_velocity_service 1 3G)" expect "the unit carries the new ceiling" "java -Xms512M -Xmx3G " "$(cat "$vdir/unit")" run_velocity_service 1 384M >/dev/null expect "a ceiling below 512M is also the initial heap" "java -Xms384M -Xmx384M " "$(cat "$vdir/unit")" rm -rf "$vdir" ssblock="$(awk '/^restart_existing_system_servers\(\) \{/,/^}/' "$BS")" Loading Loading @@ -1903,6 +1918,21 @@ expect "a v6 node address gets a v6 rule" "tcp dport 5432 ip6 saddr 2001:db8::7 rm -rf "$fwdir" # --- the proxy heap ----------------------------------------------------------------------- hblock="$(awk '/^heap_megabytes\(\) \{/,/^}/' "$BS")" [ -n "$hblock" ] || { echo "FAIL: no heap_megabytes found in $BS"; exit 1; } heap() { bash -c "$hblock"' heap_megabytes "$1"' _ "$1"; } expect "a heap in gigabytes converts to megabytes" "2048" "$(heap 2G)" expect "a heap in megabytes is kept" "768" "$(heap 768m)" for bad in 1 1K 0G 01G G -1G 1.5G 9999999G; do expect "the heap spelling '$bad' is refused" "0" "$(heap "$bad")" done case "$(awk '/^install_velocity_service\(\) \{/,/^}/' "$BS")" in *'-Xms${xms} -Xmx${xmx} '*) echo "PASS the proxy unit takes its heap from FELIS_VELOCITY_XMX" ;; *) echo "FAIL the proxy unit's heap is not FELIS_VELOCITY_XMX"; fails=$((fails + 1)) ;; esac # --- reproducible image ids --------------------------------------------------------------- # restart_existing_system_servers compares image ids across runs; a default BuildKit # provenance attestation (it carries a timestamp) would make every rebuild look new. Loading Loading
deploy/bootstrap.sh +38 −4 Changes for deploy/bootstrap.sh: 38 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -42,6 +42,8 @@ # through the handshake address instead of modern forwarding # (default: legacy18). Read once at Velocity start, so changing it # means re-running this script and restarting the proxy. # FELIS_VELOCITY_XMX maximum heap of the Velocity proxy, as <n>M or <n>G (default: 1G; # at least 256M). docs/operations.md sizes it by player count. # FELIS_VELOCITY_FORK_JAR path to a Felis-Legacy Velocity fork build to install as the # proxy instead of the stock download (default: unset, stock). # FELIS_VELOCITY_FORK_JAR_SHA256 expected sha256 of that jar. REQUIRED whenever the jar Loading Loading @@ -91,9 +93,9 @@ # FELIS_WORLDS_HOST_PATH node directory holding the world volumes (on the k3s this # installer provisions: /var/lib/rancher/k3s/storage). Setting it # enables the daily retention reaper, which archives and then deletes # worlds idle beyond the retention window, and grants the reaper's # uid (1000) traverse access to that root — k3s ships it 0700 # root:root (default: unset = no reaper) # worlds idle beyond the retention window; the reaper reads that # root as root, so it keeps k3s's own 0700 root:root # (default: unset = no reaper) # FELIS_REGISTRY_STORAGE / FELIS_UPLOADS_STORAGE / FELIS_BACKUP_STORAGE capacity the # registry, uploads and world-archive PVCs request on first install # (defaults: 10Gi, 5Gi, 10Gi). An existing claim keeps its size; on Loading Loading @@ -170,6 +172,9 @@ FELIS_BACKUP_STORAGE="${FELIS_BACKUP_STORAGE:-}" # from its volumeName. Left unset, no reaper CronJob renders and archives accumulate until # the backup PVC fills (then backups fail loudly; nothing is deleted). FELIS_WORLDS_HOST_PATH="${FELIS_WORLDS_HOST_PATH:-}" # k3s's local-path provisioner root. It appears with the first volume the provisioner # creates, which on a fresh install is after the reaper's PV has been applied. K3S_STORAGE_ROOT="/var/lib/rancher/k3s/storage" # Control-plane database backups (felis db backup): a daily timer bundles pg_dump with the # /etc/felis state a rebuild needs, and every upgrade that has migrations to apply snapshots # the database first (felis migrate up). The directory sits outside /var/lib/rancher on Loading Loading @@ -211,6 +216,7 @@ FELIS_NANO_PROXY_CIDR="${FELIS_NANO_PROXY_CIDR:-}" # needs this. Overridable because adding a second 1.8 backend otherwise means editing this # script; it is still a restart-time list, not one that follows the CRs. FELIS_LEGACY_FORWARDING_SERVERS="${FELIS_LEGACY_FORWARDING_SERVERS:-legacy18}" FELIS_VELOCITY_XMX="${FELIS_VELOCITY_XMX:-1G}" # The Go tarball is unpacked and run as root, so the default version is pinned by the sha256 # go.dev/dl publishes for each architecture install_go_toolchain handles. Move all three # together; any other FELIS_GO_VERSION has to bring its own FELIS_GO_SHA256. Loading Loading @@ -703,6 +709,24 @@ validate_settings() { pinned|latest) ;; *) die "FELIS_GAME_STACK must be pinned or latest (got '${FELIS_GAME_STACK}')" ;; esac [ "$(heap_megabytes "$FELIS_VELOCITY_XMX")" -ge 256 ] \ || die "FELIS_VELOCITY_XMX must be a heap size of at least 256M, written <n>M or <n>G (got '${FELIS_VELOCITY_XMX}')" } # heap_megabytes prints a JVM heap size written <n>M or <n>G in megabytes, or 0 for any # other spelling. heap_megabytes() { local n="${1%?}" case "$n" in ""|*[!0-9]*|0*) echo 0; return ;; esac # Six digits of gigabytes is far past any host; the cap keeps the arithmetic in range. [ "${#n}" -le 6 ] || { echo 0; return; } case "$1" in *[Mm]) echo "$n" ;; *[Gg]) echo "$((n * 1024))" ;; *) echo 0 ;; esac } # validate_offsite_settings checks the FELIS_OFFSITE_* inputs before anything is Loading Loading @@ -2371,6 +2395,10 @@ install_velocity_service() { # sees it -- unquoted, that spelling would hand java a stray "legacy112" argument and the unit # would not start. Quoting keeps the whole property one argv item. local legacy_forwarding_servers="${FELIS_LEGACY_FORWARDING_SERVERS}" # -Xms stays at 512M so a small proxy does not reserve its whole ceiling up front, unless # the ceiling itself is lower (the JVM refuses an initial heap above the maximum). local xmx="$FELIS_VELOCITY_XMX" xms="512M" [ "$(heap_megabytes "$xmx")" -ge 512 ] || xms="$xmx" cat > "$VELOCITY_SERVICE" <<EOF [Unit] Description=Felis Velocity proxy (Mojang authentication + modern forwarding) Loading @@ -2382,7 +2410,7 @@ Type=simple User=${VELOCITY_USER} Group=${VELOCITY_USER} WorkingDirectory=${VELOCITY_DIR} ExecStart=${JRE_DIR}/bin/java -Xms512M -Xmx1G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -Dmojang.sessionserver=http://${api_ip}:8081/session/minecraft/hasJoined "-Dfelis.legacy-forwarding.servers=${legacy_forwarding_servers}" -jar ${VELOCITY_DIR}/velocity.jar ExecStart=${JRE_DIR}/bin/java -Xms${xms} -Xmx${xmx} -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -Dmojang.sessionserver=http://${api_ip}:8081/session/minecraft/hasJoined "-Dfelis.legacy-forwarding.servers=${legacy_forwarding_servers}" -jar ${VELOCITY_DIR}/velocity.jar Restart=on-failure RestartSec=5 NoNewPrivileges=yes Loading Loading @@ -3330,8 +3358,14 @@ deploy_bundle() { # through a static hostPath PV, so the host directory keeps k3s's own 0700 root:root and # needs no extra grant. It must exist, though: the PV declares type Directory. if [ ! -d "$FELIS_WORLDS_HOST_PATH" ]; then if [ "$FELIS_WORLDS_HOST_PATH" = "$K3S_STORAGE_ROOT" ]; then # The provisioner would create it moments later with this same 0700 root:root; # creating it now keeps a fresh install from warning about its own default. install -d -m 0700 -o root -g root "$FELIS_WORLDS_HOST_PATH" else warn "worlds root ${FELIS_WORLDS_HOST_PATH} does not exist yet; the reaper CronJob cannot start until it does (hostPath type Directory)" fi fi manifest_args+=(--worlds-host-path "$FELIS_WORLDS_HOST_PATH" --archive-local-path "$FELIS_ARCHIVE_LOCAL_PATH") fi local size Loading
deploy/bootstrap_test.sh +33 −3 Changes for deploy/bootstrap_test.sh: 33 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -875,6 +875,8 @@ run_bundle_flags() { # backup-pvc worlds-host-path myManifests() { printf "%s\n" "$@"; } setfacl() { printf "SETFACL %s\n" "$*"; } chmod() { printf "CHMOD %s\n" "$*"; } install() { printf "INSTALL %s\n" "$*"; } K3S_STORAGE_ROOT="${K3S_STORAGE_ROOT_T:-/var/lib/rancher/k3s/storage}" node_global_cidrs() { printf "203.0.113.7/32\n2001:db8::7/128\n"; } pvc_size() { case "$2" in registry) printf "20Gi\n" ;; esac; } run_bundle() { Loading Loading @@ -935,6 +937,14 @@ missing="/tmp/felis-worlds-root-must-not-exist-$$" out="$(run_bundle_flags felis-backups "$missing")" expect "a missing worlds root is warned about, not silently skipped" "WARN: worlds root $missing does not exist yet" "$out" # On a fresh install the k3s default root does not exist until the provisioner's first # volume; the installer creates it with k3s's own mode instead of warning about its default. out="$(K3S_STORAGE_ROOT_T="$missing" run_bundle_flags felis-backups "$missing")" expect "a missing k3s storage root is created with k3s's mode" "INSTALL -d -m 0700 -o root -g root $missing" "$out" case "$out" in *WARN*) echo "FAIL: the installer's own default root must not be warned about: $out"; fails=$((fails + 1)) ;; esac # The reaper reads the root as root with DAC_OVERRIDE through a static PV, so an existing # root is left exactly as k3s shipped it: uid 1000 is now the game servers' uid, and a # traverse grant for it on the node's storage root would serve nothing but them. Loading Loading @@ -1709,15 +1719,15 @@ esac # felis-api's transactions) when restarted, so a rerun that changed none of them must leave # them running, and one that changed a thing must still restart it. vsblock="$(awk '/^install_velocity_service\(\) \{/,/^}/' "$BS"; awk '/^velocity_fingerprint\(\) \{/,/^}/' "$BS")" vsblock="$(awk '/^install_velocity_service\(\) \{/,/^}/' "$BS"; awk '/^velocity_fingerprint\(\) \{/,/^}/' "$BS"; awk '/^heap_megabytes\(\) \{/,/^}/' "$BS")" [ -n "$vsblock" ] || { echo "FAIL: no install_velocity_service found in $BS"; exit 1; } vdir="$(mktemp -d)" mkdir -p "$vdir/v/plugins/felis-link" "$vdir/jre" printf 'jar\n' > "$vdir/v/velocity.jar" printf 'plugin\n' > "$vdir/v/plugins/felis-velocity.jar" printf 'JAVA_VERSION="25"\n' > "$vdir/jre/release" run_velocity_service() { # is-active(0|1) ACTIVE="$1" VELOCITY_SERVICE="$vdir/unit" VELOCITY_DIR="$vdir/v" JRE_DIR="$vdir/jre" \ run_velocity_service() { # is-active(0|1) [heap] ACTIVE="$1" FELIS_VELOCITY_XMX="${2:-1G}" VELOCITY_SERVICE="$vdir/unit" VELOCITY_DIR="$vdir/v" JRE_DIR="$vdir/jre" \ VELOCITY_FINGERPRINT="$vdir/fp" VELOCITY_USER=felis-velocity FELIS_GAME_PORT=25565 \ FELIS_LEGACY_FORWARDING_SERVERS='' bash -c ' set -Eeuo pipefail Loading @@ -1734,6 +1744,7 @@ run_velocity_service() { # is-active(0|1) } out="$(run_velocity_service 1)" expect "a proxy with no recorded start is restarted" "SYSTEMCTL restart felis-velocity" "$out" expect "the default heap is 512M..1G" "java -Xms512M -Xmx1G " "$(cat "$vdir/unit")" [ -s "$vdir/fp" ] && echo "PASS the restart records what the proxy runs" \ || { echo "FAIL no fingerprint was recorded after the restart"; fails=$((fails + 1)); } out="$(run_velocity_service 1)" Loading @@ -1747,6 +1758,10 @@ expect "a changed plugin jar restarts the proxy" "SYSTEMCTL restart felis-veloci expect "a stopped proxy is started whatever the fingerprint" "SYSTEMCTL restart felis-velocity" "$(run_velocity_service 0)" printf 'JAVA_VERSION="25.0.1"\n' > "$vdir/jre/release" expect "a patched JRE restarts the proxy" "SYSTEMCTL restart felis-velocity" "$(run_velocity_service 1)" expect "a new heap size restarts the proxy" "SYSTEMCTL restart felis-velocity" "$(run_velocity_service 1 3G)" expect "the unit carries the new ceiling" "java -Xms512M -Xmx3G " "$(cat "$vdir/unit")" run_velocity_service 1 384M >/dev/null expect "a ceiling below 512M is also the initial heap" "java -Xms384M -Xmx384M " "$(cat "$vdir/unit")" rm -rf "$vdir" ssblock="$(awk '/^restart_existing_system_servers\(\) \{/,/^}/' "$BS")" Loading Loading @@ -1903,6 +1918,21 @@ expect "a v6 node address gets a v6 rule" "tcp dport 5432 ip6 saddr 2001:db8::7 rm -rf "$fwdir" # --- the proxy heap ----------------------------------------------------------------------- hblock="$(awk '/^heap_megabytes\(\) \{/,/^}/' "$BS")" [ -n "$hblock" ] || { echo "FAIL: no heap_megabytes found in $BS"; exit 1; } heap() { bash -c "$hblock"' heap_megabytes "$1"' _ "$1"; } expect "a heap in gigabytes converts to megabytes" "2048" "$(heap 2G)" expect "a heap in megabytes is kept" "768" "$(heap 768m)" for bad in 1 1K 0G 01G G -1G 1.5G 9999999G; do expect "the heap spelling '$bad' is refused" "0" "$(heap "$bad")" done case "$(awk '/^install_velocity_service\(\) \{/,/^}/' "$BS")" in *'-Xms${xms} -Xmx${xmx} '*) echo "PASS the proxy unit takes its heap from FELIS_VELOCITY_XMX" ;; *) echo "FAIL the proxy unit's heap is not FELIS_VELOCITY_XMX"; fails=$((fails + 1)) ;; esac # --- reproducible image ids --------------------------------------------------------------- # restart_existing_system_servers compares image ids across runs; a default BuildKit # provenance attestation (it carries a timestamp) would make every rebuild look new. Loading