Expose target node, target storage, owner (admin-only) and description
in the clone dialog, wired to the existing backend params. Reset the
form on open and fix the cramped label/field spacing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- _do_clone_sync now tails the PVE clone task log and maps the disk
transfer percentage to deploy progress 50→95% instead of a static 70%.
- Add owner_id to CloneRequest; admins may assign the clone to another
user (mirrors LXC deploy). Register the cloned instance via
save_vm_instance so it has an owner and is visible to limited users.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add ColumnFilter component (Popover-based faceted filter) and a
formatVmConfig helper rendering "N vCPU / X GB RAM / Y GB".
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move hardcoded English labels (compute resources, disk resize, raw
config, etc.) to i18n keys and replace ad-hoc mt-1 with consistent
space-y-1.5 between labels and inputs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Filter backup files by VMID, volume, notes or node in real time, with a
distinct empty state for no-match. Tint the job dialog VM-picker
checkboxes with the brand amber accent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
useCreateSnapshot omitted the required ?node= query param, so creation
failed with a 422. Pass node through, and add a UI hint plus a clear
error message when the VM storage does not support snapshots.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
new Error(error.detail) produced "[object Object]" when detail was an
array (422 validation errors) or object. Add formatApiError() to extract
a readable message and widen ApiError.detail to match real responses.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
create_vm_snapshot/create_container_snapshot returned success as soon as
the POST returned a UPID, so a snapshot that failed asynchronously (e.g.
storage without snapshot support) still reported "created". Now wait on
the task and surface the actual exitstatus.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Frontend (React/nginx) is served on port 3001, not 8000.
Port 8000 is the backend FastAPI — API endpoint and /docs
references at 8000 are kept as-is since they are correct.
Fixed in: README.md, README.ru.md, WIKI.md (quick-start URL
and standalone deployment port description).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The host watchdog ran `down` before `build --no-cache`, so a failed
build left the whole stack offline ("code updated, containers don't come
up"). Reorder to build first (app + frontend) while the old stack runs;
only tear down once images are ready. Use `up -d --wait` so success means
containers actually became healthy (DB migrations run on app startup),
and log `compose ps` + a hint on failure.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_parse_version split on "." only, so "2-1" hit int() and the whole
version collapsed to (0,) — update checks ignored build bumps and could
even offer a "downgrade". Extract every numeric run via regex instead:
"1.5.2-1" -> (1, 5, 2, 1).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- README.ru.md: bump badge from 1.5.0 to 1.5.2-1; add real-time
disk/IOPS/network metrics, per-user language and ConfirmDialog entries
- README.md: add same new feature bullets to Monitoring and Other sections
- WIKI: fix language-switch path (Panel → Profile since v1.5.2);
update log-retention note (log_retention_days now in UI, not DB-only);
update footer date and version (May 7 / 1.5.0 → June 20 / 1.5.2-1)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Update VERSION, README badge, CHANGELOG (en/ru) and WIKI for v1.5.2-1.
Patch release: styled ConfirmDialog replaces all native browser confirm() popups.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The webhook_url field was stored in DB but never used to send
notifications — removing it from UI avoids misleading users.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Profile tab: add language selector (per-user), add toast on save/error
for profile info and password change (clears fields only on success)
- Notifications: remove Chat ID field from admin Telegram section —
it was never saved to DB and only served as a test-only input;
testing is now done via "Мои уведомления" → Send test
- Add missing onSuccess/onError toasts to SMTP and Telegram save buttons
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Store UI language per user (users.language column, migration 26).
Language selector moves from Panel tab to Profile tab — each account
picks its own language, saved to DB and applied via i18n.changeLanguage()
on save so the interface switches immediately.
Panel tab: panel_name read-only (falls back to env PANEL_NAME),
log_retention_days field exposed in UI, language selector removed.
Panel API accepts panel_name in PUT so it can be overridden in DB
without touching the env var.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename SMTP request/response fields (host/port/username/password/from_email/tls)
and point security settings hooks at /admin/api/security/settings with a typed
SecuritySettings shape. Add minutes / security_saved i18n keys.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add live per-disk usage, disk read/write and network in/out rates to the
instance Overview tab, the instances list and the dashboard top-loaded list.
Backend:
- get_vm_fsinfo() pulls per-filesystem usage via QEMU guest agent
- metrics_broadcaster computes I/O rates (bytes/sec) from cumulative counters
- instances-list loop now refreshes each running VM via status/current
(1s-granular) instead of cluster/resources (10s pvestatd), with bounded
concurrency, and paces both realtime loops to a 1s cadence
Frontend:
- OverviewTab: per-disk cards, Network I/O and I/O-rate cards via WS
- InstancesPage: Net and Disk I/O columns; Disk% shown for LXC only
- DashboardPage: top-loaded list overlaid with realtime metrics
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Validate resource name in auto-allocate form before sending request
- Fill resource_name, proxmox_node, resource_type, mac_address when syncing
a VM that already has matching vmid/server_id but missing metadata
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The IP map tooltip read e.ip, but the backend ip-map endpoint returns
the address as ip_address, so the IP rendered as 'undefined'. Align the
IPAMIPMapEntry type with the backend response and build the tooltip from
proxmox_vmid, resource_name/hostname and ip_address.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wire up backend IPAM endpoints that had no frontend:
- edit/delete network (with force) on network detail page
- full pool CRUD (create/edit/delete) on network detail page
- manual allocation create + edit on allocations page
- IP address map visualization per network
Add missing hooks (useCreatePool/useUpdatePool/useDeletePool,
useUpdateAllocation), force support in useDeleteNetwork, typed
ip-map entries, writable allocation fields, and RU/EN locale keys.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- check_stale_db_volume looked for <project>_postgres_data but the
compose volume is <project>_db_data, so stale-volume detection and
--reset-data silently did nothing; use the real name.
- Generate a Fernet key (url-safe base64 of 32 bytes) for backend/.env
in all env-creation paths so sensitive fields are encrypted at rest
instead of stored as plaintext.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The mock_proxmox fixture patched ProxmoxClient with return_value= (constructor
style), but since commit d66928e clients are built via the
ProxmoxClient.from_server classmethod. from_server() therefore returned an
unconfigured child mock, so endpoints serialized a MagicMock and responded 500
— failing 5 tests in test_api_vms.py on every CI run (Backend Tests workflow).
Wire .from_server.return_value (and .return_value) on all patched ProxmoxClient
references to the configured instance so every construction path resolves to
the same mock. Full suite now green (60 passed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Roles are stored in the new resource:action format and any legacy keys are
converted once at startup by the RBAC v2 DB migration (migrate_rbac_v2), so
the permission engine no longer needs to resolve legacy codes on every check.
- get_user_permissions: store role permission codes as-is (no dual add).
- has_permission: match new-format codes only; drop resolve_permission and the
dotted-code fallbacks.
- Remove now-unused resolve_permission import in middleware.
- LEGACY_PERMISSION_MAP / convert_* are retained as one-shot DB-migration
utilities (upgrade path), not a runtime bridge.
- Tests: adapt fixtures to new-format role permissions; assert legacy keys are
no longer honored at request time.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace all legacy dotted permission codes (vms.view, proxmox.manage, ...)
in PermissionChecker/has_permission across app/api with the new
resource:action format (vm:view, server:manage, ...), per LEGACY_PERMISSION_MAP.
All 33 codes used by the API are now registered in the permission registry.
Also switch the /api/auth/me admin branch to get_all_permissions_v2 so the
endpoint emits permissions in the new format only.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These permissions were referenced by the API (users.manage, proxmox.vm.manage)
but never registered in the permission registry, so they only worked through
the is_admin bypass — non-admin users granted them silently received 403.
- Register user:manage and vm:manage in the registry.
- Add missing legacy mappings: users.manage->user:manage,
settings.manage->setting:manage.
- Grant both new permissions to the admin role (defaults + init.sql seed);
ensure_default_roles_new_format propagates them to existing deployments.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collapse four duplicated host+auth client-building blocks into a single
ProxmoxClient.from_server() classmethod (the canonical source of truth):
- _helpers._get_proxmox_client now delegates to from_server (107 callers
untouched)
- ipam._build_proxmox_client removed; its one call site uses from_server
- task_queue_service keeps its per-server cache pool, builds via from_server
- monitoring_worker keeps its ValueError-on-missing-auth contract, builds
via from_server
Behaviour preserved (token-first, then password; non-default port appended).
Verified: containers rebuild healthy, smoke test of both auth paths passes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Also drop the stray markdown code fences that wrapped the file and were
being treated as literal ignore patterns.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the /api/servers/auto-setup endpoint, the AutoSetupDialog UI and the
useAutoSetupServer hook. Rename the auto_setup locale strings to
auto_create_token. Also normalize the storages response to an array.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Align the frontend with the /logs API contract: the endpoint returns
{ logs: [...] } with a created_at field, not { items: [...] } / timestamp.
Add a Vite dev-proxy rule for /logs so the request reaches the backend.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Read-only card on the instance Settings tab surfacing the panel-stored config
(cores/memory/disk/network/cloud-init) via the saved-config endpoint.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an 'Auto-setup' dialog that onboards a Proxmox server by password and
lets the backend auto-create the API token (adds all nodes for a cluster).
Show a cluster/standalone badge with node count on the node detail page.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per-template Deploy button opens a quick-deploy dialog (prefilled from the
quick-deploy endpoint defaults) that creates a VM via /templates/api/deploy.
New 'Download CT template' dialog browses the node's appliance repository
(available-lxc-templates) and pulls a template to a vztmpl storage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the guest-agent exec-status polling loop into a shared _wait_exec_status
method reused by execute_command and execute_script. No behavior change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop dead route handlers that have an active replacement and zero callers
(frontend, backend, tests):
- create-lxc, create-lxc-smart -> superseded by POST /lxc/deploy
- clone-lxc -> superseded by container/{vmid}/clone
- {server_id}/lxc-templates -> duplicate of /lxc-templates/{server_id}
- dashboard/stats -> dashboard uses resources/all + alerts
- permissions (v1) -> superseded by permissions/v2
The identically-named ProxmoxClient/SecurityService methods are kept (they
back the surviving endpoints).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tasks page now shows the live Proxmox task log/status for UPID-backed tasks.
Instance Settings tab gains an admin-only 'Execute script' card that runs a
script in the guest via the QEMU agent and shows stdout/stderr/exit code.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface two previously-unused admin endpoints: assign/clear a VM's owner from
the instance Settings tab, and a /instances/snapshot-archives page listing
snapshots preserved from deleted guests (with config detail), linked from the
Instances header for admins.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New Storages tab in Backups: list cluster storages, add (dir/nfs/cifs/pbs
with type-specific fields), edit content/nodes, delete, and view native PVE
vzdump backup schedules — all over the previously-unused storage CRUD and
proxmox-jobs endpoints.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expand the Notifications settings tab: per-user preferences (channels,
critical-only email, Telegram chat id + verify, webhook, quiet hours),
SMTP/Telegram test buttons, a test-notification sender with channel
selection, channel status, and the configured Telegram bot username.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New /ipam/tools page surfacing the existing maintenance endpoints: summary
with recent activity, conflict detection, orphan allocations (with cleanup),
unlinked VMs (scan & link), auto-allocation + next-available lookup, and
per-IP history. Linked from the IPAM dashboard.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expand the About tab into a full update manager over the existing backend
endpoints: edit the update repository URL, check for updates (showing
changelog/errors), trigger an update with a strong confirmation, and show a
live progress banner with a reset action while an update runs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface the existing SDN backend endpoints in a new SDNManager panel on the
node detail page: zones (CRUD with type-specific fields), VNets (CRUD), and
per-VNet subnets (create/delete, optional IPAM network link), plus an apply
action with a pending-changes indicator and an availability notice.
Fix subnet deletion to pass PVE's full subnet id ({zone}-{network}-{mask})
instead of just the CIDR, which the API rejected.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface the existing HA backend endpoints (cluster HA status, add/remove
resource) in a new HAResources panel on the node detail page. Lists
HA-managed guests with state/group/restart limits, supports adding a guest
to HA (state, group, max_restart/relocate, comment) and removing it.
Shows a cluster-only notice on standalone nodes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>