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.
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.
The top of a VM's page was one line of values between pipes, an icon for
the guest agent and a hidden snapshot count, then a row of big action
icons; the host links sat in a bar fixed to the bottom of the window,
over the content.
One card now holds it all (design chosen by the owner from four):
- the name with the state badge, the title under it, and where the VM
is: its host and the host's VM list for administrators, the VM list
for owners;
- OS details (with a connected guest agent) and Refresh;
- the guest agent's state in words and the snapshot count;
- CPU, memory, each disk with its device name and size, and the IPv4
addresses, labelled;
- the page's sections as small labelled pills in the card's footer: one
row from 992 px, wrapping below.
The page has no other heading: base.html's heading area is a block it
leaves out.
Each section below it (Power, Access, Resize, Snapshot, Settings, Stats,
Destroy) is a card of the same kind, so the page reads as one design
(owner's choice of two): its sub-tabs as a small underlined nav in the
card's header, its panes in the card's body without their own borders.
Buttons are of normal size in the theme's primary colour, and those that
cannot be undone (Power Cycle, Force Off, Destroy) in the danger colour.
The Stats charts lose their coloured borders. instance_tabs.js finds the
Settings tabs by their tablist role.
The bottom bar and its setting (VIEW_INSTANCE_DETAIL_BOTTOM_BAR) are
removed, and with it the CSS that kept the old Settings tabs on one line.
Queuing a long operation put "... is being ...; follow it in the job
panel." above the page, while the job panel on the same page showed the
job and its progress. Every such form returns to a page with the job
panel for the job's resource (the VM, the compute's VM list, the pool),
and the panel shows a job even when it ends before its first poll. The
eight messages are removed: migrate, clone, create, volume clone and the
snapshot create, revert and delete jobs. Refusals stay messages.
- The Host devices tab gives a shut-off VM a PCI device of its host and
takes it back; libvirt binds the device to vfio-pci when the VM starts
and gives it back when it stops (managed). The VM's PCI devices are
listed with whether the running VM and its next start have them.
- A device is offered, and accepted on the server under the compute's
claim, only when it is no bridge of any kind (bridge header, PCIe port,
or of the bridge class: host bridge, LPC), the host has none of its own
network interfaces, disks or graphics card on it (else: bind it to
vfio-pci on the host first), no other VM names it, and every other
endpoint of its IOMMU group is the VM's too or has no driver or
vfio-pci and no other VM; bridges in the group stay with pcieport, and
a member that cannot be read keeps the group. Nothing in the group is
taken implicitly.
- A snapshot revert checks the PCI devices of the snapshot with the same
rules; migration and clones already leave host devices out.
- The add forms of the tab load together, when the tab opens.
- A Host devices tab on the VM page lists the VM's USB host devices, each
once: how it is chosen (its address, or any device of its model), the
device the running VM holds and whether its next start has it; its other
host devices (PCI, SCSI, mediated) are listed for the XML editor.
- Superusers add a USB device of the host and take it back, on a running
VM too. The add form is loaded when the tab opens, as its choices read
every VM of the host; a hub, a device the host has its own disks or
network interfaces on, or one another VM names is not offered, with the
reason, and refused on the server under the compute's claim. A device is
chosen by model when the host has one of it, else by its address.
- A VM without a USB controller is refused; a device is taken from each
definition as that definition describes it.
- A clone gets none of the VM's host devices (the clone form says so), and
a VM with host devices is not migrated. A snapshot revert is refused when
it would give the VM a device another VM names or the host uses.
- A NIC that is a host device is no longer edited or removed from the
Network tab: the XML editor changes it.
A disk-only snapshot was taken without any space check, though its
overlays grow as the guest writes and a later delete merges them down;
a full pool pauses the guest and can leave the snapshot undeletable.
Only a memory snapshot was checked, for the memory alone.
Before a snapshot, each storage pool with a disk of the VM must have
free a share of those disks' virtual size (10%, at least 1 GiB), and
the pool of the memory file the VM's memory on top. Both values are on
the Settings page (Snapshot Free Percent, Snapshot Free Min GiB; 0
turns a rule off, an invalid value keeps the default). The pools are
refreshed first, and a failed refresh or an unreadable volume refuses
the snapshot instead of skipping the check; a disk in no pool is not
checked. Nothing is reserved: later writes can still fill a pool.
A disk-only snapshot of a running VM is crash-consistent: data the
guest has not written yet is missing from it. With a connected QEMU
guest agent, the snapshot form now offers to freeze the guest's file
systems while the disks are snapshotted (libvirt's QUIESCE flag); the
box is checked by default and can be cleared. It is offered only for a
running VM whose agent is connected, and not together with memory:
libvirt accepts quiesce only for disk-only snapshots, and a memory
snapshot keeps the whole guest state anyway. A request that does not
fit is refused before libvirt is called.
Reverting a running or paused VM to a disk-only external snapshot
powers it off: libvirt starts it again from the snapshot's disks, as
after a power cut. The confirmation now says so for such a snapshot; a
snapshot with memory resumes the VM as it was saved.
The snapshot tab listed the VM's snapshots three times per page: once
per kind and once more for all of them. The list of all is now made
from the two kinds, so the combined flag is no longer used anywhere.
The revert confirm named only the disks the persistent definition
would lose. A disk hot-plugged into the running VM alone is detached
too, so the live definition is compared with what ran when the
snapshot was taken.
A storage pool refresh error after libvirt had already made, reverted
or deleted the snapshot was shown as if the operation had failed. It
is now logged, and the left-behind check is skipped then, since a stale
pool still lists the removed files. A volume removed while that check
reads it is skipped too.
An error reading the block jobs no longer breaks the instance page;
create, revert and delete still query the jobs again and refuse.
When libvirt cannot remove a snapshot file it merged or discarded, it
only logs a warning and the delete or revert still succeeds. On NFS it
removes them as the qemu user, so an image directory the qemu user may
not write to left every merged overlay on disk without a word.
Revert and delete now compare the files in use before and after and
show a warning naming the ones still on disk. Only a snapshot's own
files (overlays, memory) and overlays on a snapshot point count, and a
disk the revert detached is never named, so a kept disk is not offered
for removal.
Create, revert and delete are one libvirt call each. The pflash-to-rom
loader rewrite, the hand-written block commit and the s1./s2. names are
gone, so UEFI VMs can take external snapshots, a revert keeps disks added
later, and deleting an older snapshot keeps the newer one.
Create refuses what libvirt could not revert or delete later: internal
snapshots on the VM, a saved state, a running snapshot job, disks that
are not files, CD-ROM media, a branch after a revert, and memory without
a running VM or room in the first disk's pool. A disk-only revert keeps
the VM running, paused or shut off; one with memory resumes it as saved.
A revert in the same second as the previous one, which libvirt fails
after stopping the VM, is retried once.
A snapshot the old code took of a UEFI VM saved the loader as rom; its
revert is refused (deleting it still works).
The snapshots tab lists internal and external snapshots separately, can
save memory too, shows running snapshot jobs, and the revert confirmation
names the disks it detaches and that NVRAM is not restored.