1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 19:56:48 +00:00
Commit graph

13 commits

Author SHA1 Message Date
catborise
3baa93048b chore(deps): a list's search is kept in sessionStorage, without js-cookie
js-cookie served only table_filter.js, which kept a list's search in a
cookie for a day; the cookie went to the server with every request.
The search is now kept in the tab's sessionStorage: it stays across
reloads and pages in that tab, a new tab starts empty, and the server
never sees it. The library goes.
2026-11-05 12:37:51 +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
0fd3e69c8e feat(instances): the VM page's add dialogs in the panel's dialog look
The Add disk, Add network device and bandwidth dialogs of the VM page
set their labels in a narrow column beside the fields and closed with
a grey Close: Add disk split "GB" over two lines and offered an
unexplained Metadata box, its existing-volume pool was a dropdown of
links that wrote a hidden field; the network list prefixed every
choice with "Network" or "Interface"; the bandwidth fields asked for
"kilobytes" where libvirt counts KiB/s and KiB.

Now their labels sit above the fields, tied to them, in two columns.
Add disk is one form whose source, New disk or Existing volume, is a
radio card as in the new VM form, the chosen source's fields shown and
sent and its action taken; the size has a GiB suffix and
"Preallocate metadata (qcow2)", the existing volume's pool is a select
that loads its volumes, the bus and the cache are shared. Add network
device picks its
source from Networks and Interfaces groups and says how its MAC is
filled; the bandwidth limit names its units and when a running VM gets
it. Move says when the host has no other pool and is disabled then.
Every dialog closes with Cancel and its action; the posted fields are
unchanged.
2026-10-31 18:35:09 +03:00
catborise
51d24fce30 feat(instances): migrate a VM with its disks copied into pools of the destination
A migration needed every disk on storage both hosts share: it was refused
when the destination lacked a disk file, and a file of the same name
there was taken for the VM's own disk.

The Migrate tab now lists the VM's disk files for the chosen destination.
For each disk it offers the destination's pools that keep disk files
(directory, filesystem and NFS pools). A disk on storage both hosts share
can also stay where it is.

A directory counts as shared when both hosts have it as a storage pool
and a marker file created on the source exists on the destination. A
directory the probe cannot tell is never taken as shared.

libvirt copies the chosen disks during the migration: migrate3 with
NON_SHARED_DISK for those targets, and destination and persistent
definitions naming the new paths, where libvirt creates the files.

- A shut-off VM is started paused for the copy and shut off on the
  destination; its CPUs never run. Its UEFI variables are copied first,
  as the destination would start from the firmware's template. If the
  migration fails, the VM is shut off on the source again.
- Refused before anything changes, each disk with its reason:
  - a disk neither shared nor given a pool, also one only the next
    start's definition has;
  - CD-ROM images, read-only or encrypted disks, formats other than raw
    and qcow2, and disks with a backing file;
  - a pool that is not of disk files, or that has a file of that name,
    which libvirt would reuse and overwrite;
  - two disks copied to one file.
- The job claims each copy's name in its pool, and the source volume.
- A failed or cancelled migration deletes the copies libvirt made, and
  the UEFI variables copy, unless a VM on the destination has them.
- The source files stay and are named in the log. With "Delete the
  source files of copied disks" they go, except one another VM or volume
  uses; a failed delete is logged and the migration stands.

The NVRAM sharing check uses the same probe: a shut-off move stops when
it cannot be told, and the source file stays.

The API's migrate call takes disk_pools ({target: pool}) and
delete_source.
2026-10-29 19:46:31 +03:00
catborise
80dd145bcf feat(instances): PCI devices of the host given to a shut-off VM
- 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.
2026-10-29 14:20:34 +03:00
catborise
ac8ff62e7e feat(instances): USB devices of the host given to a VM
- 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.
2026-10-29 13:33:23 +03:00
catborise
c1d36053d6 feat(logs): every VM operation writes an audit row the VM's Logs tab finds by UUID
Operations on a VM now write their rows the way the admin audit does: one
row per operation, done or failed with a safe reason, with the user, IP and
host. Each row names the VM ("VM web-1: delete snapshot snap1") and carries
its UUID in the new Logs.instance_uuid column.

- audit_vm and failed_vm wrap audit() and failed() for a VM. A failure the
  view turns into a message is caught outside the block, so its failed row
  is written; busy claims, permission and quota refusals and invalid input
  write nothing. No password, key or XML goes into a row.
- All VM page operations move from addlogmsg to audit_vm, and addlogmsg
  goes. QoS changes and defining a VM from XML are logged now; a gstfsd
  error reply (root password, SSH key) is a failed row, not a done one.
- Partial results are rows of their own: the VM delete, then each disk
  delete; the disk detach, then the volume delete; the migration, then a
  failed autostart restore, NVRAM removal or record on the target.
- Migration rows use the compute name as the host column, as every other
  row does.
- VM job rows (create, clone, snapshots) and their resolutions carry the
  VM's UUID; snapshot job intents now record it. The owner rows of the VM
  page and the accounts pages, and the ownership system rows, carry it too.
- The Logs tab loads vm_logs/<pk>/ and shows the rows with the VM's UUID,
  so a rename keeps the history, two VMs with one name are told apart and
  a VM on two computes is one VM. It gains a Result column. Rows from
  before this change have no UUID and stay on the Logs page only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 14:14:53 +03:00
catborise
aa720e09e8 refactor(computes): drop the unused domain capabilities endpoint
No page or script called it, and it answered with the disk device
types for both videos and buses. The create view keeps reading the
domain capabilities through wvmConnect.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 09:01:25 +03:00
catborise
96141c3ef7 fix(instances): a refused custom VM form comes back with its disks and networks
A refused custom create form came back with its image pool unselected
and its disk and network lists empty: every disk's device and bus and
every MAC had to be chosen again. Adding a disk or a network also reset
the rows already there: each addition rebuilt all rows from an HTML
string, so the earlier disks fell back to the default device and bus
and every NIC got a new random MAC, a typed one included.

The view sends the submitted pool, disks (volume, device, bus) and
networks (name, MAC) back with json_script, built field by field from
the POST (submitted_custom_lists). The rows are cloned from two
<template> elements and filled with textContent and listeners; one
function, sync_custom_lists, derives the images, networks and mac
fields and the device<i>/bus<i> names from the rows in order. Adding or
removing a row leaves the others as they are, and a random MAC that
arrives after one was typed is dropped. On load the page selects the
pool, waits for its volumes, rebuilds each disk with its device, waits
for that device's bus list and selects its bus, rebuilds the networks
with their MACs, and then focuses the first error. A submitted value the
loaded lists no longer have stays selected. The bus and volume loaders
return their requests so that the page can wait on them.
2026-10-20 21:24:36 +03:00
catborise
d37aa42392 feat(console): a working serial console
The xterm console never connected: socketiod expected a different token
format, its worker had no compute credentials, one global console was
shared by every client and its output broadcast to all of them, and the
Docker image did not run socketiod at all.

- console/tokens.py: one authorize() for noVNC and socketiod; the signed
  token is the only credential, checked at connect time.
- socketiod: one pty worker per client (consolecallback with the
  instance id), one session per VM, a session cap, input and resize
  checked; the parent never opens libvirt. The engine.io same-origin
  check is on.
- consolecallback: opens the console with the compute's credentials and
  exits with a message when it cannot.
- Docker runs socketiod as a runit service; nginx proxies /socket.io/
  with Host and the scheme for the origin check. Supervisor and systemd
  start it as well; WEBVIRTCLOUD_SERIAL_CONSOLE=1 enables it.
- Tests: token and session unit tests, socketiod as a process, and a
  live test that reads SeaBIOS from a wvc-test VM on the TCP and SSH
  hosts.
2026-10-17 19:43:09 +03:00
catborise
c55f52f025 test: each app keeps its tests in a tests package
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.
2026-10-12 15:17:30 +03:00
Renamed from instances/test_xss.py (Browse further)