GL-7 Part 2: install-command generator on the customer page

Replaces the static Option-1/2 Setup Command blocks with an interactive,
client-side builder: mode (required radio), cores/memory (required for byo,
optional for appliance), vmid, node, acl-storages (quote-wrapped),
operator-pubkey-file, preserve-state-from, and --dry-run/--preflight-only/
--skip-provision/--allow-new-leaf checkboxes. genFlags()/genUpdate() assemble
a live-updating download-then-run command (never curl|bash) + a local-run
variant, enforcing the script's own rules client-side (mode required; byo
requires caps → shows a warning + no runnable command; appliance hides the
caps requirement; allow-new-leaf shows its leaf-regen warning). Emits ONLY
real host-install v1.12.0 flags; the dangerous/operator-only set
(--force/--rotate-recovery/--enable-oob/--remove-golden/--uninstall/
--adopt-pool/--rescope-acl) is never offered. Graceful static fallback:
the server-rendered Option-1/2 commands keep --customer-id + a --mode
placeholder when JS is off. No framework/CDN/network; ScriptVersion (const,
in sync with SCRIPT_VERSION) drives the header. Render/structure test covers
the control ids, version, fallback, and the excluded-flag absence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-09 08:29:15 +02:00
parent b93dd03f0a
commit 844fbfa749
4 changed files with 258 additions and 10 deletions
+58
View File
@@ -535,6 +535,64 @@ code {
color: var(--text-3);
}
/* Install-command generator (GL-7) */
.gen-controls {
background: var(--bg-0);
border: 1px solid var(--line);
border-radius: var(--radius);
padding: 1rem;
margin-bottom: 1rem;
}
.gen-radios {
display: flex;
gap: 1.25rem;
flex-wrap: wrap;
}
.gen-radio, .gen-check {
display: flex;
align-items: center;
gap: 0.4rem;
font-size: 0.85rem;
color: var(--text-1);
text-transform: none;
letter-spacing: normal;
font-weight: 400;
cursor: pointer;
}
.gen-radio input, .gen-check input {
accent-color: var(--blue-bright);
cursor: pointer;
}
.gen-checks {
display: flex;
flex-direction: column;
gap: 0.5rem;
margin-top: 0.85rem;
padding-top: 0.85rem;
border-top: 1px solid var(--line-soft);
}
.gen-check code, .gen-radio code { color: var(--blue-bright); font-size: 0.8rem; }
.gen-controls input[type="number"] {
background: var(--bg-1);
border: 1px solid var(--line);
border-radius: var(--radius);
padding: 0.5rem 0.75rem;
color: var(--text-1);
font-size: 0.9rem;
font-family: inherit;
}
.gen-controls input[type="number"]:focus,
.gen-controls input[type="text"]:focus { outline: none; border-color: var(--blue-bright); }
.gen-msg {
color: #E5534B;
font-size: 0.82rem;
margin: 0 0 0.75rem;
padding: 0.5rem 0.75rem;
background: rgba(229,83,75,.10);
border: 1px solid rgba(229,83,75,.35);
border-radius: var(--radius);
}
/* Credentials */
.credential-row {
margin-bottom: 0.5rem;