- noVNC's own web client (app/ except the bell sounds, vnc.html,
vnc_lite.html, defaults.json, mandatory.json): the console imports
only noVNC's core, and novncd serves no web pages. AUTHORS, LICENSE.txt
and package.json (the version) stay.
- 24 cached icons no {% bs_icon %} asks for; the icon cache test now
also fails on an icon nothing uses.
- Ace's ext-textarea.js, which nothing loads.
- instances/fixtures/initial_data.json, for an app ("create") that no
longer exists; migration 0006 seeds the flavors.
- webvirtcloud/asgi.py: gunicorn runs the WSGI application only.
- instances/templatetags/tags_active.py: a copy of common_tags'
class_active that no template loads.
- .github/linters/.hadolint.yaml, from super-linter, which no workflow
runs anymore.
The Jobs list sits in a card: the count and the filters in its header,
the job with its phase, its progress and its date in one cell, the state
at the row's end.
The job page is one card: resource, user and state on top, then the
phase, Cancel and the progress, the error and the results, and a
timeline that says how long the job waited and ran. Resolving an
uncertain job folds into its own card.
The Users, Groups and Removed VMs pages were bare tables: rows of
coloured icon buttons without words, five columns of small checks for
a user's role and permissions, dates broken over three lines and a
lone "+" for a new entry. The owner chose a directory layout from three
rendered options; it follows the host pages' cards:
- Each list is a card with its count and search in the header and one
list-group item per entry, which stacks on a phone without scrolling.
- A user shows their role as a badge (Superuser, Template editor) or
"User", Blocked as a red badge, their groups, a granted clone
permission and live API tokens, and the last login on one line;
role and status are searchable. Edit is the visible action, the menu
holds View profile, Block or Unblock and Delete; Block and Delete
are disabled on one's own account, which the server refuses anyway.
- A group shows its member and permission counts; its name opens it.
The page's title said "Users".
- A removed VM shows its UUID, the host it left, its owners and when
the record was made and expires.
- Logs keep their table in a card, the server search in its header,
the count of matching rows, Done and Failed as badges, and a message
column wide enough to read on a phone.
The user form was one long column of horizontal fields. The owner
rejected three boxed layouts and chose one led by what the user may
do: the Active switch, Template editor and Superuser as two cards,
groups as chips, the user's own permissions as switches each saying
what it allows, then the name and password and the quota folded into
details whose summaries tell their values (-1 as "any"); they open on
a new user and on an error inside them. A refused group or permission
is said beside its field. The group form follows it: the name, what
its members may do, its members as chips. Cancel goes back to the
list instead of the browser history.
Settings > Network was a table whose fields were read-only inputs cut
off at phone width, an unlabelled "+", three icon buttons per NIC and
a separate QoS table keyed by MAC. The owner chose card layout from
three rendered options, with the QoS limits folding out like the
device details:
- A card per NIC: a VM's only NIC spans the row, two or more sit side
by side from md. Each has its name and target, the link state as a
switch, its source and IPv4 addresses, and "Device details"
(type, MAC, model, NWFilter, IPv6) in a <details>.
- "QoS limits" in a second <details>, its summary naming the limited
directions: a form per inbound or outbound limit, with Save and
Delete limit, and the units.
- Labelled Edit, Add QoS and Delete in the card footer; "Add network
device" by the heading. The edit and add-QoS dialogs are titled and
labelled, and the edit dialog's fields have labels.
The limits come from each NIC of the persistent definition, so the QoS
table, Instance.config_qos and wvmInstance.get_all_qos are removed.
Settings > Disk was a bold title with an unlabelled "+", a CD-ROM row
in an input group, and a table whose actions were four alike icons.
The owner chose this layout from three rendered options:
- Removable media: each CD-ROM drive a card with its device, bus and
image, the ISO select and Mount (or Unmount), and Detach; "Add
CD-ROM" by the heading.
- Disks: a card each; one disk spans the row, two or more sit side by
side from md, and the device details are capped at 32rem so values
stay near their labels. The capacity large,
the used size, the pool and the source path, the device's settings
under "Device details" (they were in a popover), and labelled Edit,
Move, Detach and Delete (danger) in its footer; "Add disk" by the
heading.
- While the VM runs, "Add CD-ROM" adds the drive on the SCSI bus, and
a SCSI drive can be detached: IDE and SATA drives cannot be plugged
into or out of a running VM, SCSI ones can. Adding a drive was
disabled while the VM ran. One line says so, and why detaching other
drives and detaching or deleting disks waits for a shutdown, instead
of each button alone being greyed.
The forms, their fields and actions are unchanged. The edit dialog of each
disk is titled with its device, and its fields' ids carry the disk's
number: the dialogs of two disks had the same ids, and the title was not
the dialog's label.
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.
The Disks tab has a Move button for each disk: it opens a dialog to
choose another storage pool of the same host, and the move runs as a job.
- Running or paused VM: libvirt copies the disk with a block job
(TRANSIENT_JOB, as the VM is persistent) into a file it creates in the
pool, then pivots. The pivot names the copy in both the running and
the next start's definition.
- Shut-off VM: the volume is copied into the pool and the copy named in
the definition.
The source file goes then, unless a VM or volume of any compute uses it
(shared storage holds it for every host that mounts it), a compute
cannot be read, or the delete fails: the job lists such a file under
"Left behind", and the move stands.
A disk moves when:
- the VM is defined and running, paused or shut off, without snapshots,
a saved state or a block job;
- the disk is a writable, unshared, unencrypted raw or qcow2 file of a
storage pool, without a backing file, and the same file in both
definitions;
- the pool keeps disk files, is another directory, and has no file of
that name (libvirt would write into it).
Otherwise it is refused with the reason before anything changes.
The job claims the VM and the file's name in both pools. A cancel aborts
the block copy, and ends the job cancelled once the VM is back on its
file. A failed move deletes the copy it made, unless a definition names
it (a lost reply after the pivot); a file there before the copy began is
never deleted. Recovery after a stopped worker
ends a copy left mirroring, matched by its destination, and reads the
outcome from the definitions.
Superusers only, like the other disk edits.
- A Devices section of each host lists its PCI devices by IOMMU group and
its USB devices: what each is (vendor, product, IDs, class, driver), what
the host itself has on it (its network interfaces, disks and graphics
card, anywhere below it) and the VMs whose definitions name it.
- A VM names a PCI device by its address, a USB device by its address or
by its model only; a VM that names a model only is shown on every device
of that model, which one it takes is known only when it starts.
- A host without IOMMU groups says that no PCI device can be given to a VM
and how to turn the IOMMU on.
- One listing of the host's node devices, one XML read each (a device gone
meanwhile is left out), and the VMs' definitions read once; nothing is
shown when they cannot be read, as a device would look free.
- Read only: giving devices to VMs comes in the next layers.
- A DHCP leases card on the page of a network that serves DHCP: each
lease's address, MAC or an IPv6 client's DUID, the host name the client
sent, the VM whose card has that MAC, linked, and when it ends.
- A lease that is a fixed address is marked; any other in one of the
network's DHCP subnets has a Make fixed button that fills in the fixed
address dialog with its address, MAC or DUID and name.
- Leases that cannot be read are said on the card; the rest of the page
stays. A network that does not run has none.
- The VMs on a network are read with the MACs of their cards on it, from
the definitions already read.
- One searchable card: each secret's type, usage and UUID, whether it is
kept on disk or in memory and private, and the VMs and pools that use it,
linked. A row menu sets its value or deletes it; Delete is disabled while
the secret is in use, and its confirmation says what is not checked.
- One Set value dialog for every secret; its label and help follow the
type (Ceph key, CHAP password, passphrase), and it says a new passphrase
does not encrypt anew what the old one encrypted.
- New secret dialog: the usage's and value's labels and help follow the
type; the value is optional; Private and Ephemeral are switches with help.
- The pool list is a card per pool, two to a row, as the host
Overview's Hardware and Software cards: its name with Active or
Stopped and Autostart badges in the header, then its type, its path
(an RBD pool's Ceph pool), its volume count and its space as the
Overview shows it (computes/pool_bar.html, without the name again);
a stopped pool's space is unavailable, not zero.
wvmStorages.get_storages_info gives the path, autostart and percent
used, which computes.views.host_pools computed for itself.
- A pool's page has a Space card (percent, used of size, of what: the
filesystem of its path, its volume group or the Ceph cluster, which
other pools may share; free) and a Pool card (state, autostart,
type, path) instead of a two-column list mixing facts and forms.
Start or Stop is its heading's button; autostart and deleting a
stopped pool are in its menu; the confirmations stay.
- The volume table drops the row number; a volume's capacity and what
it has allocated share a column hidden on a phone; its format is a
badge; its actions are one group, Clone and a menu with Delete,
named for the volume.
- "New pool", "New volume" and "Upload ISO" are labelled buttons
instead of bare green pluses; their dialogs' titles name them.
- The New pool dialog is one form (design reviewed with Codex): the
pool's type as radio cards, as the VM create page chooses its disk
source (their style moves to webvirtcloud.css), one name, and only
the chosen type's fields, the others hidden and disabled.
- A directory's or a share's mount path follows the name
(/var/lib/libvirt/<name>) until it is edited: no default path of
another pool any more.
- ISO images is a directory preset named iso; when the host has an
iso pool, a card links to it instead.
- Ceph offers the host's Ceph secrets by their names, not every
secret by UUID; without one it says so and links the Secrets page.
- LVM asks to agree that the device is erased, the server too.
- AddStgPool checks each type's fields, a name or a path another
pool has, an RBD secret that is not one of the host's Ceph secrets,
and the names "." and "..". A refused pool, or one libvirt refuses,
opens the dialog again with what was entered, the reasons beside
the fields and focus on the first; the audit row for a taken name
stays.
- The state filter is a row of pills, All and each state, counting the
VMs the search finds (the chosen state aside); a state without any is
hidden unless chosen (All never), and a status line tells screen
readers how many VMs match. Every state keeps its pill.
- A labelled "New VM" button replaces the bare green plus; "Find IP"
says "Find IP / MAC", which it finds.
- States are badges; a shut-off VM is grey, not red: it is not a fault.
- A VM's cell holds its name, its title, and for those who see owners
its first owner as a badge, "+N" for the others (named for screen
readers and on hover); the separate user column goes.
- Each row has the same button group for a superuser or the VM's
owners, from the actions the user may use (states.allowed_actions),
all of it disabled on a VM an administrator paused; view-only users
get none. It holds Console, the power action
the state calls for (Start, Resume, Shut down, or Clone for a
template) and a menu of the others (Suspend, Force off, Power cycle),
what does not apply now disabled. The power button is an icon,
named on hover and for screen readers, so every group is as wide and
they line up from row to row; the power cut confirmations stay. On a
phone Console shows its icon only too.
- A grouped host's row has its name, a Connected or Not connected
badge, its VM count and a labelled host memory bar; an unreachable
host's row is table-warning. Its collapse control and the one for
all hosts are buttons, with aria-expanded kept.
- vCPUs and memory hide on a phone in both layouts, and table cells
keep Bootstrap's own padding there: Zephyr doubles it and a list's
last column no longer fit the screen.
- Totals above the list: hosts connected of all, VMs running of all,
vCPUs given on the CPUs, memory given of the memory of the hosts the
panel reads, as cards; the connected count is red while a host is
not.
- A host's name links its overview; its state is a Connected or Not
connected badge (the dot goes), beside a badge of how the panel
reaches it (TCP, SSH, TLS, Socket); its address in monospace.
- A VMs column: the host's VMs, linked to its Instances, and how many
run.
- The vCPUs have a bar like the memory's: running VMs' and shut-off
VMs' vCPUs against the CPUs, amber over 2:1 and red over 4:1 as the
ratio is; the overview's vCPU card shares it.
- The three coloured buttons of each row are one menu: Overview, Edit
connection and Remove from panel (its popper fixed, as the table's
scrolling box would cut it off).
- The four green add buttons are one "Add host" menu that says what
each kind of connection is.
- The table is table-hover; a host the panel cannot reach has a
table-warning row.
The memory given read "24.0 GB given of 32.0 GB": long, and the share
of the host's memory, what one looks for, had to be worked out. It is
now told as the vCPUs are: the share large ("75 %", amber over 90 %,
red over 100 %), then "24.0 GB / 32.0 GB", the bar and "12.0 GB
running". The Computes list's memory column shares it.
Every card of the overview has a Bootstrap card-header with an icon:
VMs, vCPUs, Memory, Storage, CPU in use and Memory in use (with the
current reading at its right), Hardware, Software and connection. The
last two were label and value lists under indented headings; they are
list-group-flush rows now, the label at the left, the value at the
right: counts in semibold, the hypervisor's and libvirt's versions as
badges, the guest architectures as light badges, the emulator and the
connection as code. The section headings, indented by the panel's
page-header margin unlike the cards, are gone: each card names itself.
The status line and notes are not paragraphs, which the panel indents.
A host the panel could not reach made its overview the 500 page,
without the host's sections, and the Computes list gave such a host an
Overview button that led nowhere. The page now keeps the host's name,
sections, "Edit connection" and "Remove from panel" (the existing
confirmation), and says "Not connected" with the reason and a "Try
again". Details that cannot be read are said in an alert; the VMs,
capacity and load still show, as they are read on their own.
A reachable host's page leads with what it runs and what it gave:
- its VMs by state (running, shut off, paused, other), linked to
Instances;
- the vCPUs, memory and storage pools given, as on the Computes list,
which now shares those parts (computes/capacity_*.html) and their
preparation (views.shown_capacity) with it;
- CPU and memory in use, side by side, with the current reading in
words, a note on what the charts hold and when they were last
updated, or since when not; memory in GB like the rest of the page;
- Hardware and Software and connection: logical CPUs and clock from
virNodeGetInfo, but physical cores, sockets and NUMA nodes counted
from the CPUs of the capabilities' NUMA cells, as virNodeGetInfo
makes a topology up for hosts it cannot describe (asymmetric NUMA);
the hypervisor's own name and version, libvirt, emulator, the guest
architectures as text instead of menus of dead links. A host without
sysinfo shows no processor instead of failing.
Empty notes no longer show "None"; labels stack over their values on a
phone instead of running into them.
Pools that cannot be read no longer drop a host's vCPUs and memory from
its capacity: the storage part says so. get_capacity also counts the
VMs by state.
The create page had three tabs (flavor, custom, template), each with its
own copy of the same create form; every flavor rendered one more copy in
a dialog, and fixes had to be made in each copy. All of them posted the
same form to the same job, differing only in where the disk comes from.
The page is now one form in sections: name and size, disk, networks and
an Advanced section. The disk section offers three sources as radio
cards (a new disk, existing volumes, a copy of a template); only the
chosen source's fields are shown, and the others are disabled, so they
are neither sent nor validated. A template's copy goes into the
template's pool unless another is picked. Flavors are presets that fill
vCPU, memory and disk size and pick a new disk; they are added and
deleted in a dialog outside the form. Every source uses the
per-interface network rows, so a new disk no longer requires a MAC:
libvirt gives an interface without one its address, as it did for the
other sources. A refused form comes back with its source, volumes,
template and networks, and the focus on its first error. Without a
storage pool or a network the page shows why instead of the form, and a
host that cannot be read is a message, not a 500.
The host dialog and the machine page share the form's look: hosts are
rows with their CPU and memory use, the machine page is a card with
Cancel/Next and the XML way is a collapsible section. All three steps
show the same step indicator, done steps linking back.
The create job refuses more than one disk source (the page sends one; a
crafted request could send two, and the job would have used the first).
A field with help text is described by its help and its error.
Frontend review fixes: the presets and the disclosure buttons show a
focus ring for keyboard users; a disclosure spans its card and its
chevron turns while open; a preset says it picks a new disk; numeric
fields bring a numeric keyboard and MAC fields no autocorrection; the
machine page's Next waits for a machine type. Tom Select's control
keeps the text colour of the select it replaces: its own fixed colour
made typed text invisible on dark Bootswatch themes, on every page that
uses it.
django-bootstrap-icons serves icons from static/icon_cache and fetches a
missing one from the CDN while the page renders; a server without
internet access shows an error text instead of the icon.
- copy (Clone on the instance lists), envelope-open ("Lost OTP?" page)
and save (VM settings, network page) were not cached; they are now,
fetched with django-bootstrap-icons itself.
- The user and group lists asked for 'exclamation-triangle ' with a
trailing space, an icon that does not exist; the warning icon never
showed.
A test checks that every {% bs_icon %} in the templates has its cache
file; it fails on the previous files.