restructure the Tailscale network choice, with offscale left to be written

Four options, in the order you gave:

  1  set up your own network        (offscale)
  2  use a network you already run  (headscale, offscale)
  3  the easy route                 (tailscale.com)
  ?  what are tailscale, headscale and offscale?

? prints the long answer and then shows the options again, rather than dropping
the reader back at a bare prompt having forgotten what they were choosing
between.

The explanation frames all three as one question — who keeps the list of your
machines and hands out the keys — and says plainly that the coordination server
never carries traffic, since that is the thing people assume it does. Tailscale
and headscale are written. OFFSCALE is a marked placeholder, and so is what
option 1 actually does; both are yours to fill in and the run says so rather than
pretending.

Option 3 is the plain flow: no --login-server at all, and the auth-key prompt
says what that means — leave it blank and Tailscale prints a link that either
creates the account or adds this machine to an existing one. Option 2 keeps the
"no suggested URL" rule, because a coordination server URL is somebody's private
infrastructure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-12 19:41:43 +00:00
co-authored by Claude Opus 5
parent 059f0f6df2
commit 6a29c39b74
2 changed files with 84 additions and 15 deletions
+45 -15
View File
@@ -441,38 +441,66 @@ if ! skip; then
SUMMARY+=("Tailscale: connected, unchanged ($(tailscale_ip))")
else
echo ""
info "Which control plane?"
echo " [1] Tailscale's own service (tailscale.com)"
echo " [2] a self-hosted headscale"
info "Which network should this machine join?"
echo ""
echo " [1] set up your own network (offscale)"
echo " [2] use a network you already run (headscale, offscale)"
echo " [3] the easy route (tailscale.com)"
echo " [?] what are tailscale, headscale and offscale?"
echo ""
TS_LOGIN_SERVER=""
TS_PLANE=""
while [[ -z "$TS_PLANE" ]]; do
if ! read -rp " Which one? (1/2) [1]: " TS_PLANE_CHOICE; then
if ! read -rp " Which one? (1/2/3/?): " TS_PLANE_CHOICE; then
echo ""
fail "No answer."
fi
case "${TS_PLANE_CHOICE:-1}" in
1) TS_PLANE="tailscale" ;;
case "$TS_PLANE_CHOICE" in
1)
# TODO(pastilhas): what setting up your own offscale actually does.
warn "Setting up your own network is not built yet."
echo " Pick 2 if you already run one, or 3 for tailscale.com."
;;
2)
# No default offered. A control-plane URL is somebody's private
# infrastructure, and a machine that joins the wrong tailnet has
# joined a stranger's network.
read -rp " headscale URL (e.g. https://headscale.example.com): " TS_LOGIN_SERVER || fail "No answer."
# No default offered, deliberately. A coordination server URL is
# somebody's private infrastructure, and a machine that joins the
# wrong one has joined a stranger's network.
read -rp " URL of your server (e.g. https://headscale.example.com): " TS_LOGIN_SERVER || fail "No answer."
if [[ "$TS_LOGIN_SERVER" =~ ^https?:// ]]; then
TS_PLANE="headscale"
TS_PLANE="self-hosted"
else
warn "That needs to be a full URL, starting with https://"
fi
;;
*) warn "Pick 1 or 2." ;;
3) TS_PLANE="tailscale" ;;
"?")
echo ""
tailscale_networks_help
echo ""
info "Which network should this machine join?"
echo ""
echo " [1] set up your own network (offscale)"
echo " [2] use a network you already run (headscale, offscale)"
echo " [3] the easy route (tailscale.com)"
echo " [?] what are tailscale, headscale and offscale?"
echo ""
;;
*) warn "Pick 1, 2, 3 or ?." ;;
esac
done
echo ""
info "How should this machine authenticate?"
echo " An auth key enrols it without a browser. Leaving this blank is"
echo " fine — Tailscale then prints a URL to open, and waits for you."
if [[ "$TS_PLANE" == "tailscale" ]]; then
echo " Leave this blank and Tailscale prints a link to open in a"
echo " browser. Signing in there creates the account if you do not"
echo " have one, or adds this machine to it if you do."
echo " An auth key, if you have minted one, skips the browser."
else
echo " An auth key enrols this machine without a browser. Leaving it"
echo " blank prints a link to open against your own server instead."
fi
echo ""
read -rp " Auth key (blank for the browser flow): " TS_AUTHKEY || fail "No answer."
@@ -516,7 +544,9 @@ if ! skip; then
echo ""
TS_ARGS=(up --timeout=60s)
[[ "$TS_PLANE" == "headscale" ]] && TS_ARGS+=(--login-server "$TS_LOGIN_SERVER")
# Only a self-hosted server needs pointing at. Option 3 is the default
# coordination server, which means passing no --login-server at all.
[[ "$TS_PLANE" == "self-hosted" ]] && TS_ARGS+=(--login-server "$TS_LOGIN_SERVER")
# Never passed empty. `--authkey ""` silently falls back to the interactive
# flow and blocks forever, which is exactly how the original hung.
[[ -n "$TS_AUTHKEY" ]] && TS_ARGS+=(--authkey "$TS_AUTHKEY")