Plan reviewed with Codex; tried on a udev host (AlmaLinux 10) and a
netcf one (AlmaLinux 8).
- Changes are one change of the host's configuration (libvirt's
interface change transaction): a bridge that does not start used to
be undefined, leaving its member without the addresses and start
mode the bridge took from it; now the whole change rolls back, the
member's own configuration too, and so does a commit libvirt refuses.
A rollback that fails too is reported with the failure, saying the
host's configuration may be changed.
Deleting a bridge, which defines its
members again on their own, is one change as well.
- A running interface is not deleted: the page hid Delete, but a post
deleted it. A bridge with addresses and several members is refused
(which member takes the addresses is the user's choice); the
confirmation says that its members are defined again.
- A bridge takes only a device in no bridge, bond or VLAN as the host
has them configured, at any depth (a bridge's bond's devices), not
the loopback, a libvirt network's bridge or a VM's tap; an ethernet
interface configures only such a device too.
- Whether the host can change interfaces: unsupported or refused by
its access rules is a no, bad XML a yes, anything else (the
connection, the login) is raised instead of taken for a yes. A page
whose host could not be read offers no actions.
- Reads: the list reads each interface's XML once from one listing
(listAllInterfaces: every state, not the active and the defined ones
apart); a page reads the running and the saved definition once each
(cached_property). netcf writes a link speed of -1 for a card that
has none (a virtio one) and then refuses its own XML: the saved one
is read instead, where virsh and the page failed. Name and MAC come
from libvirt's object, without a call. Each family says how it is
addressed (DHCP, autoconf, static or none) and every address, its
prefix where it has one; no
address is not "DHCP" any more. A bridge's members carry their link
state and speed; an unknown speed (0, -1, 4294967295) is none.
- The interface API lists from the same reader. get_details,
get_bridge, get_bridge_slave_ifaces and the per-family getters go.
webvirtcloud.css still carried the upstream panel's rules for what
Bootstrap 5.3 has as utilities and components:
- the page's bottom space (body padding) is pb-5 on base.html's body,
and the console page no longer has to undo it;
- the VM page's action tabs (.action-button, .action-block with a
fixed 65px width) are text-center with a d-block icon; its tab panes
(#power ... #undefine, one rule each) mt-3;
- the bordered sub-tab panes (.tab-pane-bordered, a fixed #eee border
that dark themes could not change) border border-top-0 p-3;
- the search box and header buttons (.search, .btn-header) m-1 and
mt-1; the SSH key select (.keyselect) a form-select;
- the boot order list (.multipleselect, fixed size, #c0c0c0 border) a
list-group of form-check-input items; its unused .multipleselect-on
goes;
- table cells centred by a global rule are align-middle on each table.
Two rules against Bootstrap's behaviour go: menus opened on hover on
wide screens (Bootstrap opens them on a click, and keyboard and touch
users had no hover), and "a { outline: 0 }", which hid the keyboard
focus ring.
The paragraph and page-header margins and the 900px container stay
for a separate change: they set every page's layout.
Eleven host pages (overview, instances, storages, networks, interfaces,
nwfilters, secrets and their item pages) each carried their own copy of
the links to the host's sections, as a breadcrumb: the sections are
siblings, not a path, and on a phone the separators were left at the
start of wrapped lines. The item pages marked no section at all.
computes/host_nav.html is the one nav, labelled "Host sections": pills
that wrap, the page's section marked active, with aria-current="page"
on the section's own page and "true" on an item of it.
Twenty-five prompts asked only "Are you sure?", and on the storage page
one handler asked the same before every button, Start and Enable
included. Each destructive button now names its object and says what
happens: a stopped network cuts running VMs off, a deleted pool keeps
its files, a deleted volume loses its data, a reverted snapshot loses
the changes made since. Saves no longer ask, and disabled buttons lose
prompts they could not show. The VM QoS messages said to restart the
network where the VM has to be powered off and on.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Column offsets without a breakpoint applied below it, where the column
is already full width, so the change password, compute, user, VM
create and VM settings forms ran past the right edge on a phone. Each
offset now starts at its column's breakpoint. The interface and network
detail lists were rows directly inside rows and sit in a column now;
the compute form loses a Bootstrap 3 thumbnail padding that broke its
gutters, and the add-rule dialog's hint is no longer cut off. The page
test checks both grid rules on every page.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Twenty tables had no .table-responsive wrapper, so on a phone the user
list, compute list, VM lists, network and network filter pages scrolled
sideways as a whole. Each table now scrolls inside its box, as the
other ten already did. The page test walks the network page too, and
checks that every table on every page has the wrapper.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
libvirt's udev interface backend (RHEL 9 and later, Debian 12) only reads
interfaces, so the create form and the start, stop and delete buttons
only failed there. The pages ask the host with an invalid definition,
which defines nothing: a backend without define refuses it as not
supported. There they show the interface state and a note instead, and
posts change nothing; the host's devices, needed only by the create
form, are not read. Any other answer keeps the pages as they were.