1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 11:16:47 +00:00
Commit graph

727 commits

Author SHA1 Message Date
catborise
02ab78fe94 fix(instances): a clone size of a digit that is no number gets the form's refusal
clone_data checked the clone's vCPUs and memory with str.isdigit(), which
takes characters such as a superscript two that int() refuses: the user
saw Python's "invalid literal for int()" instead of the refusal. It now
checks with str.isdecimal(), whose characters int() reads.
2026-11-05 08:59:08 +03:00
catborise
337063bf7b perf(instances): a VM list reads only the VMs it shows
#394 read each host's states in one call and every domain's XML once,
for the title, memory and vCPUs. A user's list shows only their own VMs,
but it read the XML of every VM on those hosts: a user with two VMs on a
host of 300 made about 301 libvirt calls a list load, where the old
per-VM reads made 6.

get_domain_rows takes the UUIDs the list shows and reads only their XML;
the states still come in one call. The capacity reads every domain, as
before.
2026-11-05 07:33:13 +03:00
catborise
02d4d02757 fix(instances): a disk resize returns to the Disks sub-tab
607c8381 sent each memory and disk resize back to its own sub-tab, but
the disk view's last redirect, the one after a resize was tried, still
went to #resize, which opens on the CPU sub-tab. Only the live tests
reach it, with a disk to grow: the full live suite failed there on every
connection type.

The live vCPU test built its post from the page's form, and the page now
disables the CPU fields while the VM runs, so the post lacked cur_vcpu
and was refused as not a number before the running VM was. It now posts
both fields, as the direct post it checks.
2026-11-05 07:33:08 +03:00
catborise
4dd72766cf perf: a VM's owners' SSH keys in one query
The VM's keys page (instances:sshkeys) and the cloud-init user data
collected the owners' keys with one query an owner. Both now read them
in one query joined over the VM's owners, ordered owner by owner as
before.
2026-11-04 21:42:18 +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
103ce111ef fix(instances): a resize keeps a VM's maximum vCPUs above the host's CPUs
The Resize tab offered vCPU counts only up to the host's logical CPUs.
A VM whose maximum was higher (4 on a 2-CPU host, say) found no option
for it, so the Maximum list showed 1, and a resize of the shut-off VM
lowered its maximum to that without a word.

get_max_cpus() now takes the VM's own maximum as a floor, and the
Instance's vcpu_range passes it. The host's CPU count shown on the page
and used by the clone form is read from the host alone, not from that
range.
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
4da64c46cd feat(locale): quota refusals and connection errors show in the reader's language
A quota refusal put the English name of the quota (cpu, memory, disk,
instance) into a translated sentence, so a Turkish page read "memory
kotası doldu". check_user_quota now returns which quota and its numbers
(QuotaExceeded), each quota has a whole sentence, and the refusals put
that sentence before what is refused; QUOTA_DEBUG adds the numbers as
before. The clone job stores the refusal as a message, so the Jobs page
shows it in its reader's language.

The connection errors of vrtManager (did not answer within, still
waited for, closed, failed with libvirt's text) were English f-strings;
they are messages now, each close reason a whole one. A connection
that died without a close callback raised an error reading "None"; it
now names the host. Logs keep the English text.
2026-11-03 18:36:02 +03:00
catborise
b2b2386db9 refactor(vrtManager): a VM's addresses are read once a page, not once an object
wvmInstance kept the guest agent's and the ARP table's addresses from
the first NIC it was asked about, and never read them again on that
object; it carried a lease lookup that was never filled.

The addresses are now one {MAC: (IPv4, IPv6)} read, kept like the
domain XML only inside a cached_reads block: the VM page, which reads
its NICs twice, asks the agent once (it may take its whole timeout),
and a read outside a page's block is a new one. The agent's addresses
still come before the ARP table's.
2026-11-03 07:11:11 +03:00
catborise
fb45445492 fix(vrtManager): a request back from other hosts counts on its own host again
A request counts on the host it connected to last. A quota check reads
every host of the user's VMs, and a VM's destruction the other hosts'
files, in the middle of a request that then goes on with the VM's own
host through the objects it kept: it was counted on the last host it
read while it used its own, so a host that does not answer could take
more requests than its limit, and the last host read was charged.

Both checks now give the request back to the host it counted on before.
2026-11-03 07:10:54 +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
1e66367bb4 feat(operations): a job's error and warning show in the reader's language
A job stored its error and its result's warning as English text, much
of it built with the values in it (volume paths, a disk, libvirt's
error), so no catalog could translate it, and the job pages and panel
showed English whatever the language.

A job now stores them as messages: our English text, marked for
translation, and its values; libvirt's own text is a message without
values and is shown as it is. The jobs API and pages put them in the
reader's language. OperationError keeps its text and values apart for
the same reason, so a refusal raised while a job is submitted is shown
translated too. Messages one after another still read as sentences.

Errors stored before are kept as one message each, shown as they were.
2026-11-02 23:49:45 +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
6709681508 feat(webvirtcloud): a request waiting on a host holds one thread, not a worker
A host that is up but does not answer (a hung NFS mount, for one) keeps
a libvirt call waiting: libvirt's keepalive does not end it, since the
daemon still answers keepalives. Each such request held a whole sync
worker, and once they held every worker the panel stopped answering,
pages without libvirt too; F5 added another.

gunicorn now runs threaded workers, 4 threads each, and a worker takes
no more connections than it has threads, so one whose threads are all
busy leaves new requests to the others. A threaded worker keeps
reporting in while a thread waits, so gunicorn's timeout no longer ends
the request: the worker now exits itself when a request runs past the
timeout (600 s), and gunicorn starts a new one. Short claims expire on
that bound.

The address search runs one at a time in a process, as it did with one
request per worker.
2026-11-02 21:19:01 +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
b89672169f fix(instances): Refresh ISO list says which pools it could not read
A pool whose refresh failed, one busy with a volume copy for example,
was skipped without a word, so a hand-copied image stayed missing with
no reason given. The other pools are still refreshed; each failure is
shown with libvirt's error.

The API comment no longer says listing the ISO images refreshes pools.
2026-11-02 16:11:15 +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
cf991adad5 fix(computes): a VM migrates to its host's panel address when it has no migration address
Without a migration address libvirt sends a migrating VM to the
destination's own host name, which the source host often cannot resolve:
a live migration to a host added without one failed ("Unable to resolve
address ..."), also when the other host had one. The destination's
address on the Computes page, which the panel reaches it at, is now the
default; the migration address stays for another network. A host the
panel reaches on its loopback keeps libvirt's default.
2026-11-01 18:41:07 +03:00
catborise
940e639149 fix(instances): a failed migration says what libvirt said
A live migration whose source host could not resolve the destination's
name for the migration stream failed with "The host of this virtual
machine cannot be reached right now": libvirt reports that failure as a
connection error, and a job's error hides those behind that sentence so
as not to name hosts. Only superusers migrate, so the migration job now
fails with libvirt's own words, here "Unable to resolve address ...",
which points at the destination's Migration address.
2026-11-01 18:30:01 +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
8b7b7bdc3e test(instances): the live LVM test confirms erasing the device it pools
The New pool form asks for the erase confirmation on a logical pool since
the storage pages were redone; the live test's pool request lacked it, so
the pool was never created and both LVM tests failed in setUp.
2026-10-31 23:23:26 +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
fe4cffdc91 fix(instances): new q35 VMs have spare PCIe ports, and a full VM says what to do
On a q35 machine each PCIe device (a virtio disk, a network card) takes
a root port of its own, libvirt makes only as many ports as the VM is
defined with, and a running VM gets no new one: adding a virtio disk to
such a VM failed with libvirt's "No more available PCI slots".

A new q35 VM is now defined with the PCIe root and 14 root ports, as
virt-install makes them: libvirt puts the VM's devices into them and
leaves the rest free for devices added while it runs.

When a running VM has no free slot, Add disk and Add network device say
what to do instead of libvirt's words: for a disk, the scsi bus when
the VM has a SCSI controller (its disks need no slot of their own), or
adding it with the VM shut down, where libvirt makes the port; for a
network device, shutting the VM down. A new volume whose attach was
refused stays in its pool, as before, to attach as an existing volume.
2026-10-31 19:47:26 +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