fix(bootstrap): install only the full control plane under felis setup

prompt_install_mode also runs inside felis setup. Setup then goes on
to the Owner and edge setup, which need the control plane, so choosing
nano there always ended in a setup error.

Under felis setup the mode is now full before any prompt or default is
considered, and an explicit FELIS_INSTALL_MODE=nano stops with a
message pointing at deploy/bootstrap.sh. That leaves the felis setup
branch of acquire_nano_binary unreachable, so it goes.
install_embedded_binary stays, since the full install still uses it.
This commit is contained in:
flyemoji committed 2026-09-22 13:52:00 +09:00
1 parent 515c4a6496
commit 3918a4b11a
2 files changed
+22 -6

No files matched your search

+8 -4
View File
@@ -2194,6 +2194,14 @@ summary() {
# prompt (or FELIS_INSTALL_MODE=nano).
# ---------------------------------------------------------------------------
prompt_install_mode() {
# felis setup carries on to the Owner and edge setup, which needs the control plane, so
# a nano install under it could only end in a setup error.
if bootstrap_from_tui; then
[ "$INSTALL_MODE" != nano ] || die "felis setup installs the full control plane; for Felis-nano run deploy/bootstrap.sh with FELIS_INSTALL_MODE=nano"
INSTALL_MODE="full"
log "install mode: full (felis setup)"
return 0
fi
case "$INSTALL_MODE" in
full|nano) log "install mode: ${INSTALL_MODE} (from FELIS_INSTALL_MODE)"; return 0 ;;
"") ;;
@@ -2285,10 +2293,6 @@ build_nano_binary() {
}
acquire_nano_binary() {
if bootstrap_from_tui; then
install_embedded_binary
return 0
fi
# The release channel takes the same prebuilt binary the control plane does. This is the
# biggest win on this path: a host that only wants the auth multiplexer stops needing a Go
# toolchain and a checkout at all.
+14 -2
View File
@@ -280,6 +280,10 @@ pblock="$(awk '/^prompt_install_mode\(\) \{/,/^}/' "$BS")"
[ -n "$pblock" ] || { echo "FAIL: no prompt_install_mode found in $BS"; exit 1; }
[ "$(printf '%s\n' "$pblock" | wc -l)" -lt 60 ] \
|| { echo "FAIL: the extracted block is not the function -- did its closing brace move?"; exit 1; }
tblock="$(awk '/^bootstrap_from_tui\(\) \{/,/^}/' "$BS")"
[ -n "$tblock" ] || { echo "FAIL: no bootstrap_from_tui found in $BS"; exit 1; }
[ "$(printf '%s\n' "$tblock" | wc -l)" -lt 5 ] \
|| { echo "FAIL: the extracted block is not the function -- did its closing brace move?"; exit 1; }
# Only the no-terminal path can run unattended, and with a terminal attached the prompt
# would sit waiting on it. setsid drops the controlling terminal, as cloud-init and CI have.
@@ -288,10 +292,12 @@ if (: </dev/tty) 2>/dev/null; then
if command -v setsid >/dev/null 2>&1; then notty=setsid; else notty=skip; fi
fi
run_mode() { # unit-path done-marker-path [FELIS_INSTALL_MODE]
INSTALL_MODE="${3:-}" NANO_SERVICE="$1" BOOTSTRAP_DONE="$2" $notty bash -c '
run_mode() { # unit-path done-marker-path [FELIS_INSTALL_MODE [FELIS_BOOTSTRAP_FROM_TUI]]
INSTALL_MODE="${3:-}" FELIS_BOOTSTRAP_FROM_TUI="${4:-}" NANO_SERVICE="$1" BOOTSTRAP_DONE="$2" \
$notty bash -c '
die() { printf "DIE: %s\n" "$*"; exit 1; }
log() { printf "LOG: %s\n" "$*"; }
'"$tblock"'
'"$pblock"'
prompt_install_mode </dev/null
printf "MODE: %s\n" "$INSTALL_MODE"' 2>&1
@@ -307,6 +313,12 @@ else
"$(run_mode "$sdir/felis-nano.service" "$sdir/bootstrap.done")"
expect "a fresh host defaults to full" "MODE: full" \
"$(run_mode "$sdir/absent.service" "$sdir/absent.done")"
# felis setup goes on to need the control plane, so under it nano is refused, and the
# nano-only default above must not apply either.
expect "felis setup refuses FELIS_INSTALL_MODE=nano" "DIE: felis setup installs the full control plane" \
"$(run_mode "$sdir/absent.service" "$sdir/absent.done" nano 1)"
expect "felis setup installs full on a nano-only host" "MODE: full" \
"$(run_mode "$sdir/felis-nano.service" "$sdir/absent.done" "" 1)"
fi
# ---------------------------------------------------------------------------------------