Commit Graph
8 Commits
Author SHA1 Message Date
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 c1db56312d feat(panel): editable IPv6 pool with batch-add management page
- net.ipv6_pool is now operator-editable (was immutable): accept bare
  addresses or explicit /128 (any other prefix length rejected), stored
  normalized to the bare form.
- New admin "IPv6 Pool" page (visible in pool mode): multi-line
  batch-add box, list with per-address state (free / used + owner), and
  remove for free addresses (assigned ones are refused — a user keeps
  its address for life).
- Adding addresses re-applies the host plumbing so any address the
  provider bound on the external interface is detached immediately.
- mgr: AddPoolIPv6s / RemovePoolIPv6 / PoolList / PoolEntries with tests.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 14:47:27 +00:00
bluebluesodaandCommandCodeBot 790ed11369 fix(pool): routed NIC for per-address IPv6, detach pool addrs from host
Empirically this is what makes discrete whitelist addresses work:

- The provider binds every address on the host's NIC at boot; while the
  host holds an address the kernel treats it as LOCAL and drops the
  container's packets using it as a source (source-address validation),
  so outbound v6 silently fails. Pool mode now removes each pool address
  from the external interface (vps ip6 addr-del), on add/reinstall and
  every ipv6-reapply/boot — self-healing after a reboot re-binds them.
- Containers get TWO NICs: eth0 = nictype routed on the external
  interface with ipv6.address=<pool /128> (Incus programs the /128 route
  + proxy_ndp + fe80::1 gateway), eth1 = bridged on incusbr0 for the
  shared IPv4. systemd-networkd binds the /128 statically on eth0 and
  DHCPv4s on eth1.
- The manual bridge /128-route + proxy_ndp plumbing (SetupIPv6BridgePool,
  WireIPv6Pool route/neigh) is gone — Incus programs everything.

Verified end-to-end on the whitelist host: container reaches out over v6
(curl -6 returns its own /128) and v4 (eth1 NAT) simultaneously, external
Globalping hits the container /128 with 0% loss, delete releases the
address and a new container reuses it.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 14:47:27 +00:00
bluebluesodaandCommandCodeBot 904e60ef7e feat(panel): IPv6 pool dropdown on create + docs
Pool mode adds a create-user dropdown (auto first-free / a specific free
address / no IPv6) and an IPv6 column in the user table. Docs cover the
two modes, the installer flow, and the empirically verified per-address
routing.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-15 14:47:27 +00:00
bluebluesodaandCommandCodeBot d93b93709f refactor: rename traffic to bandwidth across code, schema and docs
The UI already speaks "bandwidth"; the internals still said "traffic"
for the same concept (monthly quota, NIC counters, throttling). Align
the whole stack:

- db: table `traffic` -> `bandwidth`, column `traffic_quota_gb` ->
  `bandwidth_quota_gb` (fresh schema, no migration needed)
- lx: `Traffic`/`TrafficMap` -> `Bandwidth`/`BandwidthMap`
- mgr: `SampleTraffic`/`TrafficFor`/`EnforceTrafficLimits`/
  `ParseTrafficGB`/`UpdateQuotasAndTraffic` -> bandwidth equivalents
- panel/admin/main: template fields, form names, CLI flags and vars
- docs and AGENTS.md updated; ordinary English uses of "traffic"
  (forwarded traffic, inter-container traffic) are kept

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-14 05:58:50 +00:00
bluebluesodaandCommandCodeBot 57f4ccb94e chore: drop upgrade/compat scaffolding for the fresh start
The Incus line is a new project, not an upgrade path — remove every
piece of cross-version compatibility:

- version gate: ver.Blocked/MinAdoptable/SemVerLT, blockUnadoptable,
  cmdNoteVersion, the installed_version/uninstalled_version config
  fields and registry entries, install.sh old-binary detection and the
  uninstall note-version call.
- DB migrations for pre-0.3 schemas: migrateAuditTargetDrop,
  migrateUserColumns, migrateDomainColumns, migrateCPU and their tests.
- legacy admin-pass migration from config.yaml into the DB.
- duplicate static sudoers file (configs/sudoers.d/vps) — the Go
  ensureSudoers embedded copy is the only source.
- docs swept of version-gate and 0.2.x/0.3.x language.

Also rename the bridge lxdbr0 -> incusbr0 across code, scripts, config
and docs, and adapt NIC isolation to Incus 7.0 validation: ipv6_filtering
is only applied when the eth0 device actually carries an IPv6 address or
route (Incus rejects it on a v6-less device, unlike LXD).

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-14 04:05:53 +00:00
bluebluesodaandCommandCodeBot 1663563020 docs: reflect the Incus runtime, vps.* services and privilege drop
- architecture.md: Incus components, unprivileged panel section
  (incus-admin group + sudoers whitelist), vps.* unit names, atomic
  user creation transaction.
- configuration.md: incus.* config keys, /var/lib/incus socket, vps
  service restart.
- development.md: Incus dev-loop instructions, updated layout.
- README(.zh-CN).md: Debian 13/Ubuntu requirements, Incus mention.
- AGENTS.md: Incus invariants (socket, websocket exec, EnsureImage
  before Launch, sudoers whitelist, vps.service naming).

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
2026-08-14 03:33:37 +00:00
bluebluesodaandCommandCodeBot ebc2b1478f feat(incus): port the container runtime from LXD to Incus 7 LTS
The panel now talks to Incus over its Unix socket REST API
(/var/lib/incus/unix.socket, group incus-admin) exclusively:

- internal/lx: exec moved from the `lxc` CLI to the API websocket
  transport (Exec/ExecSH/RunInitScript); EnsureImage pulls a
  remote-qualified fallback (images:debian/13) before Launch since the
  API cannot auto-fetch it inside the create call; per-container df
  probe in mgr/batch.go uses the same API path.
- cfg: config key renamed lxd.* -> incus.* (image, image_fallback,
  pool, bridge, socket); DefaultSocket is the Debian-package path.
- mgr: container disk probe and image handling updated; comment sweep
  from LXD to Incus.
- deps: add gorilla/websocket for the exec transport.

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