Move the swap decision to the start of install.sh (before 00-ip-ask).
Swap is now mandatory: if absent, ask the user for a size in GiB
(default decline aborts with a bilingual note pointing at swap files
or systemd-zram-generator). The old optional swap block in
00-check.sh is removed.
All image build scripts now append the TCP tuning sysctls to
/etc/sysctl.conf and run sysctl -p (best-effort) during the build.
Covers 50/eol-debian11/80 (Debian) and 60/70/90 (RHEL/openSUSE/Arch).
scripts/eol-debian11-image.sh builds vpsmgr/debian-11-sshd from
images:debian/11 (fallback bullseye). Reuses the 50-image.sh slim
tooling and IPv6 on-link fix — systemd 247 on bullseye supports the
full [IPv6AcceptRA] section. Optional, never part of install.sh.
Downloads the repo as a tarball (no git on host), runs install.sh,
and removes the extracted temp dir on exit. Supports --update /
--local-build passthrough.
- Increase user-panel component borders from 2px to 3px
- Make the overview username visibly heavier
- Apply the stronger borders to the login card and input
- Admin create-user and change-password buttons switch from blue to a neutral
black-in-light / white-in-dark scheme (shared .neutral class with login-as)
- User panel light background darkened one shade (#f1f5f9 -> #e6ebf1) in the
overview, login page and themed variant
- Add vivid blue and fuchsia to the accent palette (5 swatches per row)
- User panel: tint background, cards, borders and code blocks via CSS
variables plus a 3px colored bar under the title for a stronger cue
- DB v12: users.color column (hex from a fixed 8-color palette, allowlist)
- Admin: click the username to open a swatch picker + clear; colored text/dot
- Login button defaults to neutral black/white; themed when a color is set
- User panel: tint background and accents via CSS variables in both modes
- Document the hidden entry point in READMEs and docs/architecture.md
- Mem/Disk sort now normalizes KiB/MiB/GiB/... to bytes so e.g. 970 MiB
sorts above 2 GiB instead of by raw prefix number.
- Bandwidth column becomes sortable, ordered by up+down total for the
month (BWTotal piped through BatchUsers -> userView).
collectManagedImages always force-added the configured default (incus.image)
first, so a default image deleted from Incus stayed as a permanent choice in
the reinstall dialog even though it no longer existed. Modify the list to
contain only images actually present in Incus, ordering the configured
default first only when it exists.
- Only images present in the alias list are offered; a deleted image now
disappears from the picker.
- Incus-query failure still offers the configured default so reinstall works.
- /images now returns 'default' pointing at an actually-present image (the
configured one if present, else the first offered), so the UI always has a
checked entry instead of leaving every radio unselected.
- Update image tests to the new contract.
- Replace hand-drawn approximation icons with each distro's official
logomark (Debian swirl, dev terminal, Alma, Rocky mountain+sun,
openSUSE gecko, Arch A) on a unified rounded brand tile, white glyph.
- Convert the flat radio pills into a responsive card grid. Selecting now
shows an accent border + ring + glow, lifts the card, tints the
background, and reveals a round check badge (animated scale in) in the
corner instead of only recolor the text/border.
- Widen reinstall modal to 560px; clarer intro copy and description line.
- Admin overview table and CLI vps list/show now show the one-hour CPU
average; the user panel keeps the five-minute (near-live) average.
- Relabel the admin column to 1小时CPU / 1h CPU.
- Unify the two READMEs with Chinese as the source of truth and add the
features shipped since v1.3.5 (SSH key management, login-as, encrypted
notes, Debian dev + Arch images).
- Switch the CPU average window from -15m to -5m across admin/user panels
and the CLI list/show path (mgr.List, mgr.Show, BatchUsers, PanelResources).
- Relabel the column/card to 5分钟CPU / 5m CPU.
The dashboard CPU figure now reflects the trailing 5-minute average.
The minimal Arch base ships a single-default mirror list, so a slow or flaky
mirror aborted the whole pacman transaction. Write a mirrorlist with a few
reliable servers (official geo redirect + kernel.org + constant.com) so pacman
falls back automatically, and pass --disable-download-timeout so a slow-but-
alive download finishes instead of tripping the 'too slow' check.
incus publish 'description=<v>' stores the value as the image's
properties.description (what incus image show prints), not a top-level
field — so the Arch build date was never read and the reinstall dialog
fell back to the static blurb. Parse properties.description instead;
verified against the live Incus API.
- Arch script records the build date as 8 digits (YYYYMMDD) in the image
description
- lx.ImageAliasesWithDesc exposes image descriptions; Images() folds the
date into the Arch intro ('…滚动发行版,我们提供镜像打包于 <date>')
- Arch icon is now the 'A without crossbar' (Λ) shape instead of a solid
triangle
- openssh on Arch ships both sshd and the ssh client; openssh-client does not
exist and broke the whole pacman transaction (tested on a real Incus host)
- pacman -Syu --needed avoids reinstalling base packages; remove orphaned
packages after the upgrade (apt-autoremove equivalent)
- record the Archlinux<YYMM> version code via the publish key=value property
(incus publish has no --description flag); plain rm for cache cleanup
(pacman -Scc prompts in a non-tty exec)
- verified end-to-end: built vpsmgr/arch-sshd, launched a container and
confirmed IPv4 + IPv6 connectivity and SSH over both stacks
- scripts/90-arch-image.sh: builds vpsmgr/arch-sshd from images:archlinux/
current; unlike other image scripts it always deletes and rebuilds (rolling),
records Archlinux<YYMM> in the image description, keeps the image slim and
deletes the base afterwards
- Register Arch Linux label + rolling-release blurb and a gray triangle icon
in the user panel reinstall dialog
- Docs (README, architecture, development, AGENTS) and image tests updated
- Keep the in-memory envelope in sync after every save so unlocking with a
freshly changed password works without a page reload
- Save & lock now uses the plain button style; Save now is highlighted
- Replace the list-header Lock button with 'Save & lock' in the editor
toolbar: it forces a server save (verified) before locking
- Add a 'Change password' button where Lock used to be; opens a modal that
re-encrypts the notes with a fresh key+salt and persists, reverting on
failure
- doSave now resolves success/failure so save-and-lock can confirm first
- Add an Export button in the notes list header (next to Lock)
- Hand-written minimal ZIP writer (STORE, no deps, CSP-safe)
- Each note becomes a .txt; a versioned raw.json is included for future
import; filename yyyy-mm-dd-hh-mm-ss-notes.zip
- SnapshotLimit() returns 0 when the configured limit is 0 (or negative),
meaning users cannot create new snapshots; existing snapshots are kept
- SnapshotCreate refuses with 'snapshots are disabled' before any Incus call
- Update config comment/registry description and tests for the new semantics
- Widen the reinstall modal (620px) and enlarge the image tabs + icon badges
(28px SVGs)
- Replace the Debian dot-swirl with a true spiral coil path so it reads as a
whirl
- Backend: ManagedImage gains desc_zh/desc_en, populated per alias so the
reinstall dialog shows a one-line blurb for the selected image
- Frontend: per-image inline SVG icons (Debian swirl, dev hammer on pink,
Alma multicolor flower, Rocky mountain+sun, openSUSE gecko) and a live
description line below the image picker
- Write user-managed key lines with a Vpsmgr-User marker and operator keys
with a Vpsmgr-Operator marker
- applySSHKeysScript now drops every marked line then re-adds the still
active/granted set, so unchecking or deleting a key actually removes it
from authorized_keys; hand-added (unmarked) keys are never touched
- Update tests for the new markers and the same-key-in-both-roles cases
- Default the 'admin public keys' list to expanded (button shows collapse)
whenever the user has activated at least one admin key; otherwise keep it
collapsed. JS derives the initial state from the DOM.
- Audit: translate newly added action labels (login, ssh keys, admin keys,
init script, notes reset, ipv6 pool, bandwidth reset); highlight the pure
admin actor '000' like '000+' operators
- User panel: V4/V6 port blocks are click-to-copy, copying the full
'ssh -p <port> root@<ip>' command via a data-copy override
- Security: login-as refuses when the user panel is disabled, avoiding a
Path="/" cookie leak; covered by a test
- Admin /login-as: create an impersonated user session, set the user-panel
cookie, redirect into that user's panel regardless of password
- Session DB migration: sessions.impersonated flag to distinguish operator
logins; user panel shows a 'logged in as' banner + return link
- Audit: impersonated-session actions are attributed '000+<user>' via an
auditActor helper (all 12 panel call sites)
- Audit coverage: add user/admin login, init-script save, ipv6 pool add/del
- Admin UI: 'login panel' button per user row and 'log in as' in the
post-create modal (flash now carries opaque data)
- Admin keys: remove the per-key active checkbox; every key the operator
adds is uniformly visible to users
- User SSH-key panel: grant admin keys with a checkbox; saving persists the
grant and syncs it into the container's authorized_keys
- Admin-injected lines carry an ASCII 'from-admin' marker so they are
reliably identifiable
- Admin keys are fully synced: activated keys present once, unactivated or
deleted ones removed on save; user's own and hand-added keys untouched
- Reinstall re-injects granted admin keys so admin access survives
- DB v10: admin_key_grants join table (cascade with user/admin key)
- Add a collapsible 'expand admin keys' link in the user SSH-key modal
- Reveals the operator's stored public keys read-only (name + key content)
- Shows a red warning that activating those keys authorizes admin login
- Hidden entirely when the admin has no stored keys
Untitled notes now get a title derived from the first line of their content
(trimmed, capped at 15 chars) at save time; an existing title is never
overwritten. A Lock button next to Add flushes pending edits, drops the
local password/key cache and returns to the unlock prompt.