feat(installer): run as root with sudo where needed, systemd service user-aware
This commit is contained in:
parent
7cdff22565
commit
17170c762a
1 changed files with 38 additions and 23 deletions
61
install.sh
61
install.sh
|
|
@ -20,6 +20,18 @@ info() { echo -e "${BLUE}$1${NC}"; }
|
|||
warn() { echo -e "${YELLOW}$1${NC}"; }
|
||||
header() { echo -e "\n${BOLD}${CYAN}$1${NC}"; }
|
||||
|
||||
# ============================================================
|
||||
# USER & SUDO
|
||||
# ============================================================
|
||||
SYS_USER="${SUDO_USER:-$USER}"
|
||||
SYS_HOME=$(eval echo "~$SYS_USER")
|
||||
[ "$EUID" -eq 0 ] && SUDO="" || SUDO="sudo"
|
||||
|
||||
if [ -z "$SUDO" ] && [ "$EUID" -ne 0 ]; then
|
||||
error "This script needs root for /opt/ and systemd. Use: sudo bash install.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
# PATHS
|
||||
# ============================================================
|
||||
|
|
@ -29,7 +41,7 @@ BIN_DIR="${INSTALL_DIR}/bin"
|
|||
DATA_DIR="${INSTALL_DIR}/data"
|
||||
STATIC_DIR="${INSTALL_DIR}/static"
|
||||
CONFIG_FILE="${INSTALL_DIR}/config.yaml"
|
||||
ENV_FILE="${REPO_DIR}/.env"
|
||||
ENV_FILE="${SYS_HOME}/.nextwks-env"
|
||||
AUTHELIA_DIR="/opt/authelia"
|
||||
AUTHELIA_CONFIG="${AUTHELIA_DIR}/configuration.yml"
|
||||
SERVICE_FILE="/etc/systemd/system/nextwks.service"
|
||||
|
|
@ -69,9 +81,10 @@ if [ ! -f "$REPO_DIR/src/main.go" ]; then
|
|||
error "git is required. Install it first: apt install git"
|
||||
exit 1
|
||||
fi
|
||||
CLONE_DIR="/tmp/nextwks-install"
|
||||
CLONE_DIR="${SYS_HOME}/nextwks"
|
||||
rm -rf "$CLONE_DIR" 2>/dev/null
|
||||
git clone --depth 1 "$REPO_URL" "$CLONE_DIR"
|
||||
chown -R "$SYS_USER:$SYS_USER" "$CLONE_DIR" 2>/dev/null || true
|
||||
REPO_DIR="$CLONE_DIR"
|
||||
success "Cloned to $REPO_DIR"
|
||||
fi
|
||||
|
|
@ -98,11 +111,11 @@ done
|
|||
# ============================================================
|
||||
if [ "$MODE" = "uninstall" ]; then
|
||||
info "Uninstalling Next Workspace..."
|
||||
systemctl stop nextwks 2>/dev/null || true
|
||||
systemctl disable nextwks 2>/dev/null || true
|
||||
rm -f "$SERVICE_FILE"
|
||||
systemctl daemon-reload
|
||||
[ -d "$INSTALL_DIR" ] && { rm -rf "$INSTALL_DIR"; success "Removed $INSTALL_DIR"; }
|
||||
$SUDO systemctl stop nextwks 2>/dev/null || true
|
||||
$SUDO systemctl disable nextwks 2>/dev/null || true
|
||||
$SUDO rm -f "$SERVICE_FILE"
|
||||
$SUDO systemctl daemon-reload
|
||||
[ -d "$INSTALL_DIR" ] && { $SUDO rm -rf "$INSTALL_DIR"; success "Removed $INSTALL_DIR"; }
|
||||
success "Uninstall complete"
|
||||
exit 0
|
||||
fi
|
||||
|
|
@ -114,8 +127,8 @@ if [ "$MODE" = "status" ]; then
|
|||
echo ""; header "Next Workspace Status"
|
||||
[ -f "${BIN_DIR}/core" ] && success "✓ Binary: ${BIN_DIR}/core" || warn "✗ Binary: not found"
|
||||
[ -f "$CONFIG_FILE" ] && success "✓ Config: $CONFIG_FILE" || warn "✗ Config: not found"
|
||||
systemctl is-active --quiet nextwks 2>/dev/null && success "✓ Service: running" || info " Service: stopped"
|
||||
systemctl is-active --quiet authelia 2>/dev/null && success "✓ Authelia: running" || info " Authelia: stopped"
|
||||
$SUDO systemctl is-active --quiet nextwks 2>/dev/null && success "✓ Service: running" || info " Service: stopped"
|
||||
$SUDO systemctl is-active --quiet authelia 2>/dev/null && success "✓ Authelia: running" || info " Authelia: stopped"
|
||||
command -v curl &>/dev/null && [ "$(curl -s --max-time 2 http://localhost:8080/api/health 2>/dev/null)" = '{"status":"ok"}' ] && success "✓ API: OK" || info " API: not responding"
|
||||
echo ""; exit 0
|
||||
fi
|
||||
|
|
@ -241,9 +254,11 @@ success "Binary built: app/core (${VERSION})"
|
|||
# INSTALL
|
||||
# ============================================================
|
||||
header "── Installing ──"
|
||||
mkdir -p "$BIN_DIR" "$DATA_DIR" "$STATIC_DIR"
|
||||
cp "$REPO_DIR/app/core" "$BIN_DIR/core" && chmod 755 "$BIN_DIR/core"
|
||||
[ -d "$REPO_DIR/app/static" ] && cp -r "$REPO_DIR/app/static"/* "$STATIC_DIR/"
|
||||
$SUDO mkdir -p "$BIN_DIR" "$DATA_DIR" "$STATIC_DIR"
|
||||
$SUDO cp "$REPO_DIR/app/core" "$BIN_DIR/core"
|
||||
$SUDO chmod 755 "$BIN_DIR/core"
|
||||
$SUDO chown -R "$SYS_USER:$SYS_USER" "$DATA_DIR" 2>/dev/null || true
|
||||
[ -d "$REPO_DIR/app/static" ] && $SUDO cp -r "$REPO_DIR/app/static"/* "$STATIC_DIR/"
|
||||
success "Copied files to $INSTALL_DIR/"
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -253,7 +268,7 @@ header "── Configuration ──"
|
|||
ADMIN_TOKEN=$(openssl rand -hex 32 2>/dev/null || head -c32 /dev/urandom | xxd -p -c32)
|
||||
SESSION_KEY=$(openssl rand -hex 32 2>/dev/null || head -c32 /dev/urandom | xxd -p -c32)
|
||||
|
||||
cat > "$CONFIG_FILE" << CONFIGEOF
|
||||
$SUDO tee "$CONFIG_FILE" > /dev/null << CONFIGEOF
|
||||
# Next Workspace — $(date +%Y-%m-%d)
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
|
|
@ -283,14 +298,14 @@ session:
|
|||
secret: "${SESSION_KEY}"
|
||||
expiry_minutes: 60
|
||||
CONFIGEOF
|
||||
chmod 600 "$CONFIG_FILE"
|
||||
$SUDO chmod 600 "$CONFIG_FILE"
|
||||
success "Config: $CONFIG_FILE"
|
||||
|
||||
# ============================================================
|
||||
# SYSTEMD
|
||||
# ============================================================
|
||||
header "── Systemd ──"
|
||||
cat > "$SERVICE_FILE" << SERVICEEOF
|
||||
$SUDO tee "$SERVICE_FILE" > /dev/null << SERVICEEOF
|
||||
[Unit]
|
||||
Description=Next Workspace (NextWks) Core
|
||||
After=network.target authelia.service
|
||||
|
|
@ -298,7 +313,7 @@ Wants=authelia.service
|
|||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
User=${SYS_USER}
|
||||
WorkingDirectory=${INSTALL_DIR}
|
||||
ExecStart=${BIN_DIR}/core -config ${CONFIG_FILE}
|
||||
Restart=always
|
||||
|
|
@ -316,7 +331,7 @@ ReadOnlyPaths=${INSTALL_DIR}/config.yaml ${INSTALL_DIR}/static
|
|||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
SERVICEEOF
|
||||
systemctl daemon-reload
|
||||
$SUDO systemctl daemon-reload
|
||||
success "Service: $SERVICE_FILE"
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -337,7 +352,7 @@ if [ -f "${AUTHELIA_DIR}/authelia" ]; then
|
|||
# Hash current admin password (if users exist) or generate one
|
||||
ADMIN_HASH=$("${AUTHELIA_DIR}/authelia" crypto hash generate --password "$(openssl rand -base64 12)" 2>/dev/null | awk '{print $NF}' || echo "\$argon2id\$v=19\$m=65536,t=3,p=4\$placeholder\$placeholder")
|
||||
|
||||
cat > "$AUTHELIA_CONFIG" << AUTHEOF
|
||||
$SUDO tee "$AUTHELIA_CONFIG" > /dev/null << AUTHEOF
|
||||
theme: light
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
|
|
@ -405,7 +420,7 @@ $(echo "$OIDC_KEY" | sed 's/^/ /')
|
|||
pre_configured_consent_duration: "1 year"
|
||||
userinfo_signed_response_alg: "none"
|
||||
AUTHEOF
|
||||
chmod 600 "$AUTHELIA_CONFIG"
|
||||
$SUDO chmod 600 "$AUTHELIA_CONFIG"
|
||||
success "Authelia config written"
|
||||
|
||||
# Create initial users_database.yml (needed for Authelia to start)
|
||||
|
|
@ -422,11 +437,11 @@ users:
|
|||
email: "${ADMIN_EMAIL:-admin@local}"
|
||||
groups: [admins]
|
||||
USERSDB
|
||||
chmod 600 "${AUTHELIA_DIR}/users_database.yml"
|
||||
$SUDO chmod 600 "${AUTHELIA_DIR}/users_database.yml"
|
||||
success "Users database created"
|
||||
fi
|
||||
|
||||
systemctl restart authelia 2>/dev/null && info "Authelia restarted" || info "Authelia not running (will start later)"
|
||||
$SUDO systemctl restart authelia 2>/dev/null && info "Authelia restarted" || info "Authelia not running (will start later)"
|
||||
fi
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -477,8 +492,8 @@ info " Workspace: ${NEXTWKS_URL}"
|
|||
info " Auth: ${AUTH_URL}"
|
||||
info " Admin UI: ${NEXTWKS_URL}/admin"
|
||||
echo ""
|
||||
info " Start: systemctl enable --now nextwks"
|
||||
info " Logs: journalctl -u nextwks -f"
|
||||
info " Start: sudo systemctl enable --now nextwks"
|
||||
info " Logs: sudo journalctl -u nextwks -f"
|
||||
info " Status: ./install.sh --status"
|
||||
echo ""
|
||||
if [ -n "${ADMIN_PASS:-}" ]; then
|
||||
|
|
|
|||
Loading…
Reference in a new issue