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

19 commits

Author SHA1 Message Date
catborise
1284b93705 feat(computes): memory given as a share; the overview in Bootstrap cards and lists
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.
2026-10-27 16:32:39 +03:00
catborise
591ec4a1f5 fix(computes): the host sections are a breadcrumb again; capacity lines wrap in their card
#241 made the host sections pills: on a desktop they took two lines,
unlike the breadcrumb the pages had. computes/host_nav.html is the
breadcrumb again, one line at 1200 px and wider, still shared by the
eleven host pages: the section's own page is its bold item with
aria-current="page", an item page (a pool, a network) links its
section in bold with aria-current="true".

The capacity lines were kept on one line, made for the Computes
table: in the overview's narrower cards a long memory line ran out of
its card. They now wrap.
2026-10-27 16:32:39 +03:00
catborise
1b99d2eac5 feat(computes): the host overview shows its VMs, capacity and load, also when it cannot be reached
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.
2026-10-27 14:51:18 +03:00
catborise
86c708ed68 refactor(computes): the host pages share one section nav
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.
2026-10-27 14:51:18 +03:00
catborise
726f330dd0 fix(api): host API checks what the web forms check
- An API volume takes the name and size the web form takes. Its name went
  into the volume XML unchecked, so a name could add elements such as a
  backing store pointing at another VM's disk; the name is also escaped
  there now. A size of 0 and metadata preallocation on a non-qcow2 volume
  are refused or dropped, as on the web form.
- An API compute update with an empty or null password keeps the stored
  one, as the web form does; it emptied it and cut the host off.
- The architectures endpoint answers 404 for an unknown compute instead of
  500; an unrouted copy of it is removed.
2026-10-26 17:47:18 +03:00
catborise
9e02286926 fix(computes): host pages survive a down host and a vTPM secret
- The host graphs and the machine/bus lists connect inside their libvirt
  error handling, so a down host gives empty answers instead of a 500 page
  the polling script drops.
- The Secrets page lists vTPM secrets instead of failing on them, and a
  secret without usage data shows an empty cell instead of "None".
- A TCP/TLS host takes a SASL password longer than 14 characters and a
  login up to the Linux limit of 32.
- The compute edit page says "Edit Compute"; a host without VMs no longer
  closes an extra page element; the memory graph is labelled MiB.
2026-10-26 15:36:57 +03:00
catborise
6c2704f97d fix(admin): Removed VMs shows the host a VM left and confirms a delete
A tombstone kept the VM's name and UUID but not its compute, so the page
could not say where the VM had been. It now stores the compute's name (as
text: the compute may be the one deleted) and the list shows it; records
made before this have no host. Deleting a record says so, and the admin
tables use scope="col" instead of the invalid span="col".

Closes #217
2026-10-26 11:48:40 +03:00
catborise
33819df794 fix(computes): one vCPU on one CPU is said in the singular
The Computes page and the new-VM dialog said "1 vCPUs on 1 CPUs" and
"1 vCPUs"; they now say "1 vCPU on 1 CPU".
2026-10-25 21:33:41 +03:00
catborise
e7361561aa feat(instances): the new-VM dialog shows what each host has given its VMs
Under each host's CPU and memory load, the dialog shows one line:

  Given to VMs: 24 vCPUs (1.5:1), 48.0 GB memory.
  Pool default: 120.0 GB free.

The line is read when the dialog opens, from computes/<id>/capacity/,
as plain text, so the VM list itself reads no VM definitions. The CPU
bars and the lines share one queue, host by host and two reads at a
time, as each read holds a worker. A host that cannot be read says so.

Compute.capacity now also gives the vCPUs per CPU and its pools with
the default one first, so the Computes page and the dialog share them.
2026-10-25 13:13:40 +03:00
catborise
d9f9ebab58 refactor(computes): the Computes page reads capacity through vrtManager
The capacity read lived in its own module with raw libvirt calls and a
thread pool with a deadline, beside helpers that already read the same
things. It now uses them:

- wvmHostDetails.get_capacity() sums the vCPUs and memory of all and of
  the running VMs from get_host_instances(), against the host's info.
- get_storages_info() also gives each pool's free space.
- Compute.capacity joins the two, like cpu_count and ram_size, and is
  None when the host is down or the read fails.

The page reads the hosts one after another, as it already connected to
each of them; a host that cannot be reached is given up after the
connect timeout. computes/capacity.py and its thread handling are gone.
The page looks and sorts as before.
2026-10-25 12:27:05 +03:00
catborise
1436ed13af feat(computes): the Computes page shows what each host has given its VMs
Each host is a row of what it has committed, read live from the host (in
parallel, by a 10 s deadline):

- Host: a status dot, the name, its address and details; when it cannot
  be reached, why.
- vCPUs: the overcommit ratio, large (warning above 2:1, red above
  4:1), over "N vCPUs on M CPUs" and the running VMs' share.
- Memory: memory given to all VMs against the host's memory, as one bar:
  running VMs dark, shut-off VMs light (they take their memory again
  when they start), and a line where the host's memory ends; red when
  the VMs were given more than the host has.
- Storage: the default pool (or the first) with its used share and free
  space; the others, a host may have dozens, open on a click.

A host that cannot be reached, or does not answer in time, says so in
one line instead. vCPUs and Memory sort by ratio and share. A host whose
read hangs is not read again until that read ends, so a stuck host keeps
at most one thread. The table's hidden status texts stay inside it, so
the page does not widen on a phone.
2026-10-25 11:57:09 +03:00
catborise
addc7ccfcb fix(computes): a VM moved between computes keeps its owners on PostgreSQL
Two computes decide the owners of the same UUID: the one the VM left
buries them in a tombstone (or a compute delete does), the one it went
to restores them. On PostgreSQL the two ran at once: the restore still
saw the old row of the uncommitted bury, skipped, and the VM ended up
without owners while the tombstone stayed. SQLite was never affected:
its IMMEDIATE transactions take the write lock at the start.

The reconcile and the compute delete now take one transaction-level
advisory lock (pg_advisory_xact_lock) when their database step starts,
so ownership decisions run one after another on PostgreSQL as they do
on SQLite. Reading libvirt stays outside the lock.
2026-10-23 15:31:04 +03:00
catborise
8c0fbff8f7 feat(logs): admin changes and logins are recorded on the Logs page
The Logs page shows who added, changed or deleted a compute, from web
or API, and every login, failed login, lockout and logout, with the
client address and a Result column (Done, Failed, Unknown for older
rows). A failed change is recorded with its reason and the error still
reaches the user; a refused one is recorded too.

- logs.audit.write saves each row in its own savepoint and never
  raises, so a log write cannot break or undo the action it records.
  The audit() context manager writes one row when the change ends.
- Logs gains success and ip; user, host and instance are wider and
  date is indexed. The page orders by date then id.
- A compute edit names the changed fields; an edit that changes
  nothing writes no row, and an empty password field is no change.
- A compute's VMs leaving the panel get a system row each: owners
  kept on the Removed VMs page, moved to another compute, restored,
  left without owners, or the removed record expired.
- Job rows carry the result. A job's log entry that cannot be
  computed is logged and skipped instead of rolling back the finish
  (test_service.py changes this on purpose).
- Logins are recorded by signal receivers; CustomLoginView is removed
  and the plain LoginView is used. A wrong OTP code is a failed login,
  counted by django-axes toward the lockout.

Panel records and host-side objects follow in the next layers.
2026-10-23 10:30:48 +03:00
catborise
2dee5ba41c fix(computes): a deleted compute's VMs keep their owners
Deleting a compute removed its VMs from the panel together with their
owners, while the VMs kept running on the host: added again, the host's
VMs came back with no owners. A compute's delete now treats each VM as
one that left its compute: its owners follow the same UUID on another
compute or wait in a tombstone for the retention period. One function,
forget(), does this for the refresh and for the delete; the API's
compute delete goes through the same model delete.

The delete holds the compute exclusive and locks its row before its
VMs', as the reconcile does: a reconcile, VM operation or job on the
compute makes it busy instead of losing owners to a concurrent restore
or deadlocking with it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-22 13:24:22 +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
0d5014d9ef fix(computes): a disk is offered the host's disk buses
The bus list of a disk on the VM create page came from the host's disk
device types: choosing "disk" for an added image offered cdrom, disk and
lun as its buses. The disk branch of get_disk_buses now returns the
host's disk bus types, the list the page starts each disk with.
2026-10-20 21:24:31 +03:00
catborise
f5ec757d1a build: Chart.js 4.5.1 2026-10-17 13:19:43 +03:00
catborise
68812ddbdf refactor(computes): the lock helpers take claims instead of file locks 2026-10-14 23:27:57 +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