Files
Phoenix/kiosk-start.sh
T
2026-06-02 20:56:19 +02:00

224 lines
6.1 KiB
Bash

#!/bin/bash
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)"
KIOSK_USER="${KIOSK_USER:-analyzer}"
PHOENIX_DIR="${PHOENIX_DIR:-$SCRIPT_DIR}"
PHOENIX_BIN="${PHOENIX_BIN:-$PHOENIX_DIR/target/release/phoenix}"
SESSION_SCRIPT="${SESSION_SCRIPT:-$PHOENIX_DIR/session.sh}"
KIOSK_HOME="$(getent passwd "$KIOSK_USER" | cut -d: -f6)"
if [ -z "${KIOSK_HOME:-}" ]; then
KIOSK_HOME="/home/$KIOSK_USER"
fi
PHOENIX_BUILD_LOG="${PHOENIX_BUILD_LOG:-$KIOSK_HOME/phoenix-build.log}"
PHOENIX_MIN_RUSTC_VERSION="${PHOENIX_MIN_RUSTC_VERSION:-1.71.0}"
export PATH="/root/.cargo/bin:/home/${KIOSK_USER}/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:${PATH:-}"
export CARGO_NET_GIT_FETCH_WITH_CLI="${CARGO_NET_GIT_FETCH_WITH_CLI:-true}"
mkdir -p "$(dirname "$PHOENIX_BUILD_LOG")"
exec 3>&1 4>&2
BUILD_LOG_PIPE="$(mktemp -u /tmp/phoenix-build-log.XXXXXX)"
mkfifo "$BUILD_LOG_PIPE"
sed -u -E $'s/\x1B\\[[0-9;?]*[ -/]*[@-~]//g' < "$BUILD_LOG_PIPE" >> "$PHOENIX_BUILD_LOG" &
BUILD_LOG_FILTER_PID=$!
cleanup_logging() {
if [ -n "${BUILD_LOG_FILTER_PID:-}" ]; then
kill "$BUILD_LOG_FILTER_PID" 2>/dev/null || true
wait "$BUILD_LOG_FILTER_PID" 2>/dev/null || true
fi
if [ -n "${BUILD_LOG_PIPE:-}" ] && [ -p "${BUILD_LOG_PIPE:-}" ]; then
rm -f "$BUILD_LOG_PIPE"
fi
}
stop_build_logging() {
exec 1>&3 2>&4
cleanup_logging
exec 3>&- 4>&-
trap - EXIT
}
trap cleanup_logging EXIT
exec > >(tee "$BUILD_LOG_PIPE") 2>&1
echo "=== $(date): kiosk-start.sh START ==="
print_banner() {
local title="${1:-PHOENIX STARTET}"
local detail="${2:-Bitte warten...}"
if command -v clear >/dev/null 2>&1; then
clear || true
fi
cat <<EOF
--------------------------
$title
--------------------------
$detail
EOF
}
needs_phoenix_build() {
if [ ! -x "$PHOENIX_BIN" ] || [ ! -s "$PHOENIX_BIN" ]; then
return 0
fi
if [ -f "$PHOENIX_DIR/Cargo.toml" ] && [ "$PHOENIX_DIR/Cargo.toml" -nt "$PHOENIX_BIN" ]; then
return 0
fi
if [ -f "$PHOENIX_DIR/Cargo.lock" ] && [ "$PHOENIX_DIR/Cargo.lock" -nt "$PHOENIX_BIN" ]; then
return 0
fi
if [ -d "$PHOENIX_DIR/src" ] && find "$PHOENIX_DIR/src" -type f -name '*.rs' -newer "$PHOENIX_BIN" -print -quit | grep -q .; then
return 0
fi
return 1
}
build_phoenix_if_needed() {
if ! needs_phoenix_build; then
return 0
fi
print_banner \
"PHOENIX WIRD GEBAUT" \
"Der erste Start oder ein Update kann einige Minuten dauern."
ensure_build_prerequisites
wait_for_build_network
build_phoenix_with_retries
}
ensure_build_prerequisites() {
if [ "$(id -u)" -eq 0 ] && command -v apt-get >/dev/null 2>&1; then
print_banner \
"BUILD-ABHAENGIGKEITEN WERDEN GEPRUEFT" \
"Rust-Toolchain und Systempakete werden bei Bedarf vorbereitet."
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y pkg-config libasound2-dev curl ca-certificates git build-essential
fi
if ! has_supported_rust_toolchain; then
install_or_update_rust_toolchain
fi
if ! has_supported_rust_toolchain; then
echo "No supported Rust toolchain found. Need rustc >= ${PHOENIX_MIN_RUSTC_VERSION}."
exit 1
fi
}
has_supported_rust_toolchain() {
if ! command -v cargo >/dev/null 2>&1 || ! command -v rustc >/dev/null 2>&1; then
return 1
fi
local current
current="$(rustc_version)"
if [ -z "$current" ]; then
return 1
fi
version_ge "$current" "$PHOENIX_MIN_RUSTC_VERSION"
}
rustc_version() {
if ! command -v rustc >/dev/null 2>&1; then
return 1
fi
rustc --version 2>/dev/null | awk '{print $2}'
}
version_ge() {
local current="${1:-0}"
local minimum="${2:-0}"
[ "$(printf '%s\n%s\n' "$minimum" "$current" | sort -V | head -n1)" = "$minimum" ]
}
install_or_update_rust_toolchain() {
local current
current="$(rustc_version || true)"
if [ -n "$current" ]; then
echo "Current rustc ${current} is too old; need >= ${PHOENIX_MIN_RUSTC_VERSION}."
else
echo "Rust toolchain not found; installing via rustup."
fi
print_banner \
"AKTUELLE RUST-TOOLCHAIN WIRD INSTALLIERT" \
"Das System-Rust ist zu alt fuer Phoenix. Es wird rustup/stable verwendet."
if command -v rustup >/dev/null 2>&1; then
rustup toolchain install stable --profile minimal
rustup default stable
else
if ! command -v curl >/dev/null 2>&1; then
echo "curl not found; cannot install rustup."
return 1
fi
curl https://sh.rustup.rs -sSf | sh -s -- -y --profile minimal --default-toolchain stable
fi
export PATH="/root/.cargo/bin:/home/${KIOSK_USER}/.cargo/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"
hash -r
echo "Using rustc $(rustc_version || echo unknown)"
}
wait_for_build_network() {
if ! command -v getent >/dev/null 2>&1; then
return 0
fi
local host="${PHOENIX_BUILD_TEST_HOST:-github.com}"
local tries="${PHOENIX_BUILD_NET_WAIT_TRIES:-20}"
local sleep_s="${PHOENIX_BUILD_NET_WAIT_SLEEP_S:-2}"
local i
for ((i = 1; i <= tries; i++)); do
if getent hosts "$host" >/dev/null 2>&1; then
return 0
fi
echo "Waiting for DNS/network before build ($i/$tries): $host"
sleep "$sleep_s"
done
echo "DNS/network check did not succeed for $host; continuing with build retries."
}
build_phoenix_with_retries() {
local attempts="${PHOENIX_BUILD_RETRIES:-3}"
local sleep_s="${PHOENIX_BUILD_RETRY_SLEEP_S:-5}"
local attempt
for ((attempt = 1; attempt <= attempts; attempt++)); do
echo "Starting Phoenix build (attempt $attempt/$attempts)"
if (
cd "$PHOENIX_DIR"
CARGO_TERM_COLOR=always cargo build --release
); then
return 0
fi
if [ "$attempt" -lt "$attempts" ]; then
echo "Phoenix build failed; retrying in ${sleep_s}s..."
sleep "$sleep_s"
fi
done
echo "Phoenix build failed after $attempts attempts."
exit 1
}
if [ ! -f "$SESSION_SCRIPT" ]; then
echo "Session script missing: $SESSION_SCRIPT"
exit 1
fi
build_phoenix_if_needed
if [ ! -x "$PHOENIX_BIN" ] || [ ! -s "$PHOENIX_BIN" ]; then
echo "Phoenix binary missing, empty or not executable: $PHOENIX_BIN"
exit 1
fi
stop_build_logging
exec /usr/bin/xinit /bin/bash "$SESSION_SCRIPT" -- :0 -nolisten tcp -nocursor vt1