installer: remove cell identity prompts — wizard handles all config
Unit Tests / test (push) Successful in 15m44s

The /setup wizard now collects cell name, domain mode, credentials,
password, services, and timezone.  The bash installer's job is just
infrastructure: packages, user, repo clone, make install, start.

Removes: prompt/prompt_secret helpers, verify_cf_token, verify_duckdns,
check_pic_ngo_available, and the entire Step 5 identity block.
TOTAL_STEPS 8 → 7.  Step numbers renumbered accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 14:41:46 -04:00
parent 9566f7dd1b
commit 8d1ef39ca5
+9 -234
View File
@@ -79,56 +79,7 @@ log_error() { printf "\n${RED}${BOLD}ERROR:${RESET}${RED} %s${RESET}\n" "$1" >
die() { log_error "$1"; exit 1; }
# ---------------------------------------------------------------------------
# Interactive prompt helpers (use /dev/tty so they work even with piped stdin)
# ---------------------------------------------------------------------------
prompt() {
# prompt <label> <default> <var>
local _label="$1" _default="$2" _var="$3" _inp=''
if [ -n "$_default" ]; then
printf " %s [%s]: " "$_label" "$_default" >/dev/tty
else
printf " %s: " "$_label" >/dev/tty
fi
read -r _inp </dev/tty || true
[ -z "$_inp" ] && _inp="$_default"
eval "${_var}=\${_inp}"
}
prompt_secret() {
# prompt_secret <label> <var>
local _label="$1" _var="$2" _inp=''
printf " %s: " "$_label" >/dev/tty
stty -echo </dev/tty 2>/dev/null || true
read -r _inp </dev/tty || true
stty echo </dev/tty 2>/dev/null || true
printf "\n" >/dev/tty
eval "${_var}=\${_inp}"
}
verify_cf_token() {
local _token="$1" _result=''
_result=$(curl -fsSm 10 \
-H "Authorization: Bearer ${_token}" \
"https://api.cloudflare.com/client/v4/user/tokens/verify" 2>/dev/null) || true
echo "$_result" | grep -q '"success":true'
}
verify_duckdns() {
local _sub="$1" _token="$2" _result=''
_result=$(curl -fsSm 10 \
"https://www.duckdns.org/update?domains=${_sub}&token=${_token}&ip=" 2>/dev/null) || true
[ "$_result" = "OK" ]
}
check_pic_ngo_available() {
local _name="$1" _result=''
_result=$(curl -fsSm 10 \
"https://ddns.pic.ngo/api/v1/check/${_name}" 2>/dev/null) || true
echo "$_result" | grep -q '"available":true'
}
TOTAL_STEPS=8
TOTAL_STEPS=7
# ---------------------------------------------------------------------------
# Must run as root
@@ -302,182 +253,13 @@ chown -R "${REPO_OWNER}:${REPO_OWNER}" "$PIC_DIR"
git config --system --add safe.directory "$PIC_DIR" 2>/dev/null || true
# ---------------------------------------------------------------------------
# Step 5 — Configure cell identity
# Step 5 — Run make install
# ---------------------------------------------------------------------------
log_step 5 "Configuring cell identity..."
if [ ! -c /dev/tty ]; then
die "No interactive terminal available. Re-run with a real terminal (not piped)."
fi
printf "\n" >/dev/tty
# ── Cell name ──────────────────────────────────────────────────────────────
PIC_CELL_NAME=''
while true; do
prompt "Cell name (e.g. myhome, alice, lab)" "" PIC_CELL_NAME
if echo "$PIC_CELL_NAME" | grep -qE '^[a-z][a-z0-9-]{1,30}$'; then
break
fi
log_warn "Must start with a letter, use only lowercase letters/digits/hyphens, 231 chars."
done
# ── Domain / DDNS choice ───────────────────────────────────────────────────
printf "\n" >/dev/tty
printf " How will your cell be publicly reachable?\n" >/dev/tty
printf " 1) pic.ngo subdomain — free, %s.pic.ngo, fully automatic HTTPS\n" "$PIC_CELL_NAME" >/dev/tty
printf " 2) Cloudflare DNS-01 — your own domain (must use Cloudflare nameservers)\n" >/dev/tty
printf " 3) DuckDNS — free *.duckdns.org subdomain\n" >/dev/tty
printf " 4) HTTP-01 (any) — any domain, port 80 must be publicly reachable\n" >/dev/tty
printf " 5) Local only — no public domain, LAN/VPN access only\n" >/dev/tty
printf "\n" >/dev/tty
PIC_DOMAIN_MODE=''
_choice=''
while true; do
prompt "Choice" "1" _choice
case "$_choice" in
1) PIC_DOMAIN_MODE="pic_ngo"; break ;;
2) PIC_DOMAIN_MODE="cloudflare"; break ;;
3) PIC_DOMAIN_MODE="duckdns"; break ;;
4) PIC_DOMAIN_MODE="http01"; break ;;
5) PIC_DOMAIN_MODE="lan"; break ;;
*) log_warn "Enter a number from 1 to 5." ;;
esac
done
PIC_DOMAIN_NAME=''
PIC_CF_TOKEN=''
PIC_DDK_TOKEN=''
PIC_DDK_SUB=''
# ── pic.ngo ────────────────────────────────────────────────────────────────
if [ "$PIC_DOMAIN_MODE" = "pic_ngo" ]; then
PIC_DOMAIN_NAME="${PIC_CELL_NAME}.pic.ngo"
printf " Checking name availability at pic.ngo..." >/dev/tty
if check_pic_ngo_available "$PIC_CELL_NAME"; then
printf " available\n" >/dev/tty
log_ok "Will register: ${PIC_DOMAIN_NAME}"
else
printf "\n" >/dev/tty
log_warn "${PIC_DOMAIN_NAME} may already be taken or the server is unreachable."
log_warn "Registration will be retried at first boot."
fi
fi
# ── Cloudflare ─────────────────────────────────────────────────────────────
if [ "$PIC_DOMAIN_MODE" = "cloudflare" ]; then
printf "\n" >/dev/tty
while true; do
prompt "Your domain name (e.g. home.example.com)" "" PIC_DOMAIN_NAME
if echo "$PIC_DOMAIN_NAME" | grep -qiE '^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z]{2,})+$'; then
break
fi
log_warn "Enter a valid fully-qualified domain name (e.g. home.example.com)."
done
printf "\n" >/dev/tty
printf " Create an API token at: Cloudflare Dashboard → My Profile → API Tokens\n" >/dev/tty
printf " Required permission: Zone / DNS / Edit (set to all zones or your specific zone)\n" >/dev/tty
printf "\n" >/dev/tty
_attempts=0
while true; do
prompt_secret "Cloudflare API token" PIC_CF_TOKEN
if [ -z "$PIC_CF_TOKEN" ]; then
log_warn "Token cannot be empty."
continue
fi
printf " Verifying token with Cloudflare..." >/dev/tty
if verify_cf_token "$PIC_CF_TOKEN"; then
printf " valid\n" >/dev/tty
log_ok "Cloudflare token verified"
break
fi
printf " invalid\n" >/dev/tty
_attempts=$((_attempts + 1))
log_warn "Verification failed — check the token has Zone / DNS / Edit permission."
if [ "$_attempts" -ge 2 ]; then
log_warn "Token failed twice. You can still continue — it will be tested again at first boot."
prompt "Press Enter to continue with this token, or Ctrl-C to abort and re-run" "" _dummy
break
fi
done
fi
# ── DuckDNS ────────────────────────────────────────────────────────────────
if [ "$PIC_DOMAIN_MODE" = "duckdns" ]; then
printf "\n" >/dev/tty
printf " First create a subdomain at duckdns.org, then enter the details below.\n" >/dev/tty
printf "\n" >/dev/tty
while true; do
prompt "DuckDNS subdomain (e.g. myhome → myhome.duckdns.org)" "" PIC_DDK_SUB
if echo "$PIC_DDK_SUB" | grep -qE '^[a-z0-9][a-z0-9-]*$'; then
break
fi
log_warn "Subdomain must be lowercase letters, digits, and hyphens only."
done
PIC_DOMAIN_NAME="${PIC_DDK_SUB}.duckdns.org"
printf "\n" >/dev/tty
_attempts=0
while true; do
prompt_secret "DuckDNS token (from duckdns.org account page)" PIC_DDK_TOKEN
if [ -z "$PIC_DDK_TOKEN" ]; then
log_warn "Token cannot be empty."
continue
fi
printf " Verifying token with DuckDNS..." >/dev/tty
if verify_duckdns "$PIC_DDK_SUB" "$PIC_DDK_TOKEN"; then
printf " valid\n" >/dev/tty
log_ok "DuckDNS token verified (${PIC_DOMAIN_NAME})"
break
fi
printf " invalid\n" >/dev/tty
_attempts=$((_attempts + 1))
log_warn "Verification failed — make sure the subdomain exists at duckdns.org and the token is correct."
if [ "$_attempts" -ge 2 ]; then
log_warn "Token failed twice. You can still continue — it will be tested again at first boot."
prompt "Press Enter to continue with this token, or Ctrl-C to abort and re-run" "" _dummy
break
fi
done
fi
# ── HTTP-01 ────────────────────────────────────────────────────────────────
if [ "$PIC_DOMAIN_MODE" = "http01" ]; then
printf "\n" >/dev/tty
while true; do
prompt "Your domain name (e.g. home.example.com)" "" PIC_DOMAIN_NAME
if echo "$PIC_DOMAIN_NAME" | grep -qiE '^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z]{2,})+$'; then
break
fi
log_warn "Enter a valid fully-qualified domain name."
done
printf "\n" >/dev/tty
log_warn "HTTP-01 requires port 80 to be publicly reachable from the internet."
log_warn "Make sure your router forwards port 80 to this machine before completing setup."
fi
# ── Local only ─────────────────────────────────────────────────────────────
if [ "$PIC_DOMAIN_MODE" = "lan" ]; then
log_ok "Local-only mode — no public domain or DDNS will be configured."
fi
printf "\n" >/dev/tty
log_ok "Identity configured: cell=${PIC_CELL_NAME} mode=${PIC_DOMAIN_MODE}${PIC_DOMAIN_NAME:+ domain=${PIC_DOMAIN_NAME}}"
# ---------------------------------------------------------------------------
# Step 6 — Run make install
# ---------------------------------------------------------------------------
log_step 6 "Running 'make install'..."
log_step 5 "Running 'make install'..."
cd "$PIC_DIR"
if ! CELL_NAME="$PIC_CELL_NAME" \
DOMAIN_MODE="$PIC_DOMAIN_MODE" \
CELL_DOMAIN_NAME="${PIC_DOMAIN_NAME:-}" \
CLOUDFLARE_API_TOKEN="${PIC_CF_TOKEN:-}" \
DUCKDNS_TOKEN="${PIC_DDK_TOKEN:-}" \
DUCKDNS_SUBDOMAIN="${PIC_DDK_SUB:-}" \
make install 2>&1 | sed 's/^/ /'; then
if ! make install 2>&1 | sed 's/^/ /'; then
die "'make install' failed. Check the output above."
fi
@@ -488,9 +270,9 @@ chown -R "${REPO_OWNER}:${REPO_OWNER}" "$PIC_DIR"
log_ok "'make install' complete"
# ---------------------------------------------------------------------------
# Step 7 — Start core services
# Step 6 — Start core services
# ---------------------------------------------------------------------------
log_step 7 "Starting core services..."
log_step 6 "Starting core services..."
cd "$PIC_DIR"
@@ -501,9 +283,9 @@ fi
log_ok "Core services started"
# ---------------------------------------------------------------------------
# Step 8 — Health check + print wizard URL
# Step 7 — Health check + print wizard URL
# ---------------------------------------------------------------------------
log_step 8 "Waiting for API health check (up to ${API_HEALTH_TIMEOUT}s)..."
log_step 7 "Waiting for API health check (up to ${API_HEALTH_TIMEOUT}s)..."
ELAPSED=0
HEALTHY=0
@@ -541,14 +323,7 @@ printf "\n${GREEN}${BOLD}=======================================================
printf "${GREEN}${BOLD} PIC installed successfully!${RESET}\n"
printf "${GREEN}${BOLD}============================================================${RESET}\n"
printf "\n"
printf " Cell: ${BOLD}%s${RESET}\n" "$PIC_CELL_NAME"
if [ -n "$PIC_DOMAIN_NAME" ]; then
printf " Domain: ${BOLD}%s${RESET} (%s)\n" "$PIC_DOMAIN_NAME" "$PIC_DOMAIN_MODE"
else
printf " Domain: %s\n" "local only (LAN/VPN)"
fi
printf "\n"
printf " Open the setup wizard to set your admin password and choose services:\n"
printf " Open the setup wizard to configure your cell:\n"
printf "\n"
printf " ${BOLD}http://${HOST_IP}:${WEBUI_PORT}/setup${RESET}\n"
printf "\n"