prompt_lxc_config asks 'SSH-Root-Login erlauben? [Y/n]' (env-presettable via SSH_ROOT_LOGIN, validated, normalized to yes|no). The bootstrap passes the value into the container; configure_ssh_root_login writes /etc/ssh/sshd_config.d/zz-root-login.conf (yes -> PermitRootLogin yes, no -> prohibit-password) and reloads sshd.
105 lines
3.9 KiB
Bash
105 lines
3.9 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
|
|
configure_ssh_root_login
|
|
|
|
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"
|