Benutzer-Werkzeuge

Webseiten-Werkzeuge


hackspace:ausstattung:tv:tvheadend:tvheadend

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
hackspace:ausstattung:tv:tvheadend:tvheadend [2025/11/24 21:46] – angelegt spock0010hackspace:ausstattung:tv:tvheadend:tvheadend [2025/11/24 21:49] (aktuell) – [Dauereinsatz (Grundlage)] spock0010
Zeile 9: Zeile 9:
 Es nutzt tunebare v4l devices. Es nutzt tunebare v4l devices.
  
 +===== Docker Run (einfach testen) =====
  
 <code> <code>
Zeile 28: Zeile 29:
  
 </code> </code>
 +
 +
 +===== Dauereinsatz (Grundlage) =====
 +
 +<code>
 +#!/usr/bin/env bash
 +#
 +# tvheadend2-manage.sh
 +#
 +# Management-Script für den TVHeadend-Docker-Container "tvheadend2":
 +#   - install   : Erstinstallation / Neuinstallation
 +#   - update    : Image aktualisieren + Container neu erstellen
 +#   - clean     : Container stoppen + löschen (Daten bleiben erhalten)
 +#   - remove    : Alias für "clean"
 +#   - purge     : Container + Image + (optional) Daten löschen
 +#   - logs      : Logs anzeigen (follow)
 +#   - status    : Status anzeigen
 +#   - shell     : Shell im Container öffnen
 +#
 +# Unterstützt variable Basis-Verzeichnisse:
 +#   - /yacht/AppData/tvheadend2
 +#   - /srv/docker/tvheadend2
 +#
 +
 +set -euo pipefail
 +
 +########################################
 +# Konfiguration
 +########################################
 +
 +# Name des Containers
 +CONTAINER_NAME="tvheadend2"
 +
 +# Docker-Image
 +IMAGE_NAME="lscr.io/linuxserver/tvheadend:latest"
 +
 +# Standard-Ports (Host:Container)
 +HTTP_PORT="9981"
 +HTSP_PORT="9982"
 +
 +# Mögliche Basisverzeichnisse (Host)
 +BASE_DIR_CANDIDATES=(
 +  "/yacht/AppData/tvheadend2"
 +  "/srv/docker/tvheadend2"
 +)
 +
 +# Effektives Basisverzeichnis bestimmen
 +BASE_DIR=""
 +for c in "${BASE_DIR_CANDIDATES[@]}"; do
 +    if [ -d "$c" ]; then
 +        BASE_DIR="$c"
 +        break
 +    fi
 +done
 +
 +# Falls noch keins existiert: erstes als Default nehmen und anlegen
 +if [ -z "$BASE_DIR" ]; then
 +    BASE_DIR="${BASE_DIR_CANDIDATES[0]}"
 +    mkdir -p "$BASE_DIR"
 +fi
 +
 +CONFIG_DIR="$BASE_DIR/data"
 +RECORDINGS_DIR="$BASE_DIR/recordings"
 +
 +# Default-UID/GID (bei Bedarf anpassen)
 +PUID="${PUID:-1000}"
 +PGID="${PGID:-1000}"
 +
 +########################################
 +# Hilfsfunktionen
 +########################################
 +
 +log() {
 +    echo "[tvh2-manage] $*"
 +}
 +
 +ensure_dirs() {
 +    log "Erzeuge Verzeichnisse (falls nicht vorhanden):"
 +    log "  CONFIG_DIR    = $CONFIG_DIR"
 +    log "  RECORDINGS_DIR= $RECORDINGS_DIR"
 +
 +    mkdir -p "$CONFIG_DIR" "$RECORDINGS_DIR"
 +
 +    # Rechte setzen (damit der Container schreiben kann)
 +    log "Setze Eigentümer auf PUID=$PUID, PGID=$PGID"
 +    chown -R "$PUID:$PGID" "$BASE_DIR"
 +}
 +
 +container_exists() {
 +    docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"
 +}
 +
 +container_running() {
 +    docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"
 +}
 +
 +########################################
 +# Aktionen
 +########################################
 +
 +do_install() {
 +    log "Starte INSTALL für $CONTAINER_NAME mit Image $IMAGE_NAME"
 +    ensure_dirs()
 +
 +    if container_exists; then
 +        log "Container $CONTAINER_NAME existiert bereits – entferne alte Instanz..."
 +        docker stop "$CONTAINER_NAME" >/dev/null 2>&1 || true
 +        docker rm "$CONTAINER_NAME" >/dev/null 2>&1 || true
 +    fi
 +
 +    log "Pull neues Image..."
 +    docker pull "$IMAGE_NAME"
 +
 +    log "Starte neuen Container mit --restart unless-stopped"
 +    docker run -d \
 +        --name "$CONTAINER_NAME" \
 +        --restart unless-stopped \
 +        -e PUID="$PUID" \
 +        -e PGID="$PGID" \
 +        -e TZ="Europe/Berlin" \
 +        -e RUN_OPTS="" \
 +        -p "${HTTP_PORT}:9981" \
 +        -p "${HTSP_PORT}:9982" \
 +        -v "${CONFIG_DIR}:/config" \
 +        -v "${RECORDINGS_DIR}:/recordings" \
 +        --device /dev/dri:/dev/dri \
 +        --device /dev/dvb:/dev/dvb \
 +        "$IMAGE_NAME"
 +
 +    log "Install/Neu-Deploy abgeschlossen. Web-GUI sollte unter http://<host>:${HTTP_PORT}/ erreichbar sein."
 +}
 +
 +do_update() {
 +    log "Starte UPDATE für $CONTAINER_NAME"
 +
 +    ensure_dirs
 +
 +    if ! container_exists; then
 +        log "Container existiert nicht. Führe stattdessen INSTALL aus."
 +        do_install
 +        return
 +    fi
 +
 +    log "Pull neues Image..."
 +    docker pull "$IMAGE_NAME"
 +
 +    log "Stoppe alten Container..."
 +    docker stop "$CONTAINER_NAME" || true
 +
 +    log "Entferne alten Container..."
 +    docker rm "$CONTAINER_NAME" || true
 +
 +    log "Starte Container mit neuem Image..."
 +    docker run -d \
 +        --name "$CONTAINER_NAME" \
 +        --restart unless-stopped \
 +        -e PUID="$PUID" \
 +        -e PGID="$PGID" \
 +        -e TZ="Europe/Berlin" \
 +        -e RUN_OPTS="" \
 +        -p "${HTTP_PORT}:9981" \
 +        -p "${HTSP_PORT}:9982" \
 +        -v "${CONFIG_DIR}:/config" \
 +        -v "${RECORDINGS_DIR}:/recordings" \
 +        --device /dev/dri:/dev/dri \
 +        --device /dev/dvb:/dev/dvb \
 +        "$IMAGE_NAME"
 +
 +    log "Update abgeschlossen."
 +}
 +
 +do_clean() {
 +    log "CLEAN: Container stoppen und löschen (Daten bleiben erhalten)."
 +
 +    if container_running; then
 +        log "Stoppe laufenden Container..."
 +        docker stop "$CONTAINER_NAME" || true
 +    fi
 +
 +    if container_exists; then
 +        log "Entferne Container..."
 +        docker rm "$CONTAINER_NAME" || true
 +    else
 +        log "Container existiert nicht – nichts zu tun."
 +    fi
 +}
 +
 +do_purge() {
 +    log "PURGE: Container, Image und optional Daten löschen."
 +
 +    # 1) Container stoppen/entfernen
 +    do_clean
 +
 +    # 2) Image löschen
 +    if docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "^${IMAGE_NAME}$"; then
 +        log "Entferne Image $IMAGE_NAME..."
 +        docker rmi "$IMAGE_NAME" || true
 +    else
 +        log "Image $IMAGE_NAME nicht gefunden – überspringe."
 +    fi
 +
 +    # 3) Daten löschen (nur nach expliziter Bestätigung)
 +    echo
 +    echo "WARNUNG: Sollen auch die Datenverzeichnisse gelöscht werden?"
 +    echo "  CONFIG_DIR    = $CONFIG_DIR"
 +    echo "  RECORDINGS_DIR= $RECORDINGS_DIR"
 +    read -r -p "WIRKLICH ALLES LÖSCHEN? (yes/NO): " ans
 +
 +    if [ "$ans" = "yes" ]; then
 +        log "Lösche Datenverzeichnisse..."
 +        rm -rf "$CONFIG_DIR" "$RECORDINGS_DIR"
 +        log "Daten entfernt."
 +    else
 +        log "Daten bleiben erhalten."
 +    fi
 +}
 +
 +do_logs() {
 +    log "Zeige Logs von $CONTAINER_NAME (Ctrl+C zum Beenden)..."
 +    docker logs -f "$CONTAINER_NAME"
 +}
 +
 +do_status() {
 +    log "Status von $CONTAINER_NAME:"
 +
 +    if container_running; then
 +        echo "  - Container läuft."
 +    elif container_exists; then
 +        echo "  - Container existiert, läuft aber nicht."
 +        echo "  - Letzter Exit-Code siehe: docker inspect $CONTAINER_NAME"
 +    else
 +        echo "  - Container existiert nicht."
 +    fi
 +
 +    echo
 +    echo "Gemappte Verzeichnisse:"
 +    echo "  BASE_DIR      = $BASE_DIR"
 +    echo "  CONFIG_DIR    = $CONFIG_DIR (-> /config)"
 +    echo "  RECORDINGS_DIR= $RECORDINGS_DIR (-> /recordings)"
 +
 +    echo
 +    echo "Image:"
 +    docker images | grep -E 'REPOSITORY|tvheadend|linuxserver/tvheadend|lscr.io/linuxserver/tvheadend' || true
 +
 +    echo
 +    echo "Container:"
 +    docker ps -a | grep -E 'CONTAINER ID|tvheadend2' || true
 +}
 +
 +do_shell() {
 +    if ! container_running; then
 +        log "Container läuft nicht – starte ihn kurz an..."
 +        docker start "$CONTAINER_NAME" >/dev/null 2>&1 || true
 +    fi
 +
 +    log "Öffne Shell im Container..."
 +    docker exec -it "$CONTAINER_NAME" bash 2>/dev/null || docker exec -it "$CONTAINER_NAME" sh
 +}
 +
 +########################################
 +# Main
 +########################################
 +
 +ACTION="${1:-}"
 +
 +case "$ACTION" in
 +    install)
 +        do_install
 +        ;;
 +    update)
 +        do_update
 +        ;;
 +    clean|remove)
 +        do_clean
 +        ;;
 +    purge)
 +        do_purge
 +        ;;
 +    logs)
 +        do_logs
 +        ;;
 +    status)
 +        do_status
 +        ;;
 +    shell)
 +        do_shell
 +        ;;
 +    *)
 +        echo "Usage: $0 {install|update|clean|remove|purge|logs|status|shell}"
 +        echo
 +        echo "  install : Container (neu) erstellen mit restart=unless-stopped"
 +        echo "  update  : Image pullen + Container neu erstellen"
 +        echo "  clean   : Container stoppen + löschen (Daten bleiben)"
 +        echo "  remove  : Alias für clean"
 +        echo "  purge   : Container+Image und optional Daten löschen"
 +        echo "  logs    : docker logs -f"
 +        echo "  status  : Übersicht über Container/Image/Verzeichnisse"
 +        echo "  shell   : Shell in laufendem Container öffnen"
 +        exit 1
 +        ;;
 +esac
 +
 +</code>
 +
 +
  
/app/www/public/data/attic/hackspace/ausstattung/tv/tvheadend/tvheadend.1764020760.txt.gz · Zuletzt geändert: von spock0010