Commit Graph

59 Commits

Author SHA1 Message Date
0f7c5a44df fix(metrics): move disk-fill chart up next to CPU and memory
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 21:57:52 +05:00
e90ad2e0d2 fix(metrics): keep previous series on NIC/range switch to avoid full-grid reload
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 21:57:52 +05:00
074983a1f6 fix(metrics): correct cpu/disk% chart scaling, evict stale collector state, lighten nic query, drop polling & dead RRD code
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 21:35:02 +05:00
4f224d90cf feat(metrics): graphs tab reads stored history with date range, NIC selector, IOPS & disk% 2026-06-21 21:35:02 +05:00
0aed32f998 feat(metrics): add useVMMetrics hook 2026-06-21 21:35:02 +05:00
df2c59eb3f chore: pre-existing WIP (overview/realtime/format/types/use-instances)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 21:35:02 +05:00
a4b99c2383 fix(instances): type multiSelectFilter as FilterFn<any> for column reuse
Some checks failed
Deploy to Production / Trigger production update (push) Failing after 10s
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>
2026-06-21 15:28:01 +05:00
5c6bb013c9 feat(instances): surface PVE lock state in the instances list
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 50s
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-21 00:38:41 +05:00
6b3700f496 feat(clone): richer clone dialog with node, storage and owner pickers
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>
2026-06-21 00:38:41 +05:00
8ebef3d10e feat(instances): add column filters and VM config formatter
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>
2026-06-21 00:38:14 +05:00
0d4406024f i18n(instances): translate settings tab labels and tidy field spacing
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-20 23:40:12 +05:00
a1aaa97b24 feat(backups): add search field to backup files and amber VM-picker checkboxes
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>
2026-06-20 23:40:12 +05:00
315aaed58b fix(instances): widen VM management dropdown so menu items fit on one line
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 23:40:12 +05:00
aa0ea459cd fix(snapshots): send required node param and add storage-support hint
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 49s
Deploy to Production / Trigger production update (push) Successful in 9s
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>
2026-06-20 23:35:42 +05:00
3cac5f6c2a fix(api-client): format FastAPI error detail instead of [object Object]
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>
2026-06-20 23:35:34 +05:00
14cac12191 feat(ui): replace all native confirm() dialogs with styled ConfirmDialog
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Add ConfirmDialogProvider + useConfirm hook (Promise-based API) so every
window.confirm() in the app is replaced with a consistent themed modal.

Replaced in 11 files (16 call-sites):
- Settings: update panel action
- Templates: delete template
- Storages: delete storage
- SSH Keys: delete key
- Nodes: delete server
- NodeNetworks: delete interface, apply pending, revert pending
- HAResources: remove HA resource
- SDNManager: apply SDN, delete zone/vnet, delete subnet
- IPAM: release allocation, delete pool, cleanup orphans

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 09:09:26 +05:00
00cbe9716b fix(settings): remove unimplemented Webhook URL field from notifications
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-20 08:53:40 +05:00
cc2bb349e5 fix(settings): notifications/profile form UX fixes
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 48s
Deploy to Production / Trigger production update (push) Successful in 8s
- 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>
2026-06-20 08:47:37 +05:00
9ced08b88c feat(settings): per-user language preference and panel improvements
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>
2026-06-20 08:47:18 +05:00
4451b3e45a fix(settings): align SMTP/security settings fields with API
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 46s
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-20 08:26:39 +05:00
a507e3c4bc feat(metrics): real-time VM disk fill, IOPS and network I/O
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>
2026-06-20 08:26:29 +05:00
965fb858da fix(ipam): require resource name before allocating IP and fill missing fields on VM link
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 46s
Deploy to Production / Trigger production update (push) Successful in 8s
- 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>
2026-06-20 03:23:57 +05:00
7546883393 feat(dashboard): show top 10 loaded running instances by CPU
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 02:59:43 +05:00
64924e50ed fix(instances): persist server filter selection across navigation and page reload
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 02:53:45 +05:00
5b781f9e16 fix(ipam): show VM id/name/IP in IP map tooltip
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-20 02:27:04 +05:00
14a6f5ace7 feat(ipam): expose network/pool/allocation management in UI
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
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>
2026-06-20 02:12:40 +05:00
f18ba4d597 revert(nodes): remove server auto-setup feature
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m35s
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-19 22:18:38 +05:00
493814f44f fix(dashboard): populate recent-activity feed from audit logs
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>
2026-06-19 22:18:30 +05:00
ed4ff6576a feat(instances): show saved VM configuration on the Settings tab
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 10s
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>
2026-06-15 00:30:44 +05:00
bb5d30ab68 feat(nodes): add server auto-setup and cluster-info badge
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>
2026-06-15 00:30:44 +05:00
5d6acd619e feat(templates): add quick-deploy and CT template download
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>
2026-06-15 00:29:34 +05:00
2886326353 feat(instances,tasks): add PVE task log viewer and VM script execution
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 52s
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>
2026-06-14 19:30:55 +05:00
bc462c9f8e feat(instances): add VM owner assignment and snapshot archive view
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-14 18:55:47 +05:00
dc95d39465 feat(backups): add storage management tab
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-14 18:48:35 +05:00
e79f9ea24c feat(settings): add notification preferences and channel tests
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
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>
2026-06-13 22:35:27 +05:00
fdd3e03c7d feat(ipam): add IPAM tools page
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>
2026-06-13 22:35:27 +05:00
fb1267c533 feat(settings): add panel update management UI
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 10s
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>
2026-06-13 22:18:08 +05:00
179cb615f3 feat(nodes): add SDN management UI
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
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>
2026-06-13 22:14:01 +05:00
14aeba41d0 feat(nodes): add High Availability management UI
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 13s
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>
2026-06-13 21:38:21 +05:00
681aa2f303 feat(backups): restore target node/storage selection + task progress tracking
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m6s
Deploy to Production / Trigger production update (push) Successful in 8s
Add target node and storage overrides to single and bulk restore flows, and
track Proxmox task progress (parse_task_progress in the monitoring worker,
new ProxmoxTask progress column + migration, enriched task API responses).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 21:26:01 +05:00
fbf6d174b6 feat(nodes): add node network interface management UI
Wire up the existing node-network backend endpoints (list/create/update/
delete + apply/revert staged config) to a new NodeNetworks component on the
node detail page. Supports bridge/bond/vlan/eth interface types with
type-specific fields and surfaces IPAM linkage.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 21:25:51 +05:00
2e8558fa51 fix(backend): restore operations — add force param, fix QEMU restore API
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Failing after 47s
- restore_vm/restore_lxc: add force=True param (needed for in-place overwrite)
- QEMU restore: remove `restore: 1` from params (breaks Proxmox API — restore
  is triggered by archive presence alone, unlike LXC where restore: 1 required).
  This fixes both single and bulk QEMU restores.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 16:32:23 +05:00
82a6e0e24a fix(frontend): IPAM translations, dialog width cap, workspace counts 2026-06-13 08:45:31 +05:00
8659ba5a92 feat(frontend): cluster management page (create / join wizard / eject)
Surface the existing backend cluster API in the UI:
- New /cluster page with topology view (clusters + standalone servers),
  per-node online status, and a 2-node quorum warning.
- Create cluster dialog (node, name with Proxmox naming rules, optional
  corosync link0, optional root password).
- 3-step Join wizard: pick joining + target node → pre-join-check with
  backup-and-clear (prepare-join) for nodes that still hold guests →
  confirm + join with the node root password.
- Eject node dialog (with SSH-fallback root password).
- hooks/use-cluster.ts: typed useClusterTopology, useCreateCluster,
  usePreJoinCheck, usePrepareJoin, useJoinCluster, useEjectNode.
- Nav item + route + RU/EN i18n strings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 07:16:48 +05:00
0e85d56c99 fix(frontend): constrain auto-import dialog width and rename duplicate filter label
- TemplatesPage: cap auto-import dialog at sm:max-w-md so it no longer
  spans the full screen (bare DialogContent defaults to near-full width).
- InstancesPage: the server (multi-server/cluster) filter wrongly reused
  the `instances.all_nodes` i18n key, so it rendered "Все узлы" identically
  to the node filter. Add a dedicated `instances.all_servers` key (RU/EN)
  and use it, so the two filters read "Все серверы" / "Все узлы".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 06:44:23 +05:00
50f2ee1966 fix(security): authenticate VNC/terminal WebSockets and harden SSH/config
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Failing after 46s
Critical security and robustness fixes from a code audit:

- WS terminal/VNC now require a JWT (?token=), validate the session,
  vms.console permission and VM ownership before bridging to Proxmox
  (previously the LXC terminal gave unauthenticated root shell access).
  Frontend ConsolePage passes the token in both WS URLs.
- Fix SSH fallback for `pvecm delnode`: SSHClient now supports password
  auth (it previously crashed with TypeError); ProxmoxClient stores the
  password for SSH fallbacks and the host port suffix is stripped.
- Add production startup warnings for default ADMIN_PASSWORD and wildcard
  CORS_ORIGINS.
- dashboard: use tz-aware utcnow() instead of naive datetime.utcnow().
- crypto: narrow decrypt_value except to InvalidToken and log failures.
- ssh_client: guard the shared connection cache with a lock; make
  unknown-host-key rejection opt-in via SSH_REJECT_UNKNOWN_HOSTS.
- logging: send loguru console output to stderr instead of stdout.
- Sync version fallback to 1.5.1; remove one-off refactor scripts.
- Add CODE_REVIEW.md audit report.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 06:31:26 +05:00
08a687c1f6 feat(frontend): add LogsPage with stats, filters and pagination
- New LogsPage.tsx under features/logs/ (was referenced by router but missing)
- Uses existing useLogs / useLogStats / useLogLevels hooks
- Stats cards (24h total, errors, failed logins, page count)
- Search + level filter + pagination wired to /logs/api/logs
- i18n strings, lucide icons, shadcn UI primitives

Fix frontend/.gitignore: '/logs' was matching 'features/logs/' (rolldown-vite
import resolution would have kept failing on CI otherwise). Scope the rule
to the project root.
2026-06-04 03:01:22 +05:00
markmorado
453c18f192 feat: real-time server CRUD sync and pve CLI auto-install
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
Backend:
- servers.py: instant connectivity check + VM cache sync after create/update;
  broadcast server_added/updated/deleted events via WebSocket
- websocket_manager: add broadcast_event() helper for global fire-and-forget events

Frontend:
- use-nodes: invalidate topology, VM list and resources after server create/update/delete
- use-realtime-sync: new hook with useGlobalRealtimeSync subscribing to server_*
  WS events and invalidating relevant React Query caches
- AppLayout: mount useGlobalRealtimeSync globally

Deploy:
- deploy.sh: auto-install pve CLI during main/quick deploy (idempotent, --auto mode)
2026-05-11 05:31:52 +02:00
markmorado
742ff27fb4 fix(frontend): explicit .tsx extensions for lazy imports (rolldown-vite 8.0.5 bug)
- Replace dynamic import('@/...') with relative './features/.../File.tsx' in router.tsx
  to work around UNLOADABLE_DEPENDENCY error from rolldown resolver in vite 8.0.5
  which fails to auto-append .tsx for dynamic imports using path aliases.

fix(deploy): make deploy.sh resilient to common build/runtime failures

- Enable pipefail
- build_images_resilient(): retry docker compose build with --no-cache after first failure
- check_stale_db_volume(): warn when reusing an old Postgres volume whose password
  no longer matches a freshly generated .env (typical 'backend in restart loop' cause)
- Add --reset-data flag (combinable with any mode) to wipe the old Postgres volume
- Document new flag in --help
2026-05-11 05:17:03 +02:00
markmorado
4a98a26d3c fix: fix CentOS logo shape and AlmaLinux 9 detection
- Replace CentOS triangle polygons with proper 4-quadrant rectangles
- Add 'alama' key to catch 'Alamalinux' typo variant in VM names

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-10 22:23:03 +02:00