1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 19:56:48 +00:00
Commit graph

428 commits

Author SHA1 Message Date
catborise
02412b7ea5 feat(jobs): deleting a VM is a job that recovery finishes
The delete ran in the request: undefine, then the VM's record, then its
disk files. A request that died in between (a gunicorn worker past its
timeout, OOM, a restart), or a database write that failed after the
undefine, left a record that later showed as removed outside the panel,
and the disk files the user asked to delete were never deleted.

Deleting a VM is now an instance.delete job. It holds the compute
exclusively, as the request did, so no other VM attaches a file it is
about to delete. The job chooses the files before it stops the VM (a host
that cannot be checked still stops nothing) and records them first. It
then stops and undefines the VM, removes its record, and deletes the
files, each with its own Logs row. Recovery decides from libvirt: a VM
still on its host means the delete failed; a VM gone means libvirt did
it, so recovery removes the record and deletes the recorded files that
are still there.

The page queues the job and returns to the VM page, where the job panel
follows it and opens the VM list when it ends; disks that were kept are
the result's warning. The API's delete answers 202 with the job and
needs a submission_key. backing_path moves to wvmConnect, as recovery
has no domain to ask.
2026-11-06 09:49:31 +03:00
catborise
2d0f41ee57 perf(instances): VM lists read each host once, not three calls a VM
A VM list row showed the VM's state, memory, vCPUs and title, read
through the VM's own connection object: a lookup by UUID, virDomainGetInfo
and the live XML, one after the other for every VM on the page.

The lists (Instances, grouped or not, and a compute's VMs) now read each
host once: the states in one getAllDomainStats call (the state group
only, as the lists' poll; no other group, so a VM busy in the QEMU
monitor holds nothing up) and the memory, vCPUs and title from each
VM's live XML, which the title already read. Checked on QEMU against
virDomainGetInfo for running, paused and shut-off VMs: the same values.

A VM gone from its host, or a host that cannot be read or fails its
listing, shows its VMs unknown as before. Only the grouped list, a
superuser's, prefetches every host's VMs and owners.
2026-11-04 20:54:11 +03:00
catborise
3911e9e238 style(instances): the Console tab asks for a new password only with "Set a new one"
The New password field sits under the "Set a new one" choice and shows
only while it is chosen, so its help no longer has to say so. The Console
heading above the Console type label goes, and the save button has the
size of the other tabs' main buttons.
2026-11-04 15:15:12 +03:00
catborise
cb07d4304e style(instances): the Users tab's owner buttons are outlined
Edit rights and Remove are outlined like the other tabs' row buttons.
2026-11-04 14:47:36 +03:00
catborise
ab2192ef5f style(instances): the XML tab's editor is taller and its review marks the changed lines
The VM's XML editor takes most of the window's height and is framed like
a form field. The review dialog shows removed and added lines on a red and
green tint, and each part of the diff starts with its line number instead
of the unified diff's @@ header.
2026-11-04 14:26:22 +03:00
catborise
9cda2f4e1b style(instances): the Migrate tab sets the switches that can lose data apart
Unsafe migration and deleting the source files of copied disks sit below
a line, apart from how the memory moves, with their help in red. The disk
lines read "vda 10.0 GB" instead of a dot-joined fragment.
2026-11-04 13:56:17 +03:00
catborise
379228927b style(instances): the Clone tab's MAC buttons sit beside the address
Random and Guess join the MAC field as one input group, the Clone tab's
secondary buttons are outlined like the other tabs', and the NIC and disk
lines read as plain text ("default pool, qcow2") instead of dot-joined
fragments.
2026-11-04 12:22:36 +03:00
catborise
f5cb6f3479 style(instances): the Disks tab's secondary buttons are outlined
Edit, Move, Detach, Unmount and a CD-ROM drive's Detach are outlined
secondary buttons and Delete an outlined danger one, as on the Network
and Snapshots tabs; Mount and Add disk stay the filled primary actions.
2026-11-04 10:47:55 +03:00
catborise
a06565fa0b feat(instances): the Network tab shows each NIC as a cable to its source
A NIC's row put its name and host device in one column, "Source",
"IPv4 unknown" and the link switch in another, and its model, MAC and
filter behind Device details; every NIC also had a "QoS limits · none"
fold and solid Edit, Add QoS and Delete buttons.

Now a row reads eth0, a cable, then the source: the cable is solid green
while the link is up and dashed grey while it is down. Under it are the
IPv4 addresses (or "No IPv4 address known") beside the link switch, and
a line of model, MAC, filter and whether bandwidth is limited. Device
details keep the type, the host device and IPv6; QoS limits show only
for a NIC that has one. The buttons are outlined. Dialogs, form names
and posts are unchanged.
2026-11-04 09:21:32 +03:00
catborise
0b2604f151 feat(instances): the Snapshots tab shows the VM's history as a line
The tab opened on "Snapshots · Active" above the form, and listed the
snapshots below it as rows of "name · description · external, current
· date" with a solid red Delete on each. Which snapshot the VM goes on
from was the word "current" among the others.

Now a line runs down the tab, newest first. On top is Now, the VM in
its state's color, with the form that takes a snapshot there. Below it
each snapshot is a point: its name and date, its description on a line
of its own, its kind under them. The one the VM goes on from is filled
and says so; the others are rings. Revert and Delete are small outlined
buttons. Forms, confirmations and the rules that disable them are
unchanged.
2026-11-04 08:59:50 +03:00
catborise
07ca42dcdf feat(instances): the Options tab groups what the VM is and what the guest sees
The tab listed seven settings at one weight, each a two-column card with
a heading and a paragraph beside its control. The controls disagreed:
three switches posted on change, while the video model, the crash action
and the guest agent (an Enabled/Disabled select) each had their own
Save, and "From the next start" was repeated under three of them.

Now it has three parts. VM details: title and description with their
Save, and the template switch below them. Devices the guest sees: video,
virtio RNG, TPM 2.0 and the guest agent as rows of name, control and a
one-line note, under one line saying when changes apply; the video model
posts on change and the guest agent is a switch, with its connection
shown beside it as the Power tab's dot. When the guest crashes:
Restart / Stop as two buttons that post on click. Form names, posts and
who sees what are unchanged.

The Turkish catalog now calls the guest agent "konuk ajanı" everywhere.
2026-11-04 08:23:43 +03:00
catborise
607c8381b4 feat(instances): the Resize tab shows how much a VM has within its maximum
Each sub-tab (CPU, Memory, Disks) opened on a two-column card that put a
heading and a sentence of current values beside the forms, and the CPU
tab added two more rows: Live vCPUs as a row of "0 · Fixed / 1 · On"
buttons and vCPU hot plug as a select with its own Save.

Now each sub-tab opens on the VM's size. CPU: one cell per vCPU up to
the maximum, filled when on, with "2 on, up to 4" and the host's logical
CPUs; on a running VM with hot-pluggable vCPUs the cells are the
buttons that turn them on and off. Memory: a bar of the current memory
within the maximum, with the host's memory. Disks: a row per disk with
its format, size now and a new size. The forms below keep their names
and posts; the CPU fields are disabled while the VM runs, and hot plug
is a switch that posts on change. A memory or disk resize returns to
its own sub-tab.
2026-11-03 23:07:59 +03:00
catborise
4997950e75 feat(instances): the Access tab splits the VM's screen from root's login
The tab put the console, a remote viewer address and two root forms at
one weight under "Access · Active · VNC", named buttons after their
implementation (VDI, Get console.vv), and repeated why the root forms
were disabled under each of them.

Now it has two sections. Screen: Open console with what it does, and
the remote viewer on a row of its own (address, Open, Download .vv
file). Log in as root: one line says how a password or key reaches the
guest now, written to the disk of a shut-off VM or sent through a
running VM's guest agent, or what to do when neither works; the
password and key rows follow with aligned labels. Ids, field names and
posts are unchanged.
2026-11-03 20:39:40 +03:00
catborise
4565221c5c feat(instances): the Boot tab shows the boot order as the chain the VM tries
A checkbox marked a device as booting and also chose what Up and Down
moved, which moved every checked device at once: to move one device the
others had to be unchecked and checked again. The buttons sat apart
from the rows, and a VM booting by device type got a note that did not
say what to do.

Now the devices the VM tries are a numbered chain, each with its own
up, down and Remove, and the others are listed below it with Add; the
posted order is unchanged. Devices read by kind first (CD-ROM sda,
Disk vda) with their file or network below; a VM booting by device
type says so and how to choose an order. Autostart and the boot menu
sit below, lighter. Focus stays on the device that moved, and on a
narrow screen a device's buttons wrap below its name.

The Turkish catalog says "Ön yükleme" and "sanal makine" throughout,
also in the Power tab texts.
2026-11-03 19:48:52 +03:00
catborise
c247a7a3f0 feat(instances): the Power tab shows the VM's state and where each action takes it
The tab put Power Off and Suspend, then Power Cycle and Force Off, in
joined button groups with a paragraph under each, so which sentence
told which button was left to the reader, and the two power cuts
looked like one control as large as the rest.

Now the tab shows the three states a VM moves between, Active,
Suspended and Off, the current one marked, and under each the action
that takes the VM there with one line on what it does. The power cuts
are small outlined buttons on a line of their own with one warning;
their confirmations stay. A state outside the three (shutting down,
crashed) is named above them. The test of the tab now finds the
outlined power-cut buttons, which its class match missed.
2026-11-03 19:22:52 +03:00
catborise
491819ed64 feat(vrtManager): the libvirt layer's messages show in the reader's language
vrtManager's errors (some 140: a disk that does not move, a network
address outside its subnet, a host device given to another VM, the
disks a migration cannot copy) were English f-strings, so no catalog
could translate them, on pages or in jobs.

They are marked texts with their values now; a variant that differs by
a word (internal or external, running or persistent, with a subnet or
without) is a whole message of its own, and a list of problems is a
list of messages. OperationError reads in the active language, so the
pages that show one translate it as they are; its args stay English, and
so do the logs and the audit log. Host device problems and the Migrate
tab's reasons a disk is not copied are messages too.
2026-11-03 00:05:34 +03:00
catborise
9d57adc097 fix(locale): the VM page's and Settings page's messages show translated
The VM page's and the Settings page's views marked their messages with
gettext_noop, so every message they gave (a refused resize, a saved
setting, a QoS change, a busy VM) showed in English whatever the
language, though the catalogs translate them. They translate in the
request's language now; their module-level texts lazily. The Settings
page's group titles stay English in the view, as the page links them
by their slugs and translates them itself.

Two values went into translated messages as English codes: a job's
state ("... is running on this resource") and a QoS direction ("Remove
the inbound limit ..."). They are named as the pages name them.
2026-11-02 23:09:05 +03:00
catborise
763f1525ca feat(locale): the panel is translated into Simplified Chinese
The Chinese catalog had not been extracted since 2023: of the panel's
1749 messages, 878 were missing and 455 carried old fuzzy guesses, and
some of those marked done said something else ("Delete API token" read
"Delete SSH key").

Every message is translated again, with one glossary for the panel's
terms, placeholders and markup checked against the English, and the
panel offers Simplified Chinese again. The CI check covers it too.

One message of the VM page (the console password's help) never reached
any catalog: its escaped quotes cut it short at extraction. It is
written with single quotes now, and translated in both catalogs.
2026-11-02 23:03:09 +03:00
catborise
5d1269666b fix(instances): the Migrate tab keeps disks of one file name apart
Two disks of a VM with the same file name in different directories
were both offered the same destination pool by default. The form was
sent, and the migration job refused it only then: both copies would
be one file.

The plan now gives each such disk, by default, a pool no earlier disk
of that name is copied into, and says under its choice that another
disk has the file name. A choice that still puts them in one pool is
refused by the job, as before.
2026-11-02 16:29:00 +03:00
catborise
d5d054de71 perf(instances): the VM page lists ISO images without reading every pool
The VM page refreshed every active storage pool to list the ISO images
for its CD-ROM drives. A pool holding large disk images took up to
seconds to refresh, most of the page's time, on every page load.

The page now lists the ISO images libvirt already knows. Images
uploaded through the panel are known at once. For an image copied to a
pool by hand, the Removable media section has a Refresh ISO list button
that refreshes the active pools and returns to the page.
2026-11-02 13:58:51 +03:00
catborise
946629b035 refactor(instances): the VM lists' scripts load from static files
The VM lists lose their inline scripts and handlers: host_groups.js
collapses a host's VMs in the grouped list, new_vm_dialog.js reads the
new-VM dialog's CPU bars and capacity lines, and console_window.js
(loaded by every page) opens a console button's window, on the lists and
on the VM page alike. A list row's Start no longer calls the please-wait
dialog, which the list pages do not have (the call only raised an
error). The VM page's URL placeholders take the __name__ form the other
pages use.
2026-11-02 09:35:07 +03:00
catborise
e143fe353a refactor(instances): the VM create pages' scripts load from static files
The create wizard's two pages lose their inline scripts and handlers:
create_machine.js (machine types of the chosen architecture, Next, the
XML editor) and create_instance.js (volume and network pickers, disk
source, presets and flavors, row lists, a refused form restored). Their
URLs and messages are data attributes of #select_chipset, #next and
#create-vm-form; URL parts use __name__ placeholders, so the volume list
URL is now the routed one with its trailing slash. The XML form shows
the please-wait dialog through data-please-wait. The page script tests
read the static files.
2026-11-02 09:26:39 +03:00
catborise
561937b31a refactor(instances): the VM page's scripts load from static files
The VM page's thirteen inline script blocks and its inline handlers move
to static files: instance_page.js (tabs, OS details, clone names and
MACs, Add disk dialog, boot order, host devices, migrate plan, console
window, switches that send their form), instance_stats.js (charts and
the Logs view) and instance_status.js (the reload when the VM's state
changes). Their values and messages come as data attributes of the
elements they belong to, page-wide ones on #vm-summary; a form marked
data-please-wait shows the please-wait dialog. Three blocks that did
nothing are dropped: popovers (the page has none), the video model
preselection (the server selects it) and the delete form's poll stop
(that form is on the destroy page). The HTML sink inventory now also
reads the app's own scripts.
2026-11-02 09:04:29 +03:00
catborise
393aecb8f1 refactor(templates): the shared page scripts load from static files
A step towards a Content-Security-Policy without inline scripts. The
scripts every page or many pages share now load from static files: the
error focus of base.html, the please-wait dialog, the sign-in forms'
password toggle and busy button, the jobs pages' reload while a job
runs, and the start of the job panel and of the VM list's state poll,
whose values come as json_script data. Cancel links go back through a
data-history-back attribute instead of a javascript: URL. The IE8
html5shiv/respond.js block, X-UA-Compatible and shrink-to-fit are gone:
no supported browser reads them.
2026-11-02 08:47:58 +03:00
catborise
6434d4cbfe fix(instances): the VM page's section bars fill their row
The buttons of the VM page's section bar and of the Settings bar under it
sat at the start of the row and left its end empty. Both bars now share
the whole row out among their buttons (Bootstrap's nav-fill), also when
they wrap on a narrow screen.
2026-11-01 23:17:12 +03:00
catborise
dbc0115c06 feat(instances): a template's page is a template's
A template's page was a VM's: it opened on Power, with only a note there
that a template is not started, while its clone form waited in a section
of Settings, next to a console, access, snapshots and stats that a VM
that never runs has no use for. A template's page now carries a Template
badge and a Clone button, opens on the clone form, and leaves out Power,
Access, Snapshot, Stats, the console settings, host devices and the
guest agent and address lines; Resize, Settings and Destroy stay for
whoever may change it. A page that no section opens shows its first.
2026-11-01 22:57:02 +03:00
catborise
8a809443a4 feat(instances): a clone takes the size asked and starts if asked
A VM made from a template came out at the template's size and shut off,
and was then resized and started by hand. The Clone tab now asks for the
clone's vCPUs and memory, filled in with the VM's, and whether to start
it. After the copy, before the clone is recorded, it is resized with the
Resize tab's own functions and started; a step that fails is a warning
of the job, and the clone stays. The quota counts the larger of the size
asked and the VM's, so a resize that fails leaves the clone at a size it
allowed.

When the job ends the page opens the clone's, not the cloned VM's again:
a template's page, shut off, read as a clone that had not started. An
outcome kept for a warning links to it.
2026-11-01 22:38:43 +03:00
catborise
eb6e6ca626 feat(instances): the VM lists follow changes by themselves
A VM list showed what it read when it was loaded: a VM stopped from
inside its guest or with virsh, or made or removed elsewhere, showed only
after a reload, unlike the VM page, which reloads when its VM's state
changes. The lists of all VMs and of one host's VMs now poll the states
of their VMs, at once and then every 5 s as the VM page does, and reload
when an answer differs from the one before. The states come from one
libvirt call per host; a user who does not see hosts gets only their own
VMs. The page in use (a dialog, a field, an unsaved XML edit, a job
outcome shown) holds the reload until it is free; that check is shared
with the job panel.
2026-11-01 19:53:45 +03:00
catborise
dbc7e688ac feat(instances): a shut-off VM with a TPM migrates with its TPM state
A shut-off VM with TPM state, as every Windows 11 VM, was refused for
migration: the state is a file of the source host, and an offline move
would start it there with a new TPM. Such a VM now migrates as a shut-off
VM with disks to copy does: its UEFI variables are copied, it is started
paused, its CPUs never run, migrates live, which carries the TPM state,
and is shut off on the destination. A shut-off VM with a saved state is
refused before any of that, for every way it moves: started paused, it
would resume and then lose the saved memory.

The clone tab says that a clone gets a new, empty TPM, and the destroy
page that the TPM state goes with the VM.
2026-11-01 18:29:53 +03:00
catborise
e35342bff1 feat(instances): a VM's TPM 2.0 is switched on and off on its Options tab
A VM made without a TPM, a Windows 10 to be upgraded to Windows 11, had
no way to get one but the XML editor. The Options tab has a TPM 2.0
switch, as the RNG one: it adds an emulated TPM of the host's model to
the definition for the next start, or removes it. Its state stays on the
host until the VM is undefined, so a TPM added again has it back. A TPM
the switch did not make (passthrough, 1.2, encrypted, with its own state
path) is left to the XML editor, and a host without swtpm says so.
2026-11-01 17:10:26 +03:00
catborise
2a05576e18 feat(instances): a CD-ROM is added on the bus chosen, with its ISO
A running VM got its new CD-ROM on SCSI, the one bus the panel could plug
in then, and Windows does not see a virtio-scsi drive before the driver
on that ISO is installed. Add CD-ROM is now a dialog that chooses the bus
and the ISO: a running VM takes USB, first, which every guest sees and
which hot-plugs, or SCSI; a shut-off one SATA (IDE on pc), SCSI or USB.
libvirt has no empty USB drive, so a USB CD-ROM takes its ISO when it is
added and is detached instead of ejected, also while the VM runs.

A USB CD-ROM is a CD drive on QEMU's usb-bot only. Where QEMU has none
(RHEL 9), libvirt took usb-storage, which shows the guest a hard disk
that Windows does not read; the drive now asks for usb-bot, and such a
host refuses it with libvirt's message.
2026-11-01 16:27:39 +03:00
catborise
005fa59bf0 feat(instances): a new VM can have UEFI Secure Boot and a TPM 2.0
Windows 11 does not install without Secure Boot and a TPM 2.0, and the new
VM form offered neither: its firmware list was BIOS and one UEFI loader
guessed from file names, which on RHEL never matched the Secure Boot one.

The firmware choices are now BIOS, UEFI and UEFI Secure Boot, as the
host's libvirt reports them (its firmware features from libvirt 12.1,
before that its loaders), and libvirt picks the firmware itself: UEFI
without Secure Boot, or with Microsoft's keys enrolled. A TPM 2.0 switch,
shown when the host has swtpm, adds an emulated TPM. The create job
refuses a firmware or a TPM the host does not offer, and the API takes
both. The path-guessing helpers are gone.
2026-11-01 16:18:29 +03:00
catborise
c401479cf9 feat(templates): every confirmation asks in the page's own dialog
Deleting or detaching a disk, deleting a network card, forcing a VM off,
reverting or deleting a snapshot, stopping or deleting a pool, a
network, an interface, a filter or a secret, and the other actions that
ask first opened the browser's yes/no box (confirm()), and the ISO
upload told its mistakes in the browser's alert().

One dialog in the base page now asks for all of them: its title and
confirming button carry the button's own words, its body the button's
question, the confirming button red for a destructive action. Confirmed,
the button is clicked again, so its form sends what it did before. A
button inside another dialog (the flavors) hides that one while asking
and shows it again after; Cancel gives the focus back, and the
confirming button acts once. The ISO upload's mistakes show in its
dialog's error box, announced.
2026-10-31 20:44:39 +03:00
catborise
95562544eb feat(instances): Add PCIe slots for a VM that has none free
An existing q35 VM whose PCIe root ports are all used takes no new
virtio disk or network device while it runs, and the only way to give
it more was editing its XML.

The Disks tab of a PCIe machine now counts its slots, "PCIe slots: 0
free of 7", in red when none is free, with what its next start will
have when that differs, and Add PCIe slots adds four root ports to its
persistent definition: libvirt numbers and places them, and a running
VM gets them at its next start. The no-slot advice of Add disk and Add
network device points at it.
2026-10-31 20:44:24 +03:00
catborise
34d9e778ce fix(instances): the Add disk dialog is as wide as the other card dialogs
The Add disk dialog kept Bootstrap's default 500px width when it got
its source cards, so their help and the name's hint broke over two
lines and left gaps between the fields. It now opens large, scrollable
and full screen on a phone, as the New storage pool and New network
dialogs that use the same cards.
2026-10-31 19:52:11 +03:00
catborise
27b8dd4f1b fix(templates): the dialogs' Cancel is outlined, as the redone ones
The host pages' dialogs (new network, fixed address, DHCP range,
bandwidth limit, new interface, new filter, filter rule, filter clone,
new storage pool, new secret, a secret's value) and the VM page's XML
review closed with a grey filled Cancel beside their action; the
redone dialogs use an outlined Cancel, so the action is the one filled
button.
2026-10-31 18:35:09 +03:00
catborise
0fd3e69c8e feat(instances): the VM page's add dialogs in the panel's dialog look
The Add disk, Add network device and bandwidth dialogs of the VM page
set their labels in a narrow column beside the fields and closed with
a grey Close: Add disk split "GB" over two lines and offered an
unexplained Metadata box, its existing-volume pool was a dropdown of
links that wrote a hidden field; the network list prefixed every
choice with "Network" or "Interface"; the bandwidth fields asked for
"kilobytes" where libvirt counts KiB/s and KiB.

Now their labels sit above the fields, tied to them, in two columns.
Add disk is one form whose source, New disk or Existing volume, is a
radio card as in the new VM form, the chosen source's fields shown and
sent and its action taken; the size has a GiB suffix and
"Preallocate metadata (qcow2)", the existing volume's pool is a select
that loads its volumes, the bus and the cache are shared. Add network
device picks its
source from Networks and Interfaces groups and says how its MAC is
filled; the bandwidth limit names its units and when a running VM gets
it. Move says when the host has no other pool and is disabled then.
Every dialog closes with Cancel and its action; the posted fields are
unchanged.
2026-10-31 18:35:09 +03:00
catborise
26a10d127a fix(instances): the disk Edit dialog on one page, and an empty serial stays empty
The disk Edit dialog showed a disk without a serial as "None" in its
Serial box, so saving it untouched gave the disk the serial "None".
The box and the format box are now empty for a missing value.

The dialog also hid most of its nine fields behind three tabs, said
nothing about a running VM, greyed the bus without a reason and its
switch labels did not toggle them. Now one body shows the disk's bus,
format and size under the title; a running VM's note that the changes
apply at its next start; the path and the Read-only and Shareable
switches in a Source card; the four performance modes in a grid; and
the bus, serial and image format folded under Device, with why the bus
is locked and that changing the format does not convert the image.
Cancel is outlined and Save the primary action.
2026-10-31 18:10:05 +03:00
catborise
2e17661390 fix(instances): a network device keeps its source unless another is chosen
The Edit dialog of a VM's network device selected the listed network
or interface whose name matched the device's source, and the first one
when none did: saving only a new model moved a macvtap device or a
bridge the host's lists did not show onto the first network, a bridge
named like a network became that network, and a macvtap device chosen
again lost its mode.

The dialog now offers the device's own source first, "<name>, as it
is", and posts nothing for it; the view passes no source and the
device's source element is left as it is. Choosing another source
changes it as before.
2026-10-31 18:10:05 +03:00
catborise
3d69dfe5d9 feat(instances): the network device Edit dialog as the disk one
The Edit dialog of a VM's network device listed its fields in an
order of its own, named the source list "Net Source" with every option
prefixed "Network" or "Interface", said nothing about a running VM and
closed with Close and Apply.

Now it reads like the disk Edit dialog: the device's model and MAC
under the title, a running VM's note that the changes apply at its
next start, the source chosen from Networks and Interfaces groups, the
model and the NWFilter side by side, the MAC in monospace, and Cancel
and Save. The posted fields are unchanged.
2026-10-31 18:10:05 +03:00
catborise
6e147ed8cc feat(instances): a VM's network devices as rows of one list
The Network tab gave each network device a card with its buttons in a
footer, two cards to a row, as the disks had.

Each device is now a row of the same kind of list as the disks: eth N
with its target, the source, the IPv4 addresses and the link switch,
and Edit, Add QoS and Delete at the row's end; the device details, the
QoS limits and the macvtap note still fold out below it. A row holds
its Edit and Add QoS dialogs, so only rows sit in the list.
2026-10-31 18:10:05 +03:00
catborise
68d0631e33 feat(instances): a VM's disks as rows of one list
The Disks tab gave each disk a card: its capacity in large type, its
pool, its path and its buttons stacked, two cards to a row, so a VM
with a few disks filled the screen.

Each disk is now a row of one list: the device with its bus and format,
the capacity and the space used with a thin bar, the pool and the path,
and Edit, Move, Detach and Delete at the row's end; the device details
still fold out below it. A qcow2 file whose metadata takes it past its
capacity shows a full bar.
2026-10-31 18:10:05 +03:00
catborise
a408cfdb2b feat(instances): the Migrate tab marks hosts it cannot use and files in the way
The Migrate tab offered every other host alike, and its plan showed
neither a file of the same name in a destination pool nor the disks of
the VM's next start, which the job then refused. Now:

- When the tab opens, the hosts are checked first: one that cannot be
  reached, or the VM's own host under another record (the same libvirt
  host UUID), is shown with why and cannot be chosen, and the disks of
  the first one left are checked. The job refuses the VM's own host
  under another name too.
- A pool of the destination that has a file of a disk's name is shown
  but cannot be chosen for it; a disk no pool can take refuses the form.
- The next start's file disks the migration does not carry are listed;
  one not on storage both hosts share refuses the form, as the job does.
2026-10-31 01:34:44 +03:00
catborise
54a1943e26 fix(instances): a VM's destruction checks its files on every host first
Destroying a VM with its disk files forced it off first and then
worked out which files to delete, so a check that failed left the VM
stopped, and only this host's VMs and volumes were checked: a file on
shared storage that a VM on another host uses was deleted.

The files are now worked out before the VM is stopped: the disks it
runs with and those of its next start, as before with their snapshot
files and seed. A file a VM or volume of another of the panel's hosts
uses at the same path (shared storage is mounted at one path on every
host, as migration needs) is kept like one used here; another record
of the VM's own host is skipped, as there the VM itself uses them. A
host that cannot be read stops the destruction with its name, before
anything is stopped or deleted.
2026-10-31 01:08:42 +03:00
catborise
5e93920d78 feat(instances): a VM's stats in one grid, its logs a switch away
The Stats tab stacked one large card per chart, so a VM with a few
devices made a long page, and its "Real Time" and "Logs" sub-tabs were
shown to every user although only a superuser may read the logs. The
owner chose the layout from rendered options: a state line, CPU and
memory side by side, one chart per NIC and disk below, each with its
latest reading next to its title, and a small Graphs/Logs switch for
superusers.

Codex reviewed the tab; this is fixed:

- Memory is shown in MiB (it was labelled MB), and its axis grows to
  the RSS when the RSS passes the balloon size instead of clipping it.
- The CPU reading says it is of the host's CPUs.
- A NIC is titled by its MAC, not an invented "eth0", and its readings
  are matched to its chart by the MAC: they were matched by position, so
  removing a NIC while the page was open moved the next one's readings
  into its chart.
- A VM that is not running says nothing is measured.
- The logs load whenever the Logs view is shown, by keyboard too; an
  empty answer says "None" and a failed one says so, instead of an
  empty table. The tab shows the latest 50 rows, with a link to all of
  the VM's rows on the Logs page.
- The VM's header shows memory in MiB; it said MB.
2026-10-30 23:41:17 +03:00
catborise
b72e9b1442 feat(instances): a VM's destruction says what goes, and keeps what a kept file needs
The Destroy tab was a sub-tab with one sentence and a link; its
confirmation page said only "This action is irreversible!" over a
"Remove Instance's data" switch. The tab now shows the state and
"Review destruction". The owner chose the confirmation layout from
three rendered options: the VM and its host, that its definition,
saved state and snapshot records go and that a running VM is forced
off, two plans for the files (delete the disk files, or keep them), the
VM's disks, what is always kept, the NVRAM choice, and Cancel.

Codex reviewed destroying; this is fixed:

- A disk file that cannot be deleted keeps the files below it, which
  it needs: they were deleted after it, leaving it broken. The files
  are deleted overlays first (split_disk_paths_by_use orders them by
  how many files each grows from), and if the files a kept one needs
  cannot be read, none of the rest goes. A message names each file
  kept so, and a failed deletion says the VM is removed.
2026-10-30 22:19:31 +03:00
catborise
7fc55537e5 feat(instances): external snapshots first, internal ones a fallback
The Snapshots tab had three sub-tabs: internal, external and the
lists, with the two kinds side by side as equals. The owner set the
direction: external snapshots are the way; internal ones pause the VM
while its memory is saved and can take long, so they stay only as a
fallback for a VM that cannot take an external one.

The tab now has the external snapshot form on top, its name and
description on one line, with its memory and freeze options; the
internal snapshot under a folded "fallback" line with its warning; and
one list of all snapshots, newest first, each on one line with its
name, description, kind and date, and Revert and Delete.

Codex reviewed snapshots end to end; these are fixed:

- The pause and memory lines follow the VM's state and the kind.
- An internal snapshot is reverted to on a shut-off VM only, on the
  server too; the tab alone held that rule.
- A paused VM's revert says it comes back paused, not that it starts.
- An external snapshot waits, with the reason, while snapshots newer
  than the one reverted to exist; the server refused it unexplained.
- Deleting an external snapshot says its files are merged with the
  disks; "into the next one" was wrong for the last one.
- The description has no 45-character limit only the browser kept.
- Freezing is not shown ticked where it cannot be offered, and
  unticking memory gives back the earlier freeze choice.
- Internal create, revert and delete refuse a saved state or a running
  disk job, as external ones do.
2026-10-30 21:40:00 +03:00
catborise
60f12cefa1 feat(instances): a VM's access in one strip, its console password kept to its rule
The Access tab hid the console, the root password, the SSH key and the
remote viewer behind four sub-tabs. The owner chose a compact layout
from three rendered options: the state, a strip with the console and
the remote viewer, then two rows for root's password and key, each
saying why it waits when it does.

Codex reviewed access end to end; these are fixed:

- console.vv carries the console password only for users with the
  passwordless console permission, as the console page passes it; it
  gave it to every user who may open the console.
- The root password field is a labelled password input, not plain text
  with a 24-character limit.
- Without a saved public key the key row is disabled and points to the
  profile, instead of offering "None".
- A paused VM's console opens, as the console view allows.
- The remote viewer address and console.vv show only for a VNC or SPICE
  console that listens beyond the host's loopback; a viewer on the
  user's computer cannot reach the others, and a serial console gave a
  pty://…:None address.
2026-10-30 20:39:40 +03:00
catborise
efb77dd866 feat(instances): a VM's power actions at a glance, a power cut asked first
The Power tab hid each action behind a sub-tab of one sentence and one
button. The owner found the first rendered layouts crowded and chose a
compact one: the VM's state, then the actions its state allows in two
groups, those that keep the guest's data and the red ones that cut the
power, each group with one short caption.

Codex reviewed the power actions; these are fixed:

- Power Cycle and Force Off ask first, naming the VM and what is lost,
  as the VM lists already did.
- The words say what happens: Power Off asks the guest to shut down;
  Power Cycle cuts the power and starts the VM again, with its pending
  settings; Force Off cuts the power.
- The tab follows states.allowed_actions, as the lists do; a running
  VM's actions now include Force Off there too.
- A running template is not offered Power Cycle, which would start it
  again; a shut-off template says to clone it instead of showing a
  Power On button that only looked disabled.
- A paused VM tells its owner that an administrator can resume it; it
  said an administrator had blocked it.
- Power On's please-wait dialog opens on the form's submit, from the
  keyboard too.
2026-10-30 19:21:30 +03:00
catborise
f8e30d7668 feat(instances): a VM's resize tab as a ledger, its vCPU changes kept
The Resize tab's CPU, Memory and Disk panes were horizontal forms with
bold host figures. The owner chose the ledger layout from three
rendered options: each section with its heading, the VM's figures and
the host's on the left, its fields on the right, and one line on what
applies now and what at the next start.

Codex reviewed resizing end to end; these are fixed:

- A vCPU turned on or off while the VM runs is kept at its next start:
  libvirt was asked without flags, which changes the running VM only.
- A paused VM offers to turn vCPUs on only: turning one off needs the
  guest, which does not run.
- A smaller disk size is refused, and so is the rest of the form,
  before anything grows; it was skipped without a word.
- vCPUs and memory below 1 are refused.
- The memory fields are numbers filled with the VM's values: the
  "Custom value" box, its script and the preset list are gone; an empty
  custom field silently used the preset.
- Units and words: MiB, not MB; a disk's field is its new size, with
  its size now above it; the messages say what the VM gets.
2026-10-30 18:16:11 +03:00