#!/usr/bin/env bash # # PDF OCR Hotfolder — Installer / Instanz-Manager für Debian 12/13 # # Basis-Installation erfolgt einmalig (Code, venv, systemd-Template-Unit). # Danach werden Hotfolder-Instanzen verwaltet: # - Beim Erstlauf: mindestens eine Instanz wird angelegt # - Beim Folgelauf: bestehende Instanzen werden erkannt; neue können ergänzt werden # # Unterstützt lokale System-User und AD-User mit lokaler UID (SSSD/Winbind). # set -euo pipefail RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $*"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } log_error() { echo -e "${RED}[ERROR]${NC} $*"; } log_step() { echo -e "\n${BLUE}==>${NC} $*"; } if [ "${EUID}" -ne 0 ]; then log_error "Bitte als root ausführen: sudo ./install.sh" exit 1 fi INSTALL_DIR="/opt/pdf-ocr-hotfolder" CONFIG_DIR="/etc/pdf-ocr-hotfolder" DATA_ROOT="/var/lib/pdf-ocr-hotfolder" LOG_DIR="/var/log/pdf-ocr-hotfolder" SERVICE_TEMPLATE="pdf-ocr-hotfolder@.service" DEFAULT_USER="pdfocr" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="$SCRIPT_DIR" if [ ! -f "$REPO_DIR/pdf_ocr_hotfolder/__init__.py" ]; then log_error "Repo-Layout nicht erkannt. install.sh aus dem Repo ausführen." exit 1 fi # ============================================================ # Basis-Installation (idempotent) # ============================================================ install_base() { log_step "System-Pakete installieren" apt-get update -qq apt-get install -y --no-install-recommends \ python3 python3-venv python3-pip \ tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng \ ghostscript qpdf unpaper pngquant \ icc-profiles-free ca-certificates curl log_info "System-Pakete ok ✓" # Ghostscript-Versions-Check (Issue #3) if command -v gs >/dev/null 2>&1; then GS_VER="$(gs --version 2>/dev/null || echo 0.0)" log_info "Ghostscript: $GS_VER" case "$GS_VER" in 10.0.0|10.00.0|10.01.*|10.02.0) echo log_warn "═══════════════════════════════════════════════════════════════" log_warn "Ghostscript $GS_VER ist vom PDF/A-Bug betroffen (10.0.0–10.02.0)." log_warn "Mit pdfa_level + skip_text=true kann ocrmypdf KEINE PDFs verarbeiten." log_warn "" log_warn "Workarounds:" log_warn " 1. ghostscript aus bookworm-backports installieren (>=10.02.1)" log_warn " 2. In der Config [ocr].pdfa_level = \"\" setzen (Default ab v0.2.2)" log_warn "═══════════════════════════════════════════════════════════════" echo ;; esac fi log_step "Default-User '$DEFAULT_USER' prüfen" if id "$DEFAULT_USER" &>/dev/null; then log_info "'$DEFAULT_USER' existiert bereits" else adduser --system --group --home "$DATA_ROOT" --shell /usr/sbin/nologin "$DEFAULT_USER" log_info "System-User '$DEFAULT_USER' angelegt ✓" fi log_step "Verzeichnisse anlegen" mkdir -p "$INSTALL_DIR" "$CONFIG_DIR" "$DATA_ROOT" "$LOG_DIR" chown root:"$DEFAULT_USER" "$CONFIG_DIR" chmod 750 "$CONFIG_DIR" log_step "Code kopieren" rm -rf "$INSTALL_DIR/pdf_ocr_hotfolder" cp -r "$REPO_DIR/pdf_ocr_hotfolder" "$INSTALL_DIR/" cp "$REPO_DIR/requirements.txt" "$INSTALL_DIR/" cp "$REPO_DIR/VERSION" "$INSTALL_DIR/" cp "$REPO_DIR/config.example.toml" "$INSTALL_DIR/" echo "$REPO_DIR" > "$INSTALL_DIR/.repo_path" log_step "Python venv" if [ ! -d "$INSTALL_DIR/venv" ]; then python3 -m venv "$INSTALL_DIR/venv" fi "$INSTALL_DIR/venv/bin/pip" install --upgrade pip -q "$INSTALL_DIR/venv/bin/pip" install -r "$INSTALL_DIR/requirements.txt" -q log_info "venv ok ✓" log_step "systemd Template-Unit installieren" cp "$REPO_DIR/systemd/$SERVICE_TEMPLATE" "/etc/systemd/system/$SERVICE_TEMPLATE" systemctl daemon-reload log_info "Template-Unit installiert ✓" chown -R "$DEFAULT_USER":"$DEFAULT_USER" "$INSTALL_DIR" "$LOG_DIR" } # ============================================================ # Instanz-Verwaltung # ============================================================ list_instances() { find "$CONFIG_DIR" -maxdepth 1 -name '*.toml' -type f 2>/dev/null \ | sed 's|.*/||; s|\.toml$||' \ | sort } show_existing_instances() { local instances mapfile -t instances < <(list_instances) if [ "${#instances[@]}" -eq 0 ]; then log_info "Keine bestehenden Instanzen gefunden." return fi echo log_info "Bestehende Instanzen:" for name in "${instances[@]}"; do local active active=$(systemctl is-active "pdf-ocr-hotfolder@${name}.service" 2>/dev/null || echo inactive) printf " • %-30s [%s]\n" "$name" "$active" done echo } create_instance() { echo read -r -p "Instanz-Name (nur a-z, 0-9, -): " INST if [[ ! "$INST" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then log_error "Ungültiger Name. Abbruch." return 1 fi if [ -f "$CONFIG_DIR/$INST.toml" ]; then log_error "Instanz '$INST' existiert bereits. Abbruch." return 1 fi local default_base="$DATA_ROOT/$INST" read -r -p "Basis-Pfad für Daten [$default_base]: " BASE BASE="${BASE:-$default_base}" read -r -p "Service-User [$DEFAULT_USER]: " SVC_USER SVC_USER="${SVC_USER:-$DEFAULT_USER}" local SVC_GROUP if id "$SVC_USER" &>/dev/null; then SVC_GROUP="$(id -gn "$SVC_USER")" log_info "User '$SVC_USER' existiert (Gruppe: $SVC_GROUP)" else log_warn "User '$SVC_USER' existiert nicht." read -r -p "Lokal als System-User anlegen? [J/n]: " CREATE_USER CREATE_USER="${CREATE_USER:-J}" if [[ "$CREATE_USER" =~ ^[JjYy]$ ]]; then adduser --system --group --home "$BASE" --shell /usr/sbin/nologin "$SVC_USER" SVC_GROUP="$SVC_USER" log_info "User '$SVC_USER' angelegt ✓" else log_error "User muss existieren (z.B. via AD/SSSD). Abbruch." return 1 fi fi log_info "Lege Datenverzeichnisse unter $BASE an..." mkdir -p "$BASE"/{incoming,outgoing,working,error} chown -R "$SVC_USER":"$SVC_GROUP" "$BASE" log_info "Erstelle Config $CONFIG_DIR/$INST.toml..." sed \ -e "s|/var/lib/pdf-ocr-hotfolder/incoming|$BASE/incoming|" \ -e "s|/var/lib/pdf-ocr-hotfolder/outgoing|$BASE/outgoing|" \ -e "s|/var/lib/pdf-ocr-hotfolder/working|$BASE/working|" \ -e "s|/var/lib/pdf-ocr-hotfolder/error|$BASE/error|" \ "$INSTALL_DIR/config.example.toml" > "$CONFIG_DIR/$INST.toml" chown root:"$SVC_GROUP" "$CONFIG_DIR/$INST.toml" chmod 640 "$CONFIG_DIR/$INST.toml" # Drop-in für abweichenden Service-User if [ "$SVC_USER" != "$DEFAULT_USER" ]; then local DROPIN_DIR="/etc/systemd/system/pdf-ocr-hotfolder@${INST}.service.d" mkdir -p "$DROPIN_DIR" cat > "$DROPIN_DIR/user.conf" < -f" echo " Neustart: systemctl restart pdf-ocr-hotfolder@" echo " Update: sudo ./update.sh" echo