Commit Graph

229 Commits

Author SHA1 Message Date
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
23c29dacc9 ci: add production deploy workflow
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Triggers update watchdog on production server via SSH on every push to main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 19:13:46 +05:00
49f888d4e2 fix(monitoring): break infinite loop on invalid UPID parsing
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 47s
When Proxmox API returns 400 "unable to parse worker upid", the monitoring
worker was getting empty status {}, treating it as running, and retrying
forever every 5 seconds, causing 100% CPU and log spam.

Now when get_task_status() returns empty dict, we immediately mark the task
as failed with exit_status="Invalid UPID" and move on instead of looping.

Fixes production deployment hang.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-13 19:04:26 +05:00
9dd992c6b9 fix(security): enforce VM access control on status endpoints; fix CI artifact upload
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
- get_vm_status and get_container_status were missing require_vm_access(),
  allowing any user with vms.view to see any VM status regardless of ownership.
  Now users with vms.view.own can only access their own VMs (403 otherwise).
- Downgrade upload-artifact@v4 → @v3: v4 is not supported on Gitea (GHES)
  and caused CI failures on every run.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-13 18:58:15 +05:00
fd592f8b59 fix(api): add missing ssh_keys router import
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Failing after 46s
The ssh_keys module was imported in main.py but missing from api/__init__.py,
potentially causing import issues. Added to ensure all API routers are
explicitly declared and available.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-13 18:53:13 +05:00
5d3f3c2b3b fix(docker): include migrations directory in backend image
The migrations/ directory was missing from the Dockerfile COPY instructions,
causing ModuleNotFoundError when app.main tries to import and run migrations
during startup. This caused production deployments to fail with:
  ModuleNotFoundError: No module named 'migrations'

The automatic migration runner in main.py (line 157) needs this directory to:
1. Detect database schema changes
2. Run pending migrations
3. Initialize default admin user

Fixes production deployment failure when containers start.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-06-13 18:52:06 +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
bfd92102cf Refactor backend: Split models and proxmox_client into modules, add alembic
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Failing after 2m27s
2026-06-13 03:53:27 +05:00
8a879f36fa release: v1.5.1
- Bump VERSION and README badge to 1.5.1
- WIKI: add new 'Logs & Audit' section (page layout, levels, API,
  query params, response shape, RBAC, retention) and bump version
  in the top note; also extend ToC
- CHANGELOG / CHANGELOG.ru: add v1.5.1 entry covering the missing
  LogsPage component fix and the .gitignore collision fix
2026-06-04 03:14:38 +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
markmorado
4ba39858c5 feat: add OS logo component for templates and instances
- Add OsLogo component with SVG icons for major distros (Ubuntu, Debian, etc.)
- Integrate OsLogo in TemplatesPage, CreateInstanceWizard, InstanceDetailPage

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-10 22:13:39 +02:00
markmorado
c317c4d81a fix: deduplicate SSH keys on LXC/VM create; filter qemu templates in wizard
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
2026-05-08 13:06:23 +02:00
markmorado
5cb186e8d1 docs: update tech stack — React 19 / TypeScript / Vite / Tailwind / Recharts 2026-05-07 00:42:06 +02:00
markmorado
0743dee005 docs: bump version to 1.5.0, update CHANGELOG, README, WIKI 2026-05-07 00:40:27 +02:00
markmorado
323d1e57fa feat: SSH keys management, backups fixes, instances/nodes/templates improvements, dev mode support
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
2026-05-07 00:30:21 +02:00
markmorado
a92cb0df33 fix(vms): auto-stop running VM/CT before destroy
The destroy endpoints returned 400 'Cannot delete a running container.
Stop it first.' when the user clicked Destroy on a running instance.
Since the destroy dialog already requires typing the instance name to
confirm, the action is unambiguously intentional — now both endpoints
issue stop_container/stop_vm with force=True, wait up to 15s for the
status to leave 'running', and only then proceed with deletion.
2026-05-06 21:11:15 +02:00
markmorado
9da65a46aa fix(lxc): preserve credentials and IP across reinstall
Three related fixes so login/password/SSH key/IP survive a reinstall:

1. backend/app/api/proxmox/lxc.py — on initial LXC deploy save
   cloud_init_user='root' and cloud_init_password=req.password to VMInstance
   (previously both were None, so reinstall could not restore root password).

2. backend/app/api/proxmox/async_ops.py — _do_reinstall_sync passes
   cached.cloud_init_password to create_lxc_container so the new container
   gets the same root password as the original.

3. backend/app/workers/monitoring_worker.py — VM sync worker no longer
   overwrites VMInstance.ip_address with NULL when no IPAM allocation
   exists for that (server_id, vmid). It only updates the field when
   IPAM has a value, otherwise the IP saved at deploy/wizard time is
   preserved.
2026-05-06 20:22:50 +02:00
markmorado
aba2eb3583 feat(lxc): support reinstall for LXC created from CT template file
Previously the reinstall endpoint required cached.template_id (clone-from-VM-
template flow), so LXC instances created via the wizard from an OS template
file (e.g. local:vztmpl/debian-13-...tar.zst) returned 'VM has no associated
template; reinstall is not available'.

Now reinstall works in two modes:
  1) clone-from-template (existing): VM/LXC with cached.template_id pointing
     to OSTemplate.vmid
  2) ostemplate-file (new, LXC only): cached.template_name like
     'storage:vztmpl/...tar.zst'. Reinstall stops, deletes, then re-creates
     the container with the same VMID using create_lxc_container, preserving
     network config, storage, rootfs size, swap, features, ssh_keys, etc.
     pulled from the previous container config + VMInstance cache.
2026-05-06 20:11:05 +02:00
markmorado
daeddbc6c7 fix(lxc): enable nesting=1 by default for systemd 255+ compat
Ubuntu 24.04 / Debian 13 ship with systemd >= 255 which requires
features=nesting=1 in unprivileged LXC containers. Without it,
container start emits 'WARN: Systemd 255 detected. You may need
to enable nesting.' Now nesting is enabled by default unless the
caller explicitly passes a 'features' string.
2026-05-06 20:03:22 +02:00
markmorado
5d905361b6 fix(lxc): remove double URL-encoding of SSH public keys
proxmoxer URL-encodes parameters automatically. The extra urllib.parse.quote()
call was double-encoding SSH keys, causing Proxmox to reject them with
'500 Internal Server Error: SSH public key validation error'.

Now passes the SSH key as-is (only stripped of whitespace), letting proxmoxer
handle encoding.
2026-05-06 19:55:25 +02:00
markmorado
1cf099ba1d feat: LXC container creation from CT templates
- Add LXC deploy API endpoints: GET /proxmox/api/lxc-templates/{id},
  GET /proxmox/api/lxc-storages/{id}, POST /proxmox/api/lxc/deploy
- Add ProxmoxClient.get_lxc_storage_templates() and get_node_storages()
- Fix duplicate create_lxc_container() — removed dead copy, updated
  canonical with nameserver/searchdomain params
- Fix wait_for_task(): accept WARNINGS:N exitstatus as success
- Add IPAM IP release on deploy failure
- Add frontend hooks: useLXCTemplates, useLXCStorages, useDeployLXC
  with 5-min staleTime caching
- Add LXC wizard steps to CreateInstanceWizard (type, template, config)
- Add LXC i18n keys to en.json and ru.json
- Add LXCTemplate and LXCDeployRequest TypeScript interfaces
2026-05-06 19:17:04 +02:00
markmorado
adcc86f30a fix: исправления и улучшения от 30.04.2026
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Has been cancelled
- Обновлён backend/Dockerfile и frontend/Dockerfile
- Исправлен async_ops.py (новые асинхронные операции)
- Обновлён config.py
- Исправлены compose.yml и compose.prod.yml
- Обновлён deploy.sh
- Переименованы nginx-конфиги (serverpanel → pvemanager)
- Улучшены InstanceActionDialogs, InstanceDetailPage, InstancesPage
- Обновлён AppLayout.tsx
- Исправлен init.sql
- Обновлён frontend/nginx.conf и package.json
2026-04-30 21:58:44 +02:00
markmorado
79d6864d43 feat(vm-ops): make reinstall/clone/change-password async via DeployTask
Backend:
- Add DeployTask.kind column ('deploy'|'reinstall'|'clone'|'change_password')
  + Migration 23: ALTER TABLE deploy_tasks ADD kind, drop NOT NULL on template_id
- Update DeployTask.to_dict() with kind-aware Russian descriptions
- New backend/app/api/proxmox/async_ops.py with three workers:
    _do_reinstall_sync, _do_clone_sync, _do_change_password_sync
  All run on shared _deploy_executor thread pool from templates.py and
  report progress through _update_deploy_task (DB + WebSocket broadcast)
- Rewrite five vms.py endpoints to return 202 + DeployTaskStartResponse:
    POST /vm/{vmid}/clone, /container/{vmid}/clone,
    POST /vm/{vmid}/reinstall,
    POST /vm/{vmid}/change-password, /container/{vmid}/change-password

Frontend:
- DeployTask: add 'kind' and 'server_id' fields
- useCloneInstance/useReinstallInstance/useChangePassword now return
  AsyncTaskResponse {task_id, status, name}; remove invalidateQueries
- InstanceActionDialogs: each onSuccess pushes task to deploy-tasks-store
  with appropriate kind, shows 'launched in background' toast
- InstancesPage:
  * ghostRows only for kind in {deploy, clone}, deduped by (server_id, vmid)
  * reinstall / change_password tasks shown as inline overlay (badge + ring)
    on the existing VM row's status column
2026-04-30 00:08:41 +02:00
markmorado
89d70654fc fix(reinstall): use OSTemplate.vmid (not template_vmid) and convert memory bytes->MB
- AttributeError: OSTemplate has no 'template_vmid' field; the actual column is 'vmid'.
- Use OSTemplate.get_vmid_for_node() to support cross-node replicated templates,
  falling back to source_node/vmid otherwise.
- VMInstance.memory is stored in bytes, but Proxmox config expects MB.
2026-04-29 23:48:48 +02:00
markmorado
5169bf80a3 fix: resolve FastAPI route ordering conflict for clone/reinstall/change-password
Specific endpoints (clone, reinstall, change-password) were being intercepted
by the generic /{action} handler because they were registered AFTER it.

Fix: move CloneRequest, ChangePasswordRequest models, _resolve_server,
_get_client_or_503 helpers, and all 5 specific endpoint functions BEFORE
the generic @router.post('.../{action}') handlers.

Remove duplicate definitions from the old 'Additional Instance Operations'
section at the end of the file.
2026-04-29 23:00:33 +02:00
markmorado
bba66d2d2c fix: add missing action mappings for reinstall and change-password in LoggingService
- Added 'reinstall': 'reinstalled' mapping in action_messages
- Added 'change-password': 'password changed' mapping in action_messages
- Fixes HTTP 400 Invalid action error for new VM/LXC operations
- All operations now properly logged to audit_logs table

Related operations:
- POST /api/{server_id}/vm/{vmid}/reinstall
- POST /api/{server_id}/vm/{vmid}/change-password
- POST /api/{server_id}/container/{vmid}/change-password

Adds:
- BUGFIX_REPORT.md - detailed bug analysis and fix
- TEST_NEW_OPERATIONS.md - operation documentation
- test_new_operations.py - verification script
2026-04-29 22:37:52 +02:00
markmorado
ae41dacd0e fix: improve pve start/restart commands with container readiness wait
- Add wait_for_containers() function that checks container health status
- Commands now wait up to 120 seconds for all containers to become healthy
- Improved error handling with better error messages
- Frontend container waits for app healthcheck before starting
- Users see clear progress messages instead of hanging indefinitely
- Fixes pve start and pve restart hanging issues
2026-04-29 22:25:11 +02:00
markmorado
297082dc72 feat: improve nodes, workspaces, settings pages; add favicon and logo; update locales 2026-04-29 16:38:32 +02:00
markmorado
1d08c815a7 fix: frontend-backend integration — 14 issues resolved
- nginx: add proxy routes for /settings/, /templates/, /ipam/, /logs/, /admin/, /health
- dashboard: fix data format mismatch (servers[] not nodes[]/vms[])
- dashboard: add WebSocket subscription to dashboard_metrics for real-time updates
- dashboard: connect activity feed to /logs/api/logs endpoint
- dashboard: reduce polling to 15s with WS as primary update source
- graphs: fix rrddata response unwrap (backend returns {data:[],timeframe:''})
- graphs: add i18n translations for chart titles
- console: add xterm.js CSS import for proper terminal rendering
- console: add i18n translations (connecting, reconnect)
- workspace: add switcher dropdown in TopBar
- workspace: add edit dialog in WorkspacesPage
- workspace: create Zustand store with localStorage persistence
- workspace: add X-Active-Workspace header to API client
- sidebar: replace generic icon with actual favicon.svg logo
- instances: translate RowActionMenu and InstanceDetailPage strings
- locales: add graphs, console, workspace, instance tab keys to en/ru
2026-04-07 00:46:04 +02:00
markmorado
4546a798d0 v1.4.0: Networks page — SDN zone/vnet editing, node interfaces CRUD, IPAM auto-create 2026-04-06 21:13:38 +02:00
markmorado
6a0564cea2 v1.3.1: VM list node/server filtering + responsive toolbar redesign
- Add server filter dropdown (populated dynamically from loaded VMs)
- Add node filter dropdown (narrows to nodes of selected server)
- Both filters persisted in URL params and restored on reload
- Toolbar restructured into 2 rows: filters row + actions row
- Responsive breakpoints: ≤900px text labels hidden, ≤768px 2-per-row,
  ≤480px full-width filters, stats hidden on mobile
- Snapshots toolbar migrated to inline flex (no legacy class dependency)
- Update VERSION, CHANGELOG, README, WIKI to v1.3.1
2026-04-05 21:47:16 +02:00
markmorado
abeb8d53a3 chore: release v1.3.0
- VERSION: 1.2.0 → 1.3.0
- CHANGELOG: add v1.3.0 section (VNC & Terminal fixes)
- README: update version badge to 1.3.0
- WIKI: bump version header, expand Console section (VNC/xterm.js),
  update VNC troubleshooting section
2026-03-27 21:36:21 +01:00
markmorado
29f1255705 feat: use xterm.js terminal for LXC containers in VM list context menu
- Context menu now shows Terminal (xterm.js) for lxc type and VNC Console for qemu
- Added openTerminalConsole() / connectTerminalConsole() / closeTerminalModal() functions
- Added terminalModal HTML alongside existing vncModal
- Backend endpoints /api/{server_id}/container/{vmid}/terminal and
  /proxmox/ws/terminal/{server_id}/{node}/{vmid} already existed and are ready
2026-03-27 21:22:27 +01:00
markmorado
32acd74b38 fix: LXC vncproxy - generate-password unsupported, use ticket as VNCAuth password 2026-03-27 21:10:49 +01:00
markmorado
c189dab5e9 fix: VNC auth - add generate-password:1 to vncproxy, fallback to ticket
Root cause of 'Connection closed' / VNCAuth failure:
- vncproxy was called without generate-password=1
- vnc_data.password was None → noVNC sent empty DES-encrypted challenge → Proxmox rejected

Fix:
- Add generate-password=1 to both qemu and lxc vncproxy requests
- If Proxmox returns password field (Proxmox 8.x VNCAuth): use it
- If not (Proxmox 9.x NoAuth): fall back to ticket as password
- Add diagnostic logging (password_len, has_generate_password)
2026-03-27 21:08:40 +01:00
markmorado
cd48c839f8 fix: VNC - pass URL directly to noVNC instead of existing WebSocket
Remove the 'onFirstMessage' hack where backend sent VNC password as
first text WebSocket message and frontend passed the already-open WS
to noVNC's RFBClass. This caused RFB handshake failures because noVNC
couldn't properly manage a WebSocket it didn't create.

Changes:
- Backend: remove send_text(password) before proxy start
- Backend: improve proxy error logging from debug to info level
- Frontend (virtual_machines.html, instance_detail.html): pass WebSocket
  URL string to RFBClass constructor - noVNC creates and manages its own
  WebSocket connection, allowing proper RFB protocol handshake
2026-03-27 20:57:04 +01:00
markmorado
06ea2b5bd4 fix: add keep_last param to backup API and fix notes-template field name 2026-03-22 20:07:50 +01:00