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>
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.