Commit Graph

399 Commits

Author SHA1 Message Date
markmorado
bec7b20e31 feat(auth): двухфакторная аутентификация (TOTP) для входа в панель
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 58s
Deploy to Production / Trigger production update (push) Successful in 8s
Бэкенд:
- two_factor_service: генерация секрета, otpauth-URI, QR как inline-SVG,
  одноразовые backup-коды (хранятся как SHA-256)
- эндпоинты /api/auth/2fa/{status,setup,enable,disable}; гейт 2FA в login
  (неверный код -> 400, чтобы SPA не сбрасывала форму); two_factor_enabled в /me
- админский сброс: POST /api/users/{id}/disable-2fa
- модель/схемы/init.sql + идемпотентная миграция №30 (two_factor_backup_codes)
- зависимости: pyotp, qrcode

Фронтенд:
- двухшаговый вход с полем кода (TOTP/backup)
- карточка 2FA в профиле: QR, проверка, backup-коды, отключение
- бейдж/сброс 2FA в списке пользователей; локали ru/en

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 21:08:38 +05:00
markmorado
fc42e8fc19 feat(nodes): показывать версию PVE, рабочие области и аптайм на карточках узлов
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 57s
Deploy to Production / Trigger production update (push) Successful in 8s
Карточки на странице «Узлы» дополнены важной информацией:
- версия Proxmox VE (чип «PVE x.y.z»);
- число нод в кластере (для кластерных серверов);
- аптайм узла;
- чипы рабочих областей, в которых состоит сервер.

Бэкенд: эндпоинт /api/{id}/nodes отдаёт version; ответ серверов
дополнен полями cluster_name и workspaces (ServerWorkspaceBrief).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 18:37:28 +05:00
markmorado
476b73b411 docs(metrics): актуализировать комментарии интервалов брокера
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m2s
Deploy to Production / Trigger production update (push) Successful in 8s
Реальные интервалы циклов: dashboard 2с, server 2с, instance 1с.
В комментариях было устаревшее 10с/5с. Логику не меняем — дашборд
уже обновляется раз в 2 секунды.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 18:30:56 +05:00
markmorado
b9e5ef9426 fix(dashboard): не обнулять узлы кластера при REST-рефетче и сбоях WS
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Successful in 56s
Deploy to Production / Trigger production update (push) Failing after 9s
Данные по узлам (nodes) приходят только из WebSocket dashboard_metrics,
а REST /api/resources/all их не содержит. Каждый 15-секундный рефетч REST
затирал ноды -> таблица узлов и счётчик обнулялись, WS возвращал через 2с.

- frontend: при REST-рефетче переносим последние известные nodes из кэша,
  чтобы node-таблица не мигала
- backend: кэш последнего удачного опроса по каждому серверу
  (_server_last_good) — транзиентный таймаут Proxmox больше не отдаёт
  пустые vms/containers/nodes

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 00:56:08 +05:00
markmorado
d4c5c6110a fix(dashboard): устранить мигание показаний и поток ошибок 422
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Successful in 58s
Deploy to Production / Trigger production update (push) Failing after 10s
- поднять лимит /proxmox/api/all-tasks до 500 (дашборд запрашивал limit=500
  при потолке le=200, что давало 422 каждые 5с)
- обработчик WS dashboard_metrics больше не затирает кэш пустыми/частичными
  тиками: игнорирует пустые сводки и сохраняет последние валидные
  nodes/vms/containers при транзиентном сбое Proxmox

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 00:49:54 +05:00
c0296e47b8 Merge pull request 'feat(ui): design polish — semantic status tokens, self-hosted fonts, a11y, skeletons' (#1) from ui/design-polish into main
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Reviewed-on: #1
2026-07-04 06:42:06 +05:00
markmorado
49e976c0c0 feat(ui): design polish — semantic status tokens, self-hosted fonts, a11y, skeletons
Design system & theme:
- add semantic status tokens (success/warning/danger + track) for both themes
- replace hardcoded green/red/amber/blue across ~20 files with tokens
- fix light-mode bugs (bg-white/10, rgba white gauges) via theme-aware track
- add named text-2xs (11px) step; unify ad-hoc text-[10px]/[11px]
- consistent card elevation (shadow-sm) + opt-in interactive hover

Fonts & perf:
- self-host DM Sans / JetBrains Mono via @fontsource-variable (font-display: swap)
- drop render-blocking Google Fonts link; remove unused Geist dep

Accessibility & mobile:
- global prefers-reduced-motion; focus-visible on custom buttons
- StatusDot role/aria-label; aria-sort on sortable table headers
- Button auto nativeButton=false when rendered as Link/anchor
- 100vh -> dvh in app shell; pointer-coarse min 44px touch targets

Loading & types:
- Skeleton primitive + table loading state on InstancesPage
- fix all 36 pre-existing tsc errors (Select null coercion, SDN query keys,
  Dashboard Rec typing, VMInstance, profile language, JSX namespace)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 06:40:48 +05:00
markmorado
00e36e1cc6 feat: Proxmox management suite — hardware, firewall, pools, disks, storage, access, node admin
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 54s
Deploy to Production / Trigger production update (push) Successful in 7s
- VM/LXC hardware editor with PCI/USB passthrough (BIOS/OVMF + efidisk,
  machine type, VGA, SCSI controller, CPU sockets); passthrough locked while running
- Firewall at datacenter/node/VM levels: rules, security groups, IP sets,
  aliases, options, log — with rule dialog referencing security groups
- Resource pools (CRUD + membership) and per-instance tags editor
- Node disks: physical disk list, SMART viewer, ZFS pool create/destroy, wipe
- Storage: add LVM/LVM-thin/ZFS/RBD/CephFS types + enable/disable toggle
- PVE Access: API tokens (create with one-time secret, delete) and realms (LDAP/AD/OpenID)
- Node admin: systemd services (start/stop/restart), APT updates & repositories
- Shared: SelectTrigger defaults to full width (fixes narrow dropdowns)

Also bundles related in-progress work: auth screen refresh, node shell console
page, server-updates badge, and node:*/access:* RBAC permissions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 05:40:52 +05:00
markmorado
5c8baefb3f feat: add firewall, pools, access, disks, node admin and VM hardware management
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m0s
Deploy to Production / Trigger production update (push) Successful in 7s
Backend: new proxmox mixins and API routes for firewall, pools, access
control, node admin and disks; extend storage and VM endpoints.

Frontend: node managers (firewall, pool, access, disk, node admin), VM
firewall and hardware tabs, PCI/USB device dialogs, related hooks and
locale strings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 00:02:15 +05:00
markmorado
c12fbf13e5 feat(instances): add VM/LXC migration, autostart/boot order, protection
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 52s
Deploy to Production / Trigger production update (push) Successful in 7s
- Migrate VMs/LXCs between cluster nodes with live progress tracking
- Configure autostart, boot order, startup/shutdown delays, and delete protection from the instance settings tab
- Group OS templates by detected OS (Ubuntu, AlmaLinux, etc.) instead of a single "Cloud Images" bucket
- Expand native Proxmox backup job management (schedule, compression, retention, guest selection, notifications)
- Add ru/en translations for the above
2026-07-03 02:40:58 +05:00
e8bce3e8ae fix(sdn): full-width selects in zone/vnet dialogs
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 03:08:41 +05:00
d3fbdb1ff5 fix(sdn): zone DNS is an SDN DNS entry id, not an IP — use select
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 52s
Deploy to Production / Trigger production update (push) Successful in 8s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 03:05:06 +05:00
91080d8574 feat(api): expose SDN DNS server entries
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 03:05:06 +05:00
87eb573cbd feat(instances): offer SDN vnets as bridges in add-NIC dialog
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 52s
Deploy to Production / Trigger production update (push) Successful in 8s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:57:22 +05:00
2dff39ada0 feat(api): include SDN vnets in node networks listing
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:57:22 +05:00
613015cf05 fix(instances): keep table page across live metric updates
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
Live WS metrics replace the table data every second, and TanStack
Table's default autoResetPageIndex snapped the list back to page 1.
Disable the auto reset and go back to page 1 only when search or
filters change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:44:39 +05:00
7e1580579d feat(instances): show bridge comments in add-NIC dropdown
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 9s
Bridge selector now shows the Proxmox interface comment (WAN, Cisco,
subnet, ...) next to the bridge name, like the native Proxmox dialog,
falling back to IPAM/interface CIDR; list sorted by name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:42:44 +05:00
052f9afb65 feat(instances): add/remove network interface from Networking tab
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m28s
Deploy to Production / Trigger production update (push) Successful in 8s
- AddNetworkInterfaceDialog: bridge dropdown (node networks), model
  select for VM, VLAN tag, firewall, optional MAC; LXC extras: eth name,
  dhcp/static IP with CIDR + gateway; picks next free netN slot
- NetworkingTab: Add interface button, per-NIC delete with confirmation
  (config.put delete=netN)
- new useNodeNetworks hook; netif i18n keys (en/ru)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:36:20 +05:00
161182b392 feat(api): support netN add/remove in VM and LXC config updates
- update_vm_config: whitelist netN/scsiN/virtioN/ideN/sataN/ipconfigN by
  regex instead of hardcoded 0-3; accept validated delete='netN' key;
  raise with real Proxmox error text instead of returning False
- update_container_config: refactor to dict signature with whitelist +
  netN + delete (fixes LXC config PUT endpoint that passed the whole
  dict as hostname)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:32:21 +05:00
7d52297f76 fix(deploy): apply VM config reliably after clone
- wait for clone lock release before config.put (cross-node clones kept
  lock past wait_for_task, dropping ALL requested settings silently)
- configure_vm applies params in independent groups (compute/network/
  cloudinit/disk) with per-group errors and lock retry
- set sockets=1 with cores so total vCPU matches request
- keep template net0 model/MAC/options, replace only bridge
- disk resize: pick boot disk via regex over all buses, report failures
- surface config errors as deploy warnings in UI toast instead of
  silent success

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 02:31:21 +05:00
e366646257 fix(deploy): cacheable build in update watchdog + auto-prune
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Watchdog rebuilt images with --no-cache on every push, writing fresh
build-cache layers that were never reused. Over ~2 weeks this grew the
Docker build cache to 57GB and filled the production disk.

- Switch `build --no-cache` to `build --pull` (cacheable). Dockerfiles
  already isolate heavy layers (apt/pip/npm) from source COPY, so app/
  frontend changes are still rebuilt — without re-running apt/pip/npm.
- Add `docker image prune` + `docker builder prune until=24h` after a
  successful deploy so old images and stale cache don't accumulate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 20:09:17 +05:00
3622747371 fix(dashboard): make donut tooltip readable
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
Theme tokens are oklch(); wrapping them in hsl(var(--card)) produced an
invalid, transparent tooltip background so the label blended into the
card. Use the oklch vars directly and force readable text colour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 19:48:58 +05:00
daa75e1502 feat(dashboard): show top disk stats as a donut chart
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Replace the disk I/O area chart with a donut where each slice is a node
sized by its disk usage % (disk_pct). More meaningful than I/O, which is
near-zero most of the time. Use real node names (name|node) in the legend
instead of node-0/node-1, and drop the now-unused RRD fetch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 19:41:54 +05:00
381e7ae821 i18n(instances): localize bulk operation toolbar buttons
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
Translate Start/Stop/Delete/Clear and the selected-count label in the bulk
actions toolbar (add instances.selected_count key). Also includes node label
display in the node filter/table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 19:02:11 +05:00
1f9a51b0be fix(dashboard): render disk chart; show server name as node label
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
- Dashboard "ТОП статистика по диску" was stuck on "Загрузка...": the
  node name in the dashboard_metrics WS payload is `name`, not `node`, so
  the RRD query stayed disabled. Use name fallback and unwrap the
  {data:[...]} response shape.
- Instances list + detail page: show the panel-side server name (from the
  add-server form) in the "Узел" column/label instead of the Proxmox node
  hostname. Real node is still used for all API calls.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:56:27 +05:00
fd47241394 feat(instances): bulk restart action and live bulk-operation status tracking
Add a Restart button to the bulk-selection toolbar (backend already supports
bulk_restart) and track bulk operation progress like instance creation:
per-row status overlay on affected instances plus a progress bar driven by
task_update WebSocket events.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:56:20 +05:00
1d1bd33e03 fix(instances): show RAM in correct units (MiB to bytes) in config
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
VM config `memory` is in MiB but formatBytes treated it as bytes,
rendering "2 KB RAM" instead of "2 GB RAM". Convert before formatting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 18:47:47 +05:00
9b1000ba76 docs: document per-user quotas and bump version to v1.7.0
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Update README/README.ru, CHANGELOG/CHANGELOG.ru, WIKI and VERSION to
cover the per-user resource quotas feature (commit 35dcbfd): instance/
vCPU/RAM/disk limits, HTTP 429 enforcement, quota:view/quota:manage
permissions, admin + self-service endpoints and UI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 23:59:08 +05:00
56d944a4c8 Удалить CODE_REVIEW.md
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
2026-06-26 23:53:23 +05:00
35dcbfd18f feat(quotas): per-user resource limits for VM/LXC deployment
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 54s
Deploy to Production / Trigger production update (push) Successful in 8s
Add per-user quotas (max instances, vCPU, RAM, disk) enforced at deploy
time and surfaced to users self-service.

Backend:
- UserQuota model (one-to-one, NULL = unlimited) + migration #28
- quota_service: usage from vm_instances cache, check_quota raises 429
- enforce in VM (templates.py) and LXC (lxc.py) deploy paths
- RBAC quota:view / quota:manage, granted to admin
- admin API GET/PUT /admin/api/users/{id}/quota
- self-service GET /settings/api/quota
- tighten VM list isolation via can_view_all_instances

Frontend:
- admin quota dialog in UsersPage with usage bars
- quota card on Settings page (own limits)
- remaining-quota hint in CreateInstanceWizard config step
- useUserQuota/useSetUserQuota, useMyQuota hooks; RU/EN locales

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 18:15:02 +05:00
d59d787bed feat(dashboard): redesign in VMmanager style with multi-node disk chart
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
- Three-panel top row: cluster overview, tasks-today, node gauges
- Cluster overview: IPv4 available in stats row alongside nodes/VM count,
  RAM/disk progress bars, RAM overselling ratio
- Tasks panel: completed/running/queued/errors/total from useAllTasks
- Node panel: SVG circular CPU & RAM gauges
- Bottom: nodes table with top-10 tabs (by CPU or disk%) + Grafana-style
  disk I/O chart with parallel useQueries for top-5 nodes, CartesianGrid,
  per-node colored lines and legend

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 03:26:41 +05:00
28fa6eb5b4 fix(instances): reset stale server/node filter on workspace switch
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 10s
Persisted instances-server-filter/instances-node-filter kept an old id
after switching workspace, emptying the list and showing the raw id in
the Select. Drop the filter to 'all' when the server/node is no longer
present in the active workspace.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 03:25:44 +05:00
7117c8adc3 feat(images): collapsible sections with persisted state
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
Make 'Cloud-образы ВМ' and 'LXC-шаблоны' section headers clickable to
collapse/expand. State is saved to localStorage per section so it
survives reloads and navigation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 03:24:55 +05:00
845c8024c4 feat(auth): forgot/reset password pages and wiring
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 1m16s
Deploy to Production / Trigger production update (push) Successful in 8s
- ForgotPasswordPage and ResetPasswordPage in the split-screen auth layout.
- "Forgot password" link on the login page now routes to /forgot-password.
- Public routes /forgot-password and /reset-password; reset page validates
  the token on mount and gates the form, with show/hide password and
  confirmation matching.
- i18n keys (reset.*) for ru/en.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 03:24:19 +05:00
8b93161434 feat(auth): self-service password reset (forgot/reset endpoints)
Add an email-based "forgot password" flow:
- PasswordResetToken model (stores only a SHA-256 hash, single-use, TTL)
  and migration 27 for the password_reset_tokens table.
- POST /api/auth/forgot-password — generic response (no account
  enumeration), 60s throttle, emails a one-time reset link via the
  existing EmailChannel as a background task.
- GET /api/auth/reset-password/validate — token validity check for the UI.
- POST /api/auth/reset-password — validates the token, enforces the
  password policy, sets the new password, clears lock state, invalidates
  outstanding tokens and terminates all sessions.
- Configurable link lifetime via PASSWORD_RESET_TOKEN_EXPIRE_MINUTES (30m).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 03:24:19 +05:00
65e14585c5 chore(frontend): make vite dev runnable outside Docker
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Allow overriding the dep-optimizer cache dir via VITE_CACHE_DIR (the
default node_modules/.vite is root-owned when built in Docker) and honor
a PORT injected by the harness. Both default to prior behavior when the
env vars are unset, so Docker builds are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 03:05:18 +05:00
89962a7f20 feat(auth): split-screen login with geometric pattern
Redesign the login page into a two-column layout: a decorative
geometric line pattern on the left (hidden on mobile) and the form on
the right with the PVEmanager logo on top and a footer with a language
switcher + copyright. Add a password show/hide toggle and a "forgot
password" link. Login logic (username/password) is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 03:05:18 +05:00
0510c1739d docs(images): document cloud-image catalog; bump to v1.6.0
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
Add v1.6.0 CHANGELOG entries (EN/RU) for the Images module: cloud-image
catalog, auto-convert to VM template, custom mirrors, arch-aware filtering.
Add feature bullet to README (EN/RU) and a dedicated WIKI section + TOC entry.
Bump VERSION 1.5.2-1 -> 1.6.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 01:38:22 +05:00
f880c9e177 fix(images): idempotent download (skip if file exists) + real failure reason
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 52s
Deploy to Production / Trigger production update (push) Successful in 8s
Retrying a template build failed at download because the qcow2 from a prior
attempt already existed and download-url refuses to overwrite. Now skip the
download when the volume already exists (volume_exists), and surface the PVE
task-log tail on download failure instead of a generic message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 00:38:50 +05:00
cdb49abf0f fix(images): sanitize VM name for import; honest create-error message
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 55s
Deploy to Production / Trigger production update (push) Successful in 9s
create_vm_with_import got the display name ('Ubuntu 22.04 LTS (Jammy) Cloud')
which PVE rejects (Parameter verification failed on 'name'). Sanitize to a
DNS-safe name (e.g. ubuntu-22-04-lts-jammy-cloud). Also stop attributing every
create failure to 'import unsupported' — only say that when the error mentions
import; otherwise surface the real error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 00:31:34 +05:00
1e06be10ad fix(images): normalize import filename extension (.img -> .qcow2)
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 52s
Deploy to Production / Trigger production update (push) Successful in 8s
Proxmox content=import rejects Ubuntu cloud '*.img' with 'invalid filename
or wrong extension' though the format is qcow2. Rename non-import-extension
files to .qcow2 before download-url; import-from auto-detects the format.
Applied to both download and template workers (download filename + import volid).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:52:56 +05:00
03b574777c fix(images): default arch to node platform; fix node selector placeholder
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Successful in 55s
Deploy to Production / Trigger production update (push) Failing after 10s
- arch filter defaults to amd64 and auto-syncs to the selected node's arch
  (useNodeArch), so amd64 nodes no longer show arm64 images by default
- node Select no longer renders raw '__none__'; shows 'Нода' placeholder
  and a disabled hint when no nodes are reachable

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:28:04 +05:00
2dff9f8c5c feat(images): node-arch endpoint for arch-aware filtering
GET /proxmox/api/{server_id}/images/node-arch derives amd64/arm64 from
node status current-kernel.machine; returns null when node unreachable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:28:04 +05:00
d2f57e13db feat(images): Phase 3 UI — custom mirror manager (admin)
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Successful in 51s
Deploy to Production / Trigger production update (push) Failing after 10s
Admin-only MirrorsManager on ImagesPage: list/add/edit/delete custom
mirrors with kind/arch/url/template/checksum fields; mirror CRUD hooks.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:17:00 +05:00
ed84e00e7b feat(images): Phase 3 backend — custom mirror CRUD
GET/POST/PUT/DELETE /proxmox/api/images/mirrors (perm template:manage).
Enabled mirrors merge into the catalog feed automatically.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:17:00 +05:00
ec8f4904a1 feat(images): Phase 2 UI — make-template toggle in download dialog
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Successful in 51s
Deploy to Production / Trigger production update (push) Failing after 11s
qcow2: 'make VM template' toggle (default on) with disk-storage picker,
cores/memory/bridge and cloud-init user/password fields; routes to
image_template task kind.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:11:20 +05:00
c7edf72d19 feat(images): Phase 2 — auto-convert qcow2 to VM template
- client.create_vm_with_import: API-only disk import via scsi0 import-from (PVE 8.2+)
- _do_image_template_sync worker: download(import) -> create+import -> cloud-init
  -> convert_to_template -> register OSTemplate (Cloud Images group)
- images download endpoint: to_template branch + cloud-init/disk_storage params
- clear fallback error when storage lacks import support (file kept)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 23:11:20 +05:00
32e06fe922 feat(images): frontend Images page, catalog hooks, download dialog
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Successful in 55s
Deploy to Production / Trigger production update (push) Failing after 11s
Phase 1 UI for VM image mirror feature:
- use-image-catalog hook (catalog, lxc repo templates, target storages, download)
- ImagesPage: server/node context, arch/search filters, cloud + LXC sections
- DownloadImageDialog: storage picker, background download via DeployTask
- CatalogImage/ImageMirror types, image_download/image_template task kinds
- sidebar nav 'Images' + /images route

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 22:57:16 +05:00
7aed5dd97e feat(images): backend catalog + mirror model + download API/worker
Phase 1 of VM image mirror feature:
- StorageMixin.download_url (PVE download-url/aria2) + get_download_target_storages
- builtin curated cloud-image catalog (Ubuntu/Debian/Rocky/Alma, amd64+arm64)
- ImageMirror model for admin custom mirrors
- /proxmox/api/images: catalog, lxc-templates proxy, storages, download
- _do_image_download_sync worker with log-tailing progress (DeployTask)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 22:51:21 +05:00
4d8cdc0143 Merge branch 'main' of https://github.com/markmorado/pvemanager
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 8s
2026-06-22 03:10:27 +05:00