Manifestbasierter Production-Updater 3.3, Modulnavigation, optionales Produktbild Studio, Listing-Studio-Aktionsleiste sowie plattformübergreifende Windows-/Linux-Release-Gates.
137 lines
4.6 KiB
Bash
137 lines
4.6 KiB
Bash
#!/usr/bin/env sh
|
|
set -eu
|
|
|
|
ROOT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
TMP_DIR=$(mktemp -d)
|
|
HOST_KIND=${VENDOO_INSTALLER_SHELL_HOST:-auto}
|
|
|
|
cleanup() { rm -rf "$TMP_DIR"; }
|
|
trap cleanup EXIT INT TERM
|
|
|
|
fail() {
|
|
printf '%s\n' "[FEHLER] $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
show_file() {
|
|
label=$1
|
|
file=$2
|
|
printf '%s\n' "--- $label: $file ---" >&2
|
|
if [ -f "$file" ]; then cat "$file" >&2; else printf '%s\n' '(Datei fehlt)' >&2; fi
|
|
printf '%s\n' "--- Ende $label ---" >&2
|
|
}
|
|
|
|
assert_file() {
|
|
file=$1
|
|
label=$2
|
|
[ -f "$file" ] || fail "$label fehlt: $file"
|
|
}
|
|
|
|
assert_dir() {
|
|
dir=$1
|
|
label=$2
|
|
[ -d "$dir" ] || fail "$label fehlt: $dir"
|
|
}
|
|
|
|
assert_contains() {
|
|
pattern=$1
|
|
file=$2
|
|
label=$3
|
|
if ! grep -q "$pattern" "$file"; then
|
|
show_file "$label" "$file"
|
|
fail "$label enthält das erwartete Muster nicht: $pattern"
|
|
fi
|
|
}
|
|
|
|
assert_token() {
|
|
file=$1
|
|
if ! grep -Eq '^VENDOO_SETUP_TOKEN=[0-9a-f]{64}$' "$file"; then
|
|
show_file '.env' "$file"
|
|
fail 'VENDOO_SETUP_TOKEN fehlt oder ist nicht 64-stellig hexadezimal.'
|
|
fi
|
|
}
|
|
|
|
is_windows_shell() {
|
|
if [ "$HOST_KIND" = windows ]; then return 0; fi
|
|
if [ "$HOST_KIND" = posix ]; then return 1; fi
|
|
case "$(uname -s 2>/dev/null || printf unknown)" in
|
|
MINGW*|MSYS*|CYGWIN*) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
assert_env_permissions() {
|
|
file=$1
|
|
if is_windows_shell; then
|
|
# Git Bash runs on NTFS and cannot reliably represent POSIX mode 0600.
|
|
# The Linux/NAS/VPS branch below remains strict. On Windows we verify
|
|
# that the installer still contains and executes the chmod hardening.
|
|
assert_contains 'chmod 600 "$ENV_FILE"' "$ROOT_DIR/setup.sh" 'setup.sh-Härtung'
|
|
assert_contains 'chmod 600 "$tmp"' "$ROOT_DIR/setup.sh" 'setup.sh-Härtung'
|
|
[ -r "$file" ] && [ -w "$file" ] || fail '.env ist unter Git Bash nicht les- und schreibbar.'
|
|
printf '%s\n' '[INFO] NTFS/Git-Bash erkannt: POSIX-Modus 0600 wird statisch geprüft; exakte Modusprüfung erfolgt auf Linux/NAS/VPS.'
|
|
return 0
|
|
fi
|
|
|
|
mode=$(stat -c '%a' "$file" 2>/dev/null || true)
|
|
[ "$mode" = 600 ] || fail ".env besitzt auf POSIX nicht Modus 600, sondern: ${mode:-unbekannt}"
|
|
}
|
|
|
|
mkdir -p "$TMP_DIR/bin"
|
|
cat > "$TMP_DIR/bin/docker" <<'EOF'
|
|
#!/usr/bin/env sh
|
|
printf '%s\n' "docker $*" >> "${FAKE_DOCKER_LOG:?}"
|
|
exit 0
|
|
EOF
|
|
cat > "$TMP_DIR/bin/curl" <<'EOF'
|
|
#!/usr/bin/env sh
|
|
exit 0
|
|
EOF
|
|
chmod +x "$TMP_DIR/bin/docker" "$TMP_DIR/bin/curl"
|
|
|
|
run_mode() {
|
|
name=$1
|
|
input=$2
|
|
dir="$TMP_DIR/$name"
|
|
mkdir -p "$dir"
|
|
|
|
if ! tar -C "$ROOT_DIR" --exclude=.git --exclude=node_modules --exclude=release-output -cf - . | tar -C "$dir" -xf -; then
|
|
fail "Release-Kopie für Modus $name konnte nicht erstellt werden."
|
|
fi
|
|
|
|
FAKE_DOCKER_LOG="$dir/docker.log"
|
|
export FAKE_DOCKER_LOG
|
|
if ! printf '%b' "$input" | PATH="$TMP_DIR/bin:$PATH" sh "$dir/setup.sh" install > "$dir/out.log" 2>&1; then
|
|
show_file "setup.sh-Ausgabe ($name)" "$dir/out.log"
|
|
show_file "Docker-Aufrufe ($name)" "$dir/docker.log"
|
|
fail "setup.sh ist im Modus $name fehlgeschlagen."
|
|
fi
|
|
|
|
assert_file "$dir/out.log" "Installer-Ausgabe ($name)"
|
|
assert_file "$dir/.env" ".env ($name)"
|
|
assert_file "$dir/docker.log" "Docker-Protokoll ($name)"
|
|
assert_contains 'keine Datei musste manuell bearbeitet werden' "$dir/out.log" "Installer-Ausgabe ($name)"
|
|
assert_token "$dir/.env"
|
|
assert_contains 'docker compose build --pull' "$dir/docker.log" "Docker-Protokoll ($name)"
|
|
assert_contains 'docker compose up -d --remove-orphans' "$dir/docker.log" "Docker-Protokoll ($name)"
|
|
assert_env_permissions "$dir/.env"
|
|
}
|
|
|
|
run_mode docker '1\n8124\nnein\n'
|
|
assert_contains '^VENDOO_PUBLISH_ADDRESS=127.0.0.1$' "$TMP_DIR/docker/.env" 'Docker-.env'
|
|
assert_contains '^VENDOO_BIND_HOST=0.0.0.0$' "$TMP_DIR/docker/.env" 'Docker-.env'
|
|
|
|
run_mode nas '2\n9124\nhttp://192.168.1.50:9124\nnein\n'
|
|
assert_dir "$TMP_DIR/nas/runtime/config" 'NAS-Konfigurationsordner'
|
|
assert_dir "$TMP_DIR/nas/runtime/db" 'NAS-Datenbankordner'
|
|
assert_contains '^VENDOO_PUBLISH_ADDRESS=0.0.0.0$' "$TMP_DIR/nas/.env" 'NAS-.env'
|
|
assert_contains '^PUBLIC_BASE_URL=http://192.168.1.50:9124$' "$TMP_DIR/nas/.env" 'NAS-.env'
|
|
|
|
run_mode vps '3\n8124\nvendoo.example.invalid\nnein\n'
|
|
assert_contains '^VENDOO_DOMAIN=vendoo.example.invalid$' "$TMP_DIR/vps/.env" 'VPS-.env'
|
|
assert_contains '^PUBLIC_BASE_URL=https://vendoo.example.invalid$' "$TMP_DIR/vps/.env" 'VPS-.env'
|
|
assert_contains '^VENDOO_COOKIE_SECURE=true$' "$TMP_DIR/vps/.env" 'VPS-.env'
|
|
assert_contains '^VENDOO_TRUST_PROXY=true$' "$TMP_DIR/vps/.env" 'VPS-.env'
|
|
|
|
printf '%s\n' 'Shell-Installer-Gate erfolgreich: Docker-, NAS- und VPS-Dialog erzeugen valide Konfiguration; POSIX-Dateirechte werden auf Linux/NAS/VPS strikt geprüft.'
|