feat: add interactive CLI setup wizard for server configuration and log file registration
This commit is contained in:
Executable
+223
@@ -0,0 +1,223 @@
|
||||
#!/bin/sh
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
# Nadir interactive setup — generates config.yaml
|
||||
#
|
||||
# Run this script on a fresh box after placing the nadir binary, before
|
||||
# `nadir install`. It asks about server settings, TLS mode, and log-file
|
||||
# tracking, then writes the configuration file and prints the next steps.
|
||||
#
|
||||
# Everything in here is a question with a default answer in brackets.
|
||||
# Press Enter to accept the default.
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
set -e
|
||||
|
||||
# ── helpers ──────────────────────────────────────────────────────────
|
||||
|
||||
prompt() {
|
||||
printf "%s [%s]: " "$1" "$2"
|
||||
read -r val
|
||||
echo "${val:-$2}"
|
||||
}
|
||||
|
||||
prompt_yn() {
|
||||
while :; do
|
||||
printf "%s (y/n) [%s]: " "$1" "$2"
|
||||
read -r val
|
||||
val=$(printf "%s" "${val:-$2}" | tr '[:upper:]' '[:lower:]')
|
||||
case "$val" in
|
||||
y|yes) return 0 ;;
|
||||
n|no) return 1 ;;
|
||||
*) printf " please answer y or n.\n" >&2 ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
prompt_multi() {
|
||||
desc="$1"
|
||||
label="$2"
|
||||
result=""
|
||||
printf "%s\n" "$desc"
|
||||
printf " Enter one %s at a time, then press Enter on an empty line when done.\n" "$label"
|
||||
while :; do
|
||||
printf " > "
|
||||
read -r val
|
||||
[ -z "$val" ] && break
|
||||
result="${result} - ${val}
|
||||
"
|
||||
done
|
||||
echo "$result"
|
||||
}
|
||||
|
||||
# ── preamble ─────────────────────────────────────────────────────────
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script should usually be run as root so the config file ends"
|
||||
echo "up owned by root (the server runs as root). Continue anyway? (y/n) [y]"
|
||||
if ! prompt_yn "Continue without root?" "y"; then
|
||||
echo "Aborted."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "╔══════════════════════════════════════════════════════════╗"
|
||||
echo "║ Nadir — interactive setup ║"
|
||||
echo "╚══════════════════════════════════════════════════════════╝"
|
||||
echo
|
||||
|
||||
# ── 1. admin username ───────────────────────────────────────────────
|
||||
|
||||
SUGGESTED_USER="${SUDO_USER:-$USER}"
|
||||
if [ -z "$SUGGESTED_USER" ] || [ "$SUGGESTED_USER" = "root" ]; then
|
||||
SUGGESTED_USER="admin"
|
||||
fi
|
||||
ADMIN_USER=$(prompt "Admin username (system user assigned the admin role)" "$SUGGESTED_USER")
|
||||
|
||||
# ── 2. config path ───────────────────────────────────────────────────
|
||||
|
||||
DEFAULT_CONFIG="${CONFIG_PATH:-$HOME/.config/nadir/config.yaml}"
|
||||
CONFIG_PATH=$(prompt "Config file path" "$DEFAULT_CONFIG")
|
||||
|
||||
# ── 3. hostname ──────────────────────────────────────────────────────
|
||||
|
||||
HOSTNAME=$(prompt "Bind address (use 127.0.0.1 for local-only, or a Tailscale/Netbird IP)" "127.0.0.1")
|
||||
|
||||
# ── 4. port ──────────────────────────────────────────────────────────
|
||||
|
||||
PORT=$(prompt "Port" "9999")
|
||||
|
||||
# ── 5. TLS mode ──────────────────────────────────────────────────────
|
||||
|
||||
echo
|
||||
echo "How should clients connect to nadir?"
|
||||
echo " 1) Plain HTTP (unsecure — local-only or dev)"
|
||||
echo " 2) HTTPS with a self-signed certificate (nadir generates cert + key)"
|
||||
echo " 3) Behind a TLS-terminating reverse proxy (trust_proxy mode)"
|
||||
printf "Choose [1-3] [1]: "
|
||||
read -r tls_mode
|
||||
tls_mode="${tls_mode:-1}"
|
||||
|
||||
SECURE_TLS="false"
|
||||
TRUST_PROXY_LINE="# trust_proxy: false"
|
||||
CERT_LINE="# tls_cert: /var/lib/nadir/tls/cert.pem"
|
||||
KEY_LINE="# tls_key: /var/lib/nadir/tls/key.pem"
|
||||
|
||||
case "$tls_mode" in
|
||||
2)
|
||||
echo " → HTTPS with self-signed certificate"
|
||||
SECURE_TLS="true"
|
||||
CERT_LINE="tls_cert: /var/lib/nadir/tls/cert.pem"
|
||||
KEY_LINE="tls_key: /var/lib/nadir/tls/key.pem"
|
||||
;;
|
||||
3)
|
||||
echo " → Behind reverse proxy (trust_proxy)"
|
||||
SECURE_TLS="true"
|
||||
TRUST_PROXY_LINE="trust_proxy: true"
|
||||
;;
|
||||
*)
|
||||
echo " → Plain HTTP"
|
||||
SECURE_TLS="false"
|
||||
;;
|
||||
esac
|
||||
|
||||
# ── 6. release repo ──────────────────────────────────────────────────
|
||||
|
||||
RELEASE_REPO=$(prompt "Gitea release repo (for auto-updates, or leave blank to disable)" "")
|
||||
|
||||
# ── 7. log files ─────────────────────────────────────────────────────
|
||||
|
||||
echo
|
||||
if prompt_yn "Track log files (add entries to log_files allowlist)?" "n"; then
|
||||
echo
|
||||
echo "For each service (e.g. nginx, ssh, auth), you'll list the paths"
|
||||
echo "nadir is allowed to serve. Add as many services as you like."
|
||||
echo
|
||||
LOG_FILES_SECTION="log_files:"
|
||||
LOG_FILES_BODY=""
|
||||
|
||||
while :; do
|
||||
service=$(prompt " Service name (e.g. nginx, sshd) — empty line to stop" "")
|
||||
[ -z "$service" ] && break
|
||||
paths=$(prompt_multi "" "log path for $service")
|
||||
LOG_FILES_BODY="${LOG_FILES_BODY}
|
||||
${service}:"
|
||||
# indentation inside prompt_multi already includes leading spaces
|
||||
IFS='
|
||||
'
|
||||
for line in $paths; do
|
||||
LOG_FILES_BODY="${LOG_FILES_BODY}
|
||||
${line}"
|
||||
done
|
||||
echo
|
||||
done
|
||||
|
||||
if [ -n "$LOG_FILES_BODY" ]; then
|
||||
LOG_FILES_SECTION="${LOG_FILES_SECTION}${LOG_FILES_BODY}"
|
||||
else
|
||||
LOG_FILES_SECTION="# log_files:"
|
||||
fi
|
||||
else
|
||||
LOG_FILES_SECTION="# log_files:"
|
||||
fi
|
||||
|
||||
# ── write config ─────────────────────────────────────────────────────
|
||||
|
||||
CONFIG_DIR=$(dirname "$CONFIG_PATH")
|
||||
mkdir -p "$CONFIG_DIR"
|
||||
|
||||
cat > "$CONFIG_PATH" <<CONFIGEOF
|
||||
# Nadir configuration - config.yaml
|
||||
# Generated by install.sh
|
||||
|
||||
server:
|
||||
secure_tls: ${SECURE_TLS}
|
||||
${TRUST_PROXY_LINE}
|
||||
${CERT_LINE}
|
||||
${KEY_LINE}
|
||||
hostname: ${HOSTNAME}
|
||||
port: ${PORT}
|
||||
release_repo: ${RELEASE_REPO}
|
||||
|
||||
roles:
|
||||
admin:
|
||||
"*": ["*"]
|
||||
auditor:
|
||||
"*": ["read"]
|
||||
|
||||
assignments:
|
||||
${ADMIN_USER}: [admin]
|
||||
dashboard: [auditor]
|
||||
|
||||
${LOG_FILES_SECTION}
|
||||
CONFIGEOF
|
||||
|
||||
chmod 600 "$CONFIG_PATH"
|
||||
echo
|
||||
echo "╔══════════════════════════════════════════════════════════╗"
|
||||
echo "║ Configuration written to: ║"
|
||||
echo "║ $CONFIG_PATH"
|
||||
echo "╚══════════════════════════════════════════════════════════╝"
|
||||
echo
|
||||
echo "Next steps:"
|
||||
echo
|
||||
echo " 1. Make sure the nadir binary is installed:"
|
||||
echo " sudo cp ./nadir /usr/local/bin/nadir"
|
||||
echo " sudo chmod +x /usr/local/bin/nadir"
|
||||
echo
|
||||
echo " 2. Run the service installer:"
|
||||
echo " sudo nadir install"
|
||||
echo
|
||||
echo " 3. If you chose TLS mode, nadir will generate a self-signed"
|
||||
echo " certificate automatically during install."
|
||||
echo
|
||||
echo " 4. Check status:"
|
||||
echo " nadir status"
|
||||
echo
|
||||
|
||||
# If a SUDO_USER exists, chown the config directory so the user can
|
||||
# read it without root.
|
||||
if [ -n "${SUDO_USER}" ] && [ "${SUDO_USER}" != "root" ]; then
|
||||
chown "${SUDO_USER}:${SUDO_USER}" "$CONFIG_DIR" 2>/dev/null || true
|
||||
chown "${SUDO_USER}:${SUDO_USER}" "$CONFIG_PATH" 2>/dev/null || true
|
||||
fi
|
||||
Reference in New Issue
Block a user