Files
proxmox-scripts/install/devpi-install.sh
T

104 lines
3.8 KiB
Bash

#!/usr/bin/env bash
# devpi installer — runs inside the LXC, called by ct/devpi.sh
set -euo pipefail
APP="devpi"
LIB_URL="${LIB_URL:-https://gitea.luki-net.org/luki-net/proxmox-scripts/raw/branch/main/lib}"
source <(curl -fsSL "$LIB_URL/install.func")
DEVPI_USER="devpi"
DEVPI_HOME="/opt/devpi"
DEVPI_DATA="$DEVPI_HOME/data"
DEVPI_VENV="$DEVPI_HOME/venv"
DEVPI_HOST="0.0.0.0"
DEVPI_PORT="3141"
[[ "$EUID" -eq 0 ]] || { msg_err "Must run as root"; exit 1; }
# ── packages + user + dirs ───────────────────────────────────────────────────
setup_base_apt python3 python3-venv python3-pip
create_system_user "$DEVPI_USER" "$DEVPI_HOME"
mkdir -p "$DEVPI_DATA"
chown -R "$DEVPI_USER:$DEVPI_USER" "$DEVPI_HOME"
# ── venv + devpi ─────────────────────────────────────────────────────────────
if [[ ! -x "$DEVPI_VENV/bin/devpi-server" ]]; then
msg_info "Creating venv at $DEVPI_VENV"
runuser -u "$DEVPI_USER" -- python3 -m venv "$DEVPI_VENV"
runuser -u "$DEVPI_USER" -- "$DEVPI_VENV/bin/pip" install --upgrade pip wheel >/dev/null
msg_info "Installing devpi-server / devpi-web / devpi-client..."
runuser -u "$DEVPI_USER" -- "$DEVPI_VENV/bin/pip" install \
devpi-server devpi-web devpi-client >/dev/null
msg_ok "devpi installed"
else
msg_warn "venv already exists, skipping pip install"
fi
# ── init data dir ────────────────────────────────────────────────────────────
if [[ ! -f "$DEVPI_DATA/.serverversion" ]]; then
msg_info "Initializing devpi data directory"
runuser -u "$DEVPI_USER" -- "$DEVPI_VENV/bin/devpi-init" --serverdir "$DEVPI_DATA"
msg_ok "devpi initialized"
fi
# ── systemd ──────────────────────────────────────────────────────────────────
write_systemd_unit devpi "$(cat <<EOF
[Unit]
Description=devpi-server (private PyPI cache)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=$DEVPI_USER
Group=$DEVPI_USER
ExecStart=$DEVPI_VENV/bin/devpi-server \\
--host $DEVPI_HOST \\
--port $DEVPI_PORT \\
--serverdir $DEVPI_DATA \\
--request-timeout 60
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
)"
wait_for_http "http://127.0.0.1:$DEVPI_PORT/" 30
# ── set root password (only on fresh install) ────────────────────────────────
CRED_FILE="/root/devpi.credentials"
if [[ ! -f "$CRED_FILE" ]]; then
DEVPI_ROOT_PW=$(openssl rand -base64 18)
msg_info "Setting devpi root password"
CLIENT_DIR=$(mktemp -d)
chown "$DEVPI_USER:$DEVPI_USER" "$CLIENT_DIR"
runuser -u "$DEVPI_USER" -- "$DEVPI_VENV/bin/devpi" --clientdir "$CLIENT_DIR" use "http://127.0.0.1:$DEVPI_PORT" >/dev/null
runuser -u "$DEVPI_USER" -- "$DEVPI_VENV/bin/devpi" --clientdir "$CLIENT_DIR" login root --password='' >/dev/null
runuser -u "$DEVPI_USER" -- "$DEVPI_VENV/bin/devpi" --clientdir "$CLIENT_DIR" user -m root "password=$DEVPI_ROOT_PW" >/dev/null
rm -rf "$CLIENT_DIR"
cat >"$CRED_FILE" <<EOF
devpi root password: $DEVPI_ROOT_PW
URL: http://<container-ip>:$DEVPI_PORT
Mirror index: http://<container-ip>:$DEVPI_PORT/root/pypi/+simple/
Web UI: http://<container-ip>:$DEVPI_PORT
EOF
chmod 600 "$CRED_FILE"
msg_ok "Credentials written to $CRED_FILE"
else
msg_warn "$CRED_FILE already exists, leaving devpi root password unchanged"
fi
apt_cleanup
msg_ok "$APP installation finished"