- new install/nexus-runtime.sh (idempotent, re-runnable on an existing LXC): uv for the nexus user (manages Python 3.12), tesseract deu+eng, nexus-worker.service unit (ConditionPathExists guards the skeleton phase), sudoers extended to cover the worker service - nexus-install.sh: RUNTIME section now invokes nexus-runtime.sh at the end of the install (after base sudoers/units, which it extends)
88 lines
4.0 KiB
Bash
Executable File
88 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# nexus runtime provisioning — idempotent, runs inside the nexus LXC as root.
|
|
#
|
|
# Added by nexus-hub card K-101 (stack scaffold). Installs everything the
|
|
# decided stack (nexus-hub ADR-0002) needs at runtime ON TOP of the base
|
|
# nexus-install.sh provisioning:
|
|
# - uv for the `nexus` user (manages Python 3.12 per pyproject.toml)
|
|
# - tesseract OCR with deu+eng language packs (ingest cards K-107+)
|
|
# - nexus-worker.service systemd unit (analysis worker, queue with K-105)
|
|
# - sudoers extension so the Actions runner may also restart the worker
|
|
#
|
|
# Called by install/nexus-install.sh (RUNTIME section) during fresh installs.
|
|
# To retrofit an EXISTING LXC (documented K-101 follow-up step), run inside it:
|
|
#
|
|
# curl -fsSL https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/install/nexus-runtime.sh | bash
|
|
#
|
|
# Safe to re-run at any time.
|
|
|
|
set -euo pipefail
|
|
|
|
LIB_URL="${LIB_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/lib}"
|
|
source <(curl -fsSL "$LIB_URL/install.func")
|
|
|
|
[[ "$EUID" -eq 0 ]] || { msg_err "Must run as root"; exit 1; }
|
|
|
|
APP_USER="nexus"
|
|
APP_HOME="/opt/nexus"
|
|
CURRENT_DIR="$APP_HOME/current"
|
|
|
|
run_user() { runuser -u "$APP_USER" -- env HOME="$APP_HOME" PATH="$APP_HOME/.local/bin:/usr/local/bin:/usr/bin:/bin" "$@"; }
|
|
|
|
id "$APP_USER" >/dev/null 2>&1 || { msg_err "user $APP_USER missing — run nexus-install.sh first"; exit 1; }
|
|
|
|
# ── OCR stack (ING-3: tesseract deu+eng) ──────────────────────────────────────
|
|
msg_info "Installing tesseract (deu+eng)..."
|
|
apt-get install -y -qq tesseract-ocr tesseract-ocr-deu tesseract-ocr-eng >/dev/null
|
|
msg_ok "tesseract $(tesseract --version 2>/dev/null | head -n1 | awk '{print $2}')"
|
|
|
|
# ── uv for the nexus user (provides Python 3.12 via pyproject/uv.lock) ────────
|
|
if [[ ! -x "$APP_HOME/.local/bin/uv" ]]; then
|
|
msg_info "Installing uv for $APP_USER..."
|
|
run_user bash -c "curl -LsSf https://astral.sh/uv/install.sh | sh" >/dev/null
|
|
msg_ok "uv $(run_user "$APP_HOME/.local/bin/uv" --version | awk '{print $2}') installed"
|
|
else
|
|
msg_warn "uv already present ($(run_user "$APP_HOME/.local/bin/uv" --version | awk '{print $2}')), skipping"
|
|
fi
|
|
run_user "$APP_HOME/.local/bin/uv" python install 3.12 >/dev/null 2>&1 || true
|
|
msg_ok "Python 3.12 toolchain available via uv"
|
|
|
|
# ── nexus-worker.service ──────────────────────────────────────────────────────
|
|
cat >/etc/systemd/system/nexus-worker.service <<EOF
|
|
[Unit]
|
|
Description=nexus — analysis worker (job queue arrives with K-105)
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
# Skeleton-safe: only start once the deploy artifact provides the entrypoint.
|
|
ConditionPathExists=$CURRENT_DIR/start-worker.sh
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=$APP_USER
|
|
Group=$APP_USER
|
|
WorkingDirectory=$CURRENT_DIR
|
|
EnvironmentFile=/etc/nexus/env
|
|
ExecStart=$CURRENT_DIR/start-worker.sh
|
|
Restart=on-failure
|
|
RestartSec=5
|
|
NoNewPrivileges=true
|
|
ProtectSystem=full
|
|
PrivateTmp=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# ── sudoers: extend the narrow rule to cover the worker service ───────────────
|
|
cat >/etc/sudoers.d/nexus-deploy <<EOF
|
|
$APP_USER ALL=(root) NOPASSWD: /usr/bin/systemctl restart nexus.service, /usr/bin/systemctl start nexus.service, /usr/bin/systemctl stop nexus.service, /usr/bin/systemctl status nexus.service, /usr/bin/systemctl restart nexus-worker.service, /usr/bin/systemctl start nexus-worker.service, /usr/bin/systemctl stop nexus-worker.service, /usr/bin/systemctl status nexus-worker.service
|
|
EOF
|
|
chmod 440 /etc/sudoers.d/nexus-deploy
|
|
visudo -cf /etc/sudoers.d/nexus-deploy >/dev/null
|
|
|
|
systemctl daemon-reload
|
|
systemctl enable nexus-worker.service >/dev/null 2>&1
|
|
msg_ok "nexus-worker.service installed + enabled (starts once a deploy ships start-worker.sh)"
|
|
|
|
msg_ok "nexus runtime provisioning finished (idempotent — safe to re-run)"
|