Files
playwish/install/lib.sh
T
99admandClaude Opus 5.5 3610de7bae Audiofy – Musikwünsche für Partys
Server (Website, Admin-Bereich, Player-API) und Player (raspotify +
Controller) mit Install-Skripten für Debian-Systeme.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:16:39 +01:00

147 lines
5.0 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Audiofy – gemeinsame Hilfsfunktionen für die Install-Skripte (wird per "source" geladen)
# shellcheck shell=bash
AUDIOFY_DIR="${AUDIOFY_DIR:-/opt/audiofy}"
AUDIOFY_USER="${AUDIOFY_USER:-audiofy}"
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VORLAGEN="$REPO/install/vorlagen"
if [ "$(id -u)" -eq 0 ]; then
SUDO=""
ALS_DIENST=(runuser -u "$AUDIOFY_USER" --)
else
SUDO="sudo"
ALS_DIENST=(sudo -u "$AUDIOFY_USER")
fi
# --- Ausgabe ------------------------------------------------------------------
schritt() { printf '\n\033[1m==> %s\033[0m\n' "$*"; }
info() { printf ' %s\n' "$*"; }
warnung() { printf '\033[33m ! %s\033[0m\n' "$*"; }
abbruch() { printf '\033[31m ✗ %s\033[0m\n' "$*" >&2; exit 1; }
# --- Abfragen -----------------------------------------------------------------
# frage VAR "Text" [Standard]
frage() {
local antwort
read -r -p " $2${3:+ [$3]}: " antwort
printf -v "$1" '%s' "${antwort:-${3:-}}"
}
# frage_geheim VAR "Text" – Eingabe wird nicht angezeigt
frage_geheim() {
local antwort
read -r -s -p " $2: " antwort
echo
printf -v "$1" '%s' "$antwort"
}
# ja_nein "Frage" [j|n] – Rückgabewert 0 = ja
ja_nein() {
local standard="${2:-j}" antwort
read -r -p " $1 [$([ "$standard" = j ] && echo J/n || echo j/N)]: " antwort
antwort="${antwort:-$standard}"
[[ "$antwort" =~ ^[jJyY] ]]
}
# --- System -------------------------------------------------------------------
pruefe_system() {
[ -f /etc/debian_version ] || abbruch "Nur für Debian und Debian-basierte Systeme (z. B. Raspberry Pi OS)."
command -v systemctl >/dev/null || abbruch "systemd wird benötigt."
command -v apt-get >/dev/null || abbruch "apt wird benötigt."
if [ -n "$SUDO" ]; then
command -v sudo >/dev/null || abbruch "Bitte als root ausführen oder sudo installieren."
info "Für die Einrichtung sind root-Rechte nötig – sudo fragt ggf. nach deinem Passwort."
sudo true || abbruch "sudo nicht möglich."
fi
python3 -c 'import sys; sys.exit(sys.version_info < (3, 11))' 2>/dev/null \
|| abbruch "Python 3.11 oder neuer wird benötigt (Debian 12 oder neuer)."
}
pakete() {
info "Installiere: $*"
$SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y -qq "$@" >/dev/null
}
dienst_benutzer() {
if ! id "$AUDIOFY_USER" >/dev/null 2>&1; then
$SUDO useradd --system --home-dir "$AUDIOFY_DIR" --no-create-home --shell /usr/sbin/nologin "$AUDIOFY_USER"
info "Dienst-Benutzer '$AUDIOFY_USER' angelegt (ohne Login, ohne sudo)"
fi
}
# code_kopieren QUELLE ZIEL – ersetzt den Inhalt von ZIEL (gehört root, Dienst darf nur lesen)
code_kopieren() {
local quelle="$1" ziel="$2"
$SUDO install -d -o root -g "$AUDIOFY_USER" -m 750 "$ziel"
$SUDO find "$ziel" -mindepth 1 -delete
tar -C "$quelle" --exclude='__pycache__' --exclude='.venv' --exclude='.pytest_cache' --exclude='tests' -cf - . \
| $SUDO tar -C "$ziel" --no-same-owner -xf -
$SUDO chown -R root:"$AUDIOFY_USER" "$ziel"
$SUDO find "$ziel" -type d -exec chmod 750 {} +
$SUDO find "$ziel" -type f -exec chmod 640 {} +
}
# venv_einrichten REQUIREMENTS
venv_einrichten() {
local venv="$AUDIOFY_DIR/.venv"
[ -x "$venv/bin/python" ] || $SUDO python3 -m venv "$venv"
$SUDO "$venv/bin/pip" install -q --upgrade pip
$SUDO "$venv/bin/pip" install -q -r "$1"
$SUDO chown -R root:"$AUDIOFY_USER" "$venv"
$SUDO chmod -R g+rX,o-rwx "$venv"
}
# vorlage DATEI ZIEL – ersetzt {{NAME}} durch den Wert der Shell-Variablen NAME
vorlage() {
local inhalt
inhalt="$(python3 - "$VORLAGEN/$1" <<'PY'
import os, re, sys
text = open(sys.argv[1]).read()
def ersetzen(m):
wert = os.environ.get(m.group(1))
if wert is None:
sys.exit(f"Vorlage {sys.argv[1]}: {m.group(1)} ist nicht gesetzt")
return wert
print(re.sub(r"\{\{([A-Z_]+)\}\}", ersetzen, text), end="")
PY
)" || abbruch "Vorlage $1 konnte nicht ausgefüllt werden"
printf '%s\n' "$inhalt" | $SUDO tee "$2" >/dev/null
}
# --- .env (gehört dem Dienst-Benutzer, Rechte 600) ------------------------------
# env_setzen DATEI KEY WERT – der Wert läuft über stdin (nicht in der Prozessliste sichtbar)
env_setzen() {
printf '%s' "$3" | "${ALS_DIENST[@]}" python3 -c '
import os, sys
pfad, key = sys.argv[1], sys.argv[2]
wert = sys.stdin.read()
zeilen = open(pfad).read().splitlines() if os.path.exists(pfad) else []
zeilen = [z for z in zeilen if not z.strip().startswith(key + "=")] + [f"{key}={wert}"]
fd = os.open(pfad, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
with os.fdopen(fd, "w") as f:
f.write("\n".join(zeilen) + "\n")
' "$1" "$2"
}
# env_wert DATEI KEY – gibt den Wert aus (leer, wenn nicht vorhanden)
env_wert() {
"${ALS_DIENST[@]}" sh -c 'grep -m1 "^$2=" "$1" 2>/dev/null | cut -d= -f2-' _ "$1" "$2" || true
}
# env_umbenennen DATEI ALT NEU – übernimmt alte Schlüsselnamen (für Updates)
env_umbenennen() {
local wert
if [ -z "$(env_wert "$1" "$3")" ]; then
wert="$(env_wert "$1" "$2")"
if [ -n "$wert" ]; then
env_setzen "$1" "$3" "$wert"
info "$2 → $3 übernommen"
fi
fi
}