mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 19:56:48 +00:00
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>
This commit is contained in:
parent
49cf16ecbe
commit
c1d36053d6
24 changed files with 639 additions and 524 deletions
|
|
@ -106,9 +106,9 @@ class Kind:
|
|||
the kind decides whether the job is idle and ends it if so."""
|
||||
|
||||
def log_entry(self, op, state):
|
||||
"""(host, instance, message) of the Logs row written with each end of
|
||||
the job (in the same transaction); its host and instance also go on
|
||||
the row of a resolution. None: no row."""
|
||||
"""(host, instance, instance UUID, message) of the Logs row written
|
||||
with each end of the job (in the same transaction); its host, instance
|
||||
and UUID also go on the row of a resolution. None: no row."""
|
||||
return None
|
||||
|
||||
|
||||
|
|
@ -219,8 +219,8 @@ def _entry(op, state):
|
|||
return None
|
||||
|
||||
|
||||
def _log(user, host, instance, message, success):
|
||||
write(str(user), str(host), str(instance), utils.safe_text(message), success)
|
||||
def _log(user, host, instance, uuid, message, success):
|
||||
write(str(user), str(host), str(instance), utils.safe_text(message), success, uuid=str(uuid))
|
||||
|
||||
|
||||
def finish(op, outcome, *, worker=None):
|
||||
|
|
@ -262,10 +262,10 @@ def resolve(op_id, user, outcome_state, note):
|
|||
Operation.objects.filter(pk=op.pk).update(state=outcome_state, resolution=outcome_state,
|
||||
resolution_note=note, resolved_by=user, resolved_at=timezone.now())
|
||||
Claim.objects.filter(operation=op).delete()
|
||||
# the host and VM columns of the kind's own entries, so the VM's log shows it
|
||||
# the host, VM and UUID columns of the kind's own entries, so the VM's log shows it
|
||||
entry = _entry(op, outcome_state)
|
||||
host, instance = entry[:2] if entry is not None else ("-", op.resource_label)
|
||||
_log(user.username, host, instance, f"Job {op.pk} resolved as {outcome_state}: {note}",
|
||||
host, instance, uuid = entry[:3] if entry is not None else ("-", op.resource_label, "")
|
||||
_log(user.username, host, instance, uuid, f"Job {op.pk} resolved as {outcome_state}: {note}",
|
||||
outcome_state == Operation.SUCCEEDED)
|
||||
op.refresh_from_db()
|
||||
return op
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ class NoopKind(Kind):
|
|||
return Outcome(Operation.SUCCEEDED, result={"recovered": True})
|
||||
|
||||
def log_entry(self, op, state):
|
||||
return ("c", "vm", f"No-op {state}")
|
||||
return ("c", "vm", op.params["uuid"], f"No-op {state}")
|
||||
|
||||
|
||||
@register
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue