Tests that build vrtManager objects and touch no view, form or model of
an app lived in that app; vrtManager/tests already holds such tests, so
the convention was split. They move to vrtManager/tests: the firmware,
CPU mode and PCIe port definitions of a new VM (test_create), USB and PCI
host devices, the console listener, host CPU reads, interface reads,
deletes and XML, network filters, PCI passthrough rules, node devices,
network changes, addresses and leases, pool XML, secrets, and the live
tests that use vrtManager only (disk resize, ISO, snapshots, XML, live
clone). livetest.py, the live-test helper six apps import, and the
network test driver move with them.
Others go to their app: the quota with a host down to instances, the
401/403 Logs rows (webvirtcloud's middleware) to webvirtcloud, the VM
page's tab script test to instances, novncd's own tests out of the
console views tests, the compute lock and input validation tests out of
the computes views tests, the interface views out of the forms tests.
instances/tests/test_views.py, entirely live, is test_live_views.py.
Test modules imported fixtures from each other; shared ones are now in
vrtManager/tests/fakes.py (migration fakes, node devices, IOMMU groups,
leases, a NAT network, a Ceph secret), interfaces/tests/fakes.py,
console/tests/daemons.py (novncd loaded once), livetest.wait_for and
instances/tests/create_page.BODY. Every live test checks
livetest.enabled(). The suite runs the same 2097 tests.
As the storage and network pages; plan reviewed with Codex.
- The list is grouped by type (bridges, bonds, VLANs, ethernet; a type
the host has none of is left out), three cards a row, with a search
of their names, MACs and networks (table_filter.js, which now takes
any element with data-search as a row); a card per interface: its link
as the kernel reports it (up green, down grey, another state or
unknown told as such, no red card for a link that is merely down),
MAC, MTU, speed when known, the members it reports and the libvirt
networks that use it, linked.
- An interface's page: an Interface card (type, libvirt's own state
where it manages interfaces, link, start mode, MAC, MTU, speed, STP,
networks using it); on a host whose libvirt changes interfaces, a
card per family with how it is addressed and its addresses; the
members of a bridge, bond or VLAN with their link and speed, or that
none is reported; for a bridge, the running VMs' cards on it,
directly or through a network using it, with their tap and MAC,
linked (wvmInterface.get_vms: one domain listing). Not the bridge's
delay: netcf tells it in seconds, the udev backend in hundredths.
Start or Stop in its heading, Delete in its menu, disabled while it
runs, on hosts that can change interfaces only.
- A host whose libvirt only reads interfaces says so once, with that
it does not tell their addresses, instead of "None" on every page.
- The New interface dialog is one form, as the New pool and New
network ones (choice_dialog.js, radio_card.html): Bridge or
Ethernet, a bridge's member from the devices it can take, an
ethernet interface's device from the ones the host does not define
yet, a static address's fields with its choice; a refused interface,
or one libvirt refuses, opens it again with what was entered; a made
one opens its page.
- networks_by_device maps the libvirt networks to their bridges or
interfaces on the page's own connection.
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.
- The create form refuses a name the host already defines. Defining it
again replaced that interface's configuration, for example the host's
own uplink when a bridge was named after it.
- An interface that does not start is undefined again, so the name is
free for another try; the name check above makes this safe.
The Logs page now records every change an admin makes to a compute's
libvirt objects, with the compute's name in the host column:
- networks: add, start, stop, delete, autostart, DHCP range, fixed
addresses, QoS and XML edits;
- storage pools: add, start, stop, delete, autostart, from web and
API; volumes: add and delete (web and API), clone and ISO upload;
- host interfaces: add, start, stop, delete;
- secrets: add, set value (never the value), delete;
- network filters: add, clone, delete, XML edits, rules and
references.
A refused or failed change is a failed row with its reason (libvirt
text through safe_text). The volume clone and upload jobs write their
row when they end; a refused submission is a failed row at once. A
volume row names the volume libvirt created (a dir pool adds .qcow2 or
.img). Volume create or delete through the API on an inactive pool
(409) is a failed row.
Network filters: the rows read "Network filter f1: add" instead of
"f1 network filter is created", and their host is the compute's name
instead of its hostname. A duplicate name or UUID no longer raises a
bare exception, and a filter XML that cannot be parsed no longer ends
in UnboundLocalError.
With the netcf backend (RHEL/AlmaLinux 8), undefining a bridge also
removes its members' configuration: the device came back without any
after a reboot. Like virsh iface-unbridge, each member is now defined
again on its own after the bridge is undefined, with the bridge's start
mode and, when it is the only member, its addresses. A bond keeps its
mode and devices.
Checked on AlmaLinux 8 (libvirt 8.0, netcf): an ethernet and a bond
member get their ifcfg back, and the bond comes up with the address
after a reboot.
131 test modules sat next to the code they test; instances alone had
51 of them beside views.py and utils.py. They move into a
tests/ package per app, and the JavaScript checks into
webvirtcloud/tests/js. Each non-empty tests.py becomes tests/test_views.py;
the empty generated stubs are removed.
Imports of the app's own modules become absolute, paths built from
__file__ go one level up, the live helper is instances.tests.livetest,
and coverage omits */tests/*. The suite discovers the same 960 tests as
before.