Allows the shared column filter to be attached to typed VMInstance columns
without a FilterFn<unknown> assignability error.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend returns the live `lock` field (clone/create/migrate/...) and the
list shows an amber badge next to the status, so an instance that is
still being cloned no longer looks like a ready stopped VM.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>