309 Commits
Author SHA1 Message Date
bluebluesoda c2fa63fba9 fix(panel): hidden state boxes for sticky notes were always visible
.notes-cover and .notes-main set display:flex, which overrode the HTML
hidden attribute (the UA [hidden]{display:none} rule loses to any author
display value). As a result the enable, locked and editor states rendered
simultaneously. Add explicit [hidden] overrides so the three states stay
mutually exclusive.
2026-08-24 07:54:31 +00:00
bluebluesoda 10c649f794 refine(panel): tighten notes UX and trim SSH-key panel wording
- SSH keys: drop the long "clean key / comment fallback" explanation from
  both the user and admin panels (the behavior is unchanged).
- Notes: before enabling or unlocking, the card shows only the essentials
  (a single enable button / the password prompt) with nothing else visible.
- Titles are now edited inline in the list tabs; the separate title field is
  gone, giving the body more room.
- Delete moved off the tabs into the editor toolbar with a two-step
  confirm (armed for 3s), disabled when only one note remains; a manual
  save button sits next to it.
- Save status is explicit: red "storage full" on overflow (client and
  server), red "network problem" on fetch failures, plus the existing
  unsaved/saving/saved timestamp states. The enable flow caches the key
  even if the first save fails.
2026-08-24 07:47:42 +00:00
bluebluesoda 241279ffb9 feat(panel): machine-panel init script modal and encrypted sticky notes
Move the init-script editor out of its standalone card into a modal opened
from the Machine card (JSON save keeps the modal open; the form POST path is
unchanged). In its place, add end-to-end-encrypted sticky notes: the browser
derives an AES-256-GCM key from a user-chosen password (PBKDF2, 200k iters)
via WebCrypto, and the server only stores an opaque envelope in a new
sticky_notes table (schema v9). Notes have enable/locked/unlocked states,
a 7-day local key cache, add/delete/drag-reorder, and auto-save 3s after
edits stop. Plaintext is capped at 512 KiB client-side; the server rejects
oversized bodies (notes_full) - both surface as "storage full".
2026-08-24 07:28:18 +00:00
bluebluesoda 5e5aac44e9 feat(admin): SSH public-key management for the operator panel
Add an operator-side SSH key store (admin_keys table, schema v8) managed
from a floating panel opened via a new header tab. Keys are stored cleanly
(comment stripped, name falls back to the comment) and reconciled full-set
on save, mirroring the user panel; they are not injected into containers yet.
Adds SaveAdminKeys/ListAdminKeys in mgr and a JSON /keys endpoint with
tests for the db, mgr and admin handler layers.
2026-08-24 07:15:54 +00:00
bluebluesoda aa55def3c2 feat(panel): dedicated SSH key management replacing quick-add
Replace the client-side "quick add SSH key" (one key, stuffed into the
init script) with a real key manager: a floating panel in the Machine
card lists every stored key with an enable checkbox, editable name,
clean read-only key and delete, plus an add row that auto-fills the name
from the key comment.

- DB v7: ssh_keys(user_id, name, key, active) table, cascades on user
  delete; keys stored clean (type + base64, trailing comment stripped)
- mgr: ParsePublicKey validation, SaveSSHKeys full-set reconcile
  (update/add/delete + duplicate rejection), ApplySSHKeys injects
  append-only into ~/.ssh/authorized_keys with per-key dedup, preserving
  any keys the user added by hand
- /ssh-keys JSON endpoint saves the set and applies active keys to the
  running container immediately (best-effort; warns when unreachable);
  active keys are also injected on reinstall
- deactivation is additive-only: unchecked keys stop being re-applied
  but are never removed from the container
- i18n warn string; tests for db CRUD/cascade, key parsing/reconcile,
  and the panel handler
2026-08-24 06:57:59 +00:00
bluebluesoda 61fdf68686 feat(images): optional Debian 13 dev image builder
Add scripts/80-debian-dev-image.sh, modeled on 50-image.sh: pulls
images:debian/13, installs the universal sshd/tooling set plus the dev
toolchain (python3 + pip + venv, git/sqlite3/ripgrep/jq/gh/sshpass, all
--no-install-recommends), Go 1.26.7 (arch-aware, sha256 from the dl JSON
API), nvm v0.40.7 + Node 24, cleans caches, and publishes
vpsmgr/debian-dev-sshd (base deleted).

- Symlink go/gofmt/node/npm/npx into /usr/local/bin: /etc/profile.d is
  only read by login shells, so non-interactive ssh commands would miss
  them; nvm's .bashrc hook already covered node
- Register the alias in imageLabels so the reinstall dialog shows
  "Debian 13 dev"; extend collectManagedImages tests
- Optional: not part of install.sh, keeping small hosts lean
- Document the new image in docs/architecture.md, development.md and the
  AGENTS.md image-build invariant
2026-08-24 05:09:32 +00:00
bluebluesodaandCommandCodeBot a1cb6595ce fix(mgr): skip guests that reject IPv6 config instead of failing reapply
vps-ipv6.service runs `vps ipv6-reapply`, which failed hard when a
single container (e.g. a user-broken networkd) rejected its config.
That aborted `systemctl enable --now vps-ipv6` during install and left
`vps install` halfway, with the panel service stopped.

Align ipv6-reapply with the install path: treat RoutedIPv6Error as a
warning and move on, so one bad guest cannot take down the boot unit or
the panel. Host-level errors still abort.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-22 10:04:06 +00:00
bluebluesodaandCommandCodeBot 990f1a2a71 fix(panel): always accept ssh keys with comments and strip them in preview
- Parser now takes only `type base64` (greedy over the base64 alphabet,
  stopping at the first space); any trailing comment such as
  "Generated By Termius" is dropped instead of failing the match.
- Preview shows the cleaned key (no comment) so WYSIWYG with what gets
  inserted into the init script.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-22 09:44:11 +00:00
bluebluesodaandCommandCodeBot 5cc2f10ae4 feat(panel): 15-minute CPU average and dark-mode IPv6 select
- Widen the CPU average window from 5 to 15 minutes across the admin
  and user panels (List, Show, BatchUsers, PanelResources) and relabel
  the columns/cards accordingly.
- Replace the hardcoded white background of the create-user IPv6
  dropdown with a themed class so it matches the dark color scheme.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-22 08:22:50 +00:00
bluebluesoda f9114c86f3 Update README.md 2026-08-22 00:33:05 +08:00
bluebluesoda c9d19090f8 Update 20-network.sh 2026-08-22 00:24:36 +08:00
bluebluesodaandCommandCodeBot cc2c80a4fb fix(panel): accept key comments and fix init-script save flash
- Strip the trailing comment from pasted SSH public keys on insert
  (e.g. "Generated By Termius") instead of rejecting the whole key.
- Save the init script via native form submit: the previous fetch
  followed the handler's 302 redirect and mistook the returned HTML
  page for an error banner, dumping it into the toast.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-21 07:38:00 +00:00
bluebluesodaandCommandCodeBot 84f53394d6 fix(panel): i18n the chart axis label "24h ago" for English
The left axis caption was hardcoded Chinese; render it via the same
lang switch as the rest of the template.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-21 07:26:55 +00:00
bluebluesodaandCommandCodeBot dcc2f767ff feat(images): optional openSUSE Leap 16 image builder
Add scripts/70-opensuse-image.sh, modeled on 60-rhel-image.sh: pulls
images:opensuse/16.0, installs sshd + universal tooling via zypper,
cleans caches, and publishes vpsmgr/opensuse-sshd (base deleted).

- Register the alias in imageLabels so the reinstall dialog shows
  "openSUSE Leap 16"; extend collectManagedImages tests
- Leap 16 ships systemd-networkd, so panel IPv6 config takes the
  existing Debian networkd branch — no runtime code changes needed
- Optional: not part of install.sh, keeping small hosts lean
- Document the new image in README (zh/en) and docs/architecture.md

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-21 06:20:23 +00:00
bluebluesodaandCommandCodeBot 98b730c2d0 feat(panel): 24h resource usage charts for the user panel
Three canvas charts (CPU line, memory area, bandwidth stacked bars)
on the overview page, after the init-script card. Per-minute data
comes from the existing resource_samples table via a new /stats JSON
endpoint — pure DB read, no Incus call.

- mgr: ChartHistory returns per-minute points; bandwidth is the delta
  of the cumulative rx/tx counters between samples, safe against
  container restarts (boot-time guard) and counter resets
- panel: /stats handler (auth required) serves the last 24h for the
  current user; ChartPoint JSON {m, c, y, r, t}
- overview.html: three chart cards with shared pan (drag), zoom
  (wheel at cursor), double-click reset, adaptive time ticks that
  never crowd narrow screens, stable Y axes computed once from the
  full window, dark mode, per-minute hover tooltips
- tests: TestStatsEndpoint covers auth, JSON shape, and the bandwidth
  delta computation

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-21 06:02:21 +00:00
bluebluesodaandCommandCodeBot 7344b8ef3c feat(swap): auto-apply swap ratio on install, drop swap-reapply CLI
The swap-reapply command is internal bookkeeping users should never
see: containers get the configured incus.swap_ratio automatically, so
remove it from the CLI surface.

- cmdInstall now calls ApplySwapToAll alongside the other upgrade
  self-heal steps, so containers created before swap support get their
  allowance after upgrading and running `vps install`
- vps config set incus.swap_ratio keeps applying immediately to all
  containers (unchanged)
- drop the swap-reapply dispatch, cmdSwapReapply and help entry
- docs updated accordingly

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-21 05:03:41 +00:00
bluebluesodaandCommandCodeBot 7b31f2d4ec feat(swap): configurable per-container swap allowance
Incus 7 on cgroup v2 writes memory.swap.max=0 for every container
unless limits.memory.swap carries an explicit byte amount (true/false
both end up as 0), so containers previously got no host swap at all
and `free` inside showed 0. Add incus.swap_ratio (default 0.5) so each
container gets limits.memory.swap = limits.memory x ratio, set at
create/reinstall and on quota changes.

- config: incus.swap_ratio field + registry entry (non-negative float,
  0 disables swap; ApplyImmediate)
- lx: Client carries swapRatio; SetMem keeps swap proportional,
  SetSwap refreshes only the swap key
- mgr: ApplySwapToAll refreshes every container from the DB memory
  quota (idempotent, no restart)
- cli: `vps config set incus.swap_ratio N` re-applies to all
  containers automatically; `vps swap-reapply` is the manual/repair
  path for containers created before swap support
- docs: configuration/architecture/README updated

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 21:01:44 +00:00
bluebluesodaandCommandCodeBot 8188bd2dbf feat(install): remove unused snap lxd before installing Incus
Ubuntu images ship lxd as a snap even when it is never used or
initialized; its daemon/socket, /var/lib/lxd (or /var/snap/lxd) and
lxdbr0 collide with Incus. Before installing Incus, detect snap lxd and
remove it — but only when clearly unused: abort instead of deleting when
the daemon is running, containers exist, or an initialized lxd.db is
present (checked under both deb and snap data dirs). Idempotent; skipped
when the snap is already gone.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 16:48:24 +00:00
bluebluesodaandCommandCodeBot fd9f17cd09 fix(install): skip base image pull on reinstall
50-image.sh checked for the base image (vpsmgr-debian-13) BEFORE the
prebuilt sshd image, but the base is deleted after the first build as a
build intermediate. Every reinstall/upgrade therefore re-pulled
images:debian/13 over the network, then discovered vpsmgr/debian-sshd
already existed and exited. Check the sshd image first and exit before
touching the base image when it is present.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 16:21:51 +00:00
bluebluesodaandCommandCodeBot 3ef74e9c36 fix(lx): harden only bridged NICs, not routed pool-mode eth0
HardenIsolation unconditionally applied the NIC isolation options
(security.port_isolation / ipv4_filtering / ipv6_filtering) to eth0.
Incus only accepts those options on bridged NICs — pool-mode eth0 is a
routed NIC carrying the public /128, so `vps install` failed with
"Invalid device option security.ipv4_filtering". Prefix mode (single
bridged eth0) was unaffected, which is why the bug only surfaced in
pool mode.

- EnsureEth0Options generalized to EnsureDeviceOptions(name, devName)
  (wrapper kept for the EnsureBlockRoutes caller)
- HardenIsolation now iterates all NICs and skips non-bridged ones;
  pool-mode eth1 (bridged) is hardened like a prefix-mode eth0

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 16:13:33 +00:00
bluebluesodaandCommandCodeBot 76e99e0fcf feat(config): allow any space-free string for panel.display_ip
display_ip is purely cosmetic (panel URL, SSH hints) and never used in
rules, so accept IPv6 addresses, domain names, or any string without
spaces instead of requiring a parseable IP.

- registry: validate only that the value contains no spaces
- tests: domain accepted, space-containing value rejected
- docs/examples: drop the "public IPv4" wording

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 16:05:19 +00:00
bluebluesodaandCommandCodeBot fc6ec62892 fix(install): cap IPv6 probe to a 5-minute Phase-3 budget
The external Globalping verification could previously stretch to ~10
minutes (ICMP and TCP tests each ran up to 3 attempts with a 90s wait
per measurement). Give both tests a shared 300s budget, checked before
each attempt and inside the wait loop, so the installer never blocks
longer than ~5 minutes on a slow/unresponsive Globalping.

- gp_wait waits for the remaining budget instead of a fixed 90s
- gp_run_test stops starting attempts once the budget is used up
- summary reports the elapsed time, or that the budget was hit
- verdict stays "unverified" on budget exhaustion (grep contract
  with 00-ip-ask.sh unchanged)

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 15:59:18 +00:00
bluebluesodaandCommandCodeBot 7bc37567da fix(net): detect ext iface via IPv6 route / link fallback
The installer and IPv6 probe found the external interface only through
`ip route show default` (the IPv4 main table). On IPv6-only hosts and
policy-routed boxes (v4 default in a non-main table, e.g. WARP/wireguard
tunnels) that returns nothing, so check-ipv6-support.sh died at
"no default route / ext interface found" before probing anything and
the installer silently fell back to a wrong iface.

Fall back to the IPv6 default route, then the first non-virtual UP
interface (excluding lo/incusbr/virbr/docker/veth/warp/wg), in all five
places that detect the WAN iface: check-ipv6-support.sh, 00-check.sh,
00-ip-ask.sh, uninstall.sh and DetectExtIF.

Verified on a real IPv6-only host: probe now reports ext iface eth0 and
reaches Phase 2 instead of dying.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 08:12:43 +00:00
bluebluesodaandCommandCodeBot 3439f4517a style(panel): tint the snapshots button violet
The Machine-card snapshots button was the same neutral white as
Restart; give it a light-violet fill (dark-mode aware) so the two are
distinguishable at a glance.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 07:13:15 +00:00
bluebluesodaandCommandCodeBot 728f5c2748 feat(panel): move snapshots into a Machine-card modal
- snapshot management now lives behind a button in the Machine card,
  opening a modal instead of a standalone card
- drop the size column from the snapshot table
- the modal reopens after an operation via #snapshots hash so the user
  sees the updated list
- remove now-unused FormatBytes helper

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 07:03:02 +00:00
bluebluesodaandCommandCodeBot 484b53e811 feat(panel): user-managed container snapshots
- user panel: create/list/restore/delete disk-only snapshots per container,
  with confirm dialogs and a reinstall warning that snapshots are wiped
- snapshots.limit config key (default 1) enforces a per-container cap;
  admin panel is untouched
- restore keeps the live container config (disk_only) so quotas/NIC limits
  stay in sync with the DB, serialized via opMu against reinstall/delete
- audit log: snapshot.create / snapshot.delete / snapshot.restore
- fix: snapshot names carry a random suffix to avoid same-second collisions

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 06:46:56 +00:00
bluebluesodaandCommandCodeBot 049bc9c2c8 feat(audit): log user create/delete, quota, password and blocked-domain changes
- admin: record user.create, user.delete, quota.update, passwd.reset,
  blocked.update and admin.passwd (actor "000" for admin's own changes)
- panel: record passwd.change when a user changes their own password
- audit page: bilingual labels for the new action types

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-20 05:53:26 +00:00
bluebluesoda 84768f4f01 feat: bandwidth reset, strict usernames, unified dark mode
- admin: add reset-traffic-only action in the quota modal that zeroes a
  user's monthly counters and immediately lifts any active throttle
- mgr: tighten username validation to lowercase letters/digits only
  (no hyphens) and halve the max length to 31
- panel: match the admin panel's neutral dark palette for consistent
  dark-mode backgrounds across both UIs
2026-08-20 05:29:37 +00:00
bluebluesoda e5464db3b3 fix(admin): show new containers as running before first sample
- fall back to one live instances-list call only for users lacking a sample\n- steady state keeps the dashboard free of Incus calls\n- apply the same fallback to CLI list/show
2026-08-19 17:47:58 +00:00
bluebluesoda fc7685b418 fix(panel): highlight PROXY v2 disabled-by-default hint 2026-08-19 17:19:28 +00:00
bluebluesoda 8fe68c1acc feat(panel): show live cpu/mem/disk usage blocks
- add 5-minute CPU, used memory and used disk under the quota grid\n- read from the persisted sampler snapshot, no live Incus sample
2026-08-19 17:07:27 +00:00
bluebluesoda 918c1b0575 feat(admin): sortable dashboard columns and compact ssh port
- click Name/5m CPU/Mem/Procs/Disk headers to cycle asc/desc/default\n- single-column client-side sorting with indicator arrows\n- show the SSH port bare on the second line under Ports/SSH
2026-08-19 17:02:56 +00:00
bluebluesoda 1c294d0f52 fix(admin): shorten dashboard table headers
- compact CPU/Mem/Procs/Disk column titles so the table does not overflow
2026-08-19 16:52:57 +00:00
bluebluesoda 86b7038e2f fix(install): tolerate guest ipv6 setup failures
- continue host installation when one container rejects guest IPv6 setup\n- preserve fatal handling for host and database errors\n- identify the affected container in reapply failures
2026-08-19 16:39:51 +00:00
bluebluesoda 99f990b910 Merge main into dev 2026-08-19 16:11:42 +00:00
bluebluesoda 7866badddc feat(metrics): persist minute resource samples
- collect container metrics in one background Incus sample\n- serve dashboard usage from seven-day SQLite history\n- replace per-container disk exec and live page sampling
2026-08-19 15:53:04 +00:00
bluebluesoda 9da5624560 docs: raise minimum disk recommendation 2026-08-17 11:51:34 +00:00
bluebluesoda ee975021ba docs: refine feature summaries
- condense Chinese and English feature details\n- document quotas, networking, traffic, storage, and proxy behavior
2026-08-17 11:49:19 +00:00
bluebluesoda 50496f9367 docs: refresh bilingual readmes
- make Chinese the default README\n- streamline installation and usage guidance\n- align platform, IPv6, storage, and CLI documentation
2026-08-17 11:36:20 +00:00
bluebluesoda 8ab4d396d9 feat(install): add --update to force prebuilt binary refresh
- install.sh accepts --update (alongside --local-build): it forces a
  fresh download of the latest prebuilt release over an existing binary.
  A plain re-run still skips an installed binary (idempotent adopt).
- Conservative by design: on download/checksum failure the installed
  binary is kept and a warning is printed — never a surprise local
  rebuild over an unknown checkout.
- install_prebuilt now stops vps.service before replacing the binary
  (ETXTBSY on a live panel), and only after the download has verified,
  so a failed download never takes the panel down.
- docs: AGENTS.md invariant, architecture.md install lifecycle,
  README.zh-CN usage line.
2026-08-16 05:29:46 +00:00
bluebluesoda adad8584d4 feat(domain): admin blocked-domains list + strict validation
- Admin domain panel gains a blocked-domains textarea (one domain per
  line); entries and all their subdomains are refused by mgr.AddDomain —
  the single add path — using label-boundary matching (example.co.uk
  blocks a.example.co.uk but not forexample.co.uk). Existing domains are
  untouched; only the add path is guarded.
- Save is per-line validated: invalid lines are skipped and reported by
  their 1-based line numbers in a flash banner, the rest are saved.
- Migration v5 seeds a default list (mozilla/github/aws/microsoft/apple/
  google/etc.) only when the settings key was never written, so admin
  edits or a full clear are never re-seeded.
- normalizeDomain is rewritten around explicit rules shared by the add
  path and the blocked list: lowercase, strip all trailing dots, reject
  any character outside [a-z0-9.-] (never silently strip — pasting a URL
  is an error), must end with a letter (excludes dotted-quad IPs), must
  contain a dot (no single-word names), each label non-empty/<=63 and
  starting+ending with a letter or digit (consecutive hyphens mid-label
  like xn--p1ai stay legal), total <= 253. No TLD validation.
- Tests: db round-trip + v5 seed (fresh/reopen/admin-edit/preexisting-key),
  matching semantics, parse/save partial validation, validation rules.
- docs: architecture.md blocked-domain section.
2026-08-16 05:19:15 +00:00
bluebluesoda fb3f8b7cfc feat(install): add VPSMGR_STORAGE=dir opt-in for test boxes
- New installs use a dir storage pool when VPSMGR_STORAGE=dir (default
  zfs). A failed ZFS pool still aborts — the switch is explicit, never
  an automatic fallback.
- 00-check.sh skips zfsutils-linux, the DKMS module build and the zfs
  boot units entirely in dir mode (no kernel module needed).
- 10-incus.sh creates/adopts a dir pool without requiring zpool; zfs
  mode still refuses any non-ZFS pool, fresh or adopted.
- uninstall.sh is unchanged: incus storage delete handles both drivers
  and the zpool destroy is already guarded by 'zpool list'.
- docs: architecture.md and AGENTS.md document the switch.
2026-08-15 17:33:53 +00:00
bluebluesoda 0adc50a4db fix(pool): RHEL containers need nmcli IPv6 config, not just networkd
poolContainerScript only rendered Debian systemd-networkd files
(/etc/systemd/network/eth0.network binding the public /128). RHEL-family
images use NetworkManager, which ignores networkd config, so a pool-mode
Alma/Rocky container never bound its routed-NIC /128 and had no public
IPv6 — while Debian worked. Verified on a whitelist-provider host: the
nmcli path (eth0 = manual IPv6, /128, fe80::1 gateway, IPv4 disabled;
eth1 = DHCPv4) brings up the /128, the default route and v4/v6/DNS
connectivity, and the connection survives reboots.

- routed_ipv6.go: poolContainerScript branches on the guest stack —
  RHEL/NetworkManager gets a static nmcli connection matched by DEVICE
  (name-grep fallback), Debian keeps the networkd files. Idempotent and
  self-healing on reinstall/ipv6-reapply.
- ipv6_test.go: TestPoolContainerScript asserts both branches render the
  /128, fe80::1 gateway and DHCPv4 markers.
2026-08-15 17:10:31 +00:00
bluebluesodaandCommandCodeBot 555401ea5b feat(ui): trim Globalping credit; warn against adding host's own v6
Trim the Globalping attribution in the installer to a short credit.
In the admin IPv6 pool page, show a prominent bilingual alert telling
operators not to add the host's own currently-used public IPv6 address
to the pool (it would break host IPv6 connectivity).

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 16:27:09 +00:00
bluebluesodaandCommandCodeBot 902e9a9063 feat(install): default pool mode + Globalping attribution
Make the IPv6 pool option the default choice in the installer prompt
(press enter for pool) and show a small thank-you attribution to
Globalping for powering the external reachability probe.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 16:20:02 +00:00
bluebluesodaandCommandCodeBot 90b7193127 fix(install): resolve Go tarballs from stable download manifest
The VERSION endpoint can temporarily name a release before its archive is
available through every download edge, causing a hard 404 during local
builds. Read the official stable JSON manifest instead, select the archive
for the current architecture, retry downloads, and fall back through the
previous stable release when the newest archive is unavailable.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 15:30:07 +00:00
bluebluesodaandCommandCodeBot 64349de0c0 refactor(install): always use root loop-file storage
Remove secondary-disk discovery and whole-disk ZFS creation from the
installer. New installations now always create a sparse ZFS loop-file
pool from free space on /, while existing vpsmgr pools are still adopted.
The installer no longer scans, selects, formats, or modifies devices such
as /dev/vdb, including virtual ISO/CD devices.

Update storage documentation and keep the existing reclaim, pool sizing,
and ZFS quota behavior.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 15:24:18 +00:00
bluebluesodaandCommandCodeBot 3d524eef05 fix(install): remove duplicate legacy IPv6 prompt
The script accidentally contained two ask_ipv6 definitions. Bash used the
second legacy definition, so the new detector/globalping flow was silently
overridden and installations jumped straight to manual prefix input.
Keep only the detector-based implementation.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 15:03:12 +00:00
bluebluesodaandCommandCodeBot d07deedb8d chore: use doc-reserved IPv6 in panel test fixture
Switch the fixture to the 2001:db8:: documentation block so the
workspace carries no real-format provider prefix.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 14:48:59 +00:00
bluebluesodaandCommandCodeBot 1b1cd74c8f chore: use doc-reserved IPv6 in panel test fixture
The test used a real-format global prefix; switch to the 2001:db8::
documentation block.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 14:47:27 +00:00