make the machine-role question require an answer
No default, and it is the only question in the script like that. A guessed default is right often enough to be trusted and wrong in exactly the case that costs the most — pinning a static IP on a rented box, or leaving the firewall open on one. Every branch downstream is about what this machine is exposed to, so it is worth one deliberate keystroke rather than an Enter. Empty and unrecognised answers re-ask rather than aborting; a failed read means EOF rather than a wrong answer, and fails with the environment variable named, because otherwise the loop spins forever the first time this runs unattended. Drops guess_machine_role, which existed only to supply that default. default_iface stays — the static IP section needs it when it is ported. MACHINE_ROLE in the environment still answers it ahead of time. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -230,43 +230,18 @@ default_iface() {
|
|||||||
ip route get 8.8.8.8 2>/dev/null | awk '{for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}'
|
ip route get 8.8.8.8 2>/dev/null | awk '{for (i = 1; i <= NF; i++) if ($i == "dev") {print $(i + 1); exit}}'
|
||||||
}
|
}
|
||||||
|
|
||||||
# A default for the question below — a suggestion the user confirms, never a
|
|
||||||
# decision taken on their behalf.
|
|
||||||
#
|
|
||||||
# The signal that separates homelab from vps is whether this machine's own
|
|
||||||
# address is in RFC1918 space. That is a better test than asking whether it is
|
|
||||||
# virtualised, because a homelab is very often a VM on Proxmox and would be
|
|
||||||
# misread as rented; and it is the same fact that decides most of what the role
|
|
||||||
# is consulted for — whether the address is yours to pin, and whether the box is
|
|
||||||
# exposed to the open internet.
|
|
||||||
guess_machine_role() {
|
|
||||||
# Nothing here is a server. It is the machine you are sitting at.
|
|
||||||
if [[ "$OS" == "macos" ]]; then
|
|
||||||
echo dev
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# A graphical session means someone sits at this one too.
|
|
||||||
if [[ -n "${DISPLAY:-}" ]] || systemctl list-unit-files 2>/dev/null | grep -qE '^(gdm3?|sddm|lightdm)\.service'; then
|
|
||||||
echo dev
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
local ip
|
|
||||||
ip="$(ip -4 addr show "$(default_iface)" 2>/dev/null | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -1)"
|
|
||||||
case "$ip" in
|
|
||||||
10.* | 192.168.* | 172.1[6-9].* | 172.2[0-9].* | 172.3[01].*) echo homelab ;;
|
|
||||||
"") echo homelab ;; # no address to judge by: assume the safer of the two
|
|
||||||
*) echo vps ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ask what this machine is, unless the environment already said.
|
# Ask what this machine is, unless the environment already said.
|
||||||
#
|
#
|
||||||
# Asked in pre-flight rather than at the point of use so that the run knows its
|
# Asked in pre-flight rather than at the point of use so that the run knows its
|
||||||
# own shape before it starts: the steps that care are spread from swap through to
|
# own shape before it starts: the steps that care are spread from swap through to
|
||||||
# the firewall, and being asked "is this a VPS?" for the fourth time halfway down
|
# the firewall, and being asked "is this a VPS?" for the fourth time halfway down
|
||||||
# a provisioning run is how people start answering without reading.
|
# a provisioning run is how people start answering without reading.
|
||||||
|
#
|
||||||
|
# NO DEFAULT, deliberately, and it is the only question in the script like that.
|
||||||
|
# A guessed default is right often enough to be trusted and wrong in exactly the
|
||||||
|
# case that costs the most: pinning a static IP on a rented box, or leaving the
|
||||||
|
# firewall open on one. Every branch downstream is about what this machine is
|
||||||
|
# exposed to, so it is worth one deliberate keystroke rather than an Enter.
|
||||||
ask_machine_role() {
|
ask_machine_role() {
|
||||||
if [[ -n "$MACHINE_ROLE" ]]; then
|
if [[ -n "$MACHINE_ROLE" ]]; then
|
||||||
case "$MACHINE_ROLE" in
|
case "$MACHINE_ROLE" in
|
||||||
@@ -275,30 +250,28 @@ ask_machine_role() {
|
|||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local guess choice
|
|
||||||
guess="$(guess_machine_role)"
|
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
info "What is this machine?"
|
info "What is this machine? Several later steps depend on the answer."
|
||||||
echo " [1] homelab — yours, on a network you control"
|
echo " [1] homelab — yours, on a network you control"
|
||||||
echo " [2] vps — rented, public IP, provider's DHCP and console"
|
echo " [2] vps — rented, public IP, provider's DHCP and console"
|
||||||
echo " [3] dev — a laptop or desktop you sit at"
|
echo " [3] dev — a laptop or desktop you sit at"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
case "$guess" in
|
local choice
|
||||||
homelab) choice=1 ;;
|
while [[ -z "$MACHINE_ROLE" ]]; do
|
||||||
vps) choice=2 ;;
|
# A failed read means EOF, not a wrong answer — without this the loop would
|
||||||
dev) choice=3 ;;
|
# spin forever when stdin is closed, which is how an unattended run hangs.
|
||||||
esac
|
if ! read -rp " Which one? (1/2/3): " choice; then
|
||||||
|
fail "No answer, and this question has no default. Set MACHINE_ROLE=homelab|vps|dev to answer it ahead of time."
|
||||||
prompt_value MACHINE_ROLE_CHOICE "Pick a number" "$choice"
|
fi
|
||||||
|
case "$choice" in
|
||||||
case "$MACHINE_ROLE_CHOICE" in
|
1 | homelab) MACHINE_ROLE=homelab ;;
|
||||||
1 | homelab) MACHINE_ROLE=homelab ;;
|
2 | vps) MACHINE_ROLE=vps ;;
|
||||||
2 | vps) MACHINE_ROLE=vps ;;
|
3 | dev) MACHINE_ROLE=dev ;;
|
||||||
3 | dev) MACHINE_ROLE=dev ;;
|
"") warn "There is no default here — pick 1, 2 or 3." ;;
|
||||||
*) fail "Not one of the options: '$MACHINE_ROLE_CHOICE'" ;;
|
*) warn "Not one of the options: '$choice'" ;;
|
||||||
esac
|
esac
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
# Convenience for the steps that branch on it.
|
# Convenience for the steps that branch on it.
|
||||||
|
|||||||
Reference in New Issue
Block a user