mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-10 04:06:47 +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
|
|
@ -9,7 +9,7 @@ from django.conf import settings
|
|||
from django.db import transaction
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from libvirt import libvirtError
|
||||
from logs.views import addlogmsg
|
||||
from logs.audit import reason, write
|
||||
from vrtManager.instance import wvmInstance, wvmInstances
|
||||
|
||||
from .models import Instance
|
||||
|
|
@ -159,8 +159,14 @@ def migrate_instance(
|
|||
compress=False,
|
||||
):
|
||||
"""Migrates instance to new_compute and logs the outcome (the mode
|
||||
used, or the error). Returns the mode."""
|
||||
source = instance.compute
|
||||
used, or the error), then each later step that failed in a row of its
|
||||
own. Returns the mode."""
|
||||
source, target = instance.compute, migration_target(new_compute)
|
||||
|
||||
def log(action, error=None):
|
||||
message = f"VM {instance.name}: {action}" + (f": {reason(error, user)}" if error is not None else "")
|
||||
write(user.username, source.name, instance.name, message, error is None, uuid=instance.uuid)
|
||||
|
||||
conn_migrate = None
|
||||
try:
|
||||
conn_migrate = wvmInstances(
|
||||
|
|
@ -183,11 +189,7 @@ def migrate_instance(
|
|||
uri=new_compute.migration_uri,
|
||||
)
|
||||
except Exception as error:
|
||||
msg = _("Instance migration to %(target)s failed: %(error)s") % {
|
||||
"target": migration_target(new_compute),
|
||||
"error": error,
|
||||
}
|
||||
addlogmsg(user.username, source.hostname, instance.name, msg)
|
||||
log(f"migrate to {target}", error)
|
||||
raise
|
||||
finally:
|
||||
if conn_migrate is not None:
|
||||
|
|
@ -195,10 +197,7 @@ def migrate_instance(
|
|||
|
||||
# The VM runs on new_compute now: what follows must not stop it
|
||||
# from being recorded there.
|
||||
msg = _("Instance is migrated(%(mode)s) to %(target)s") % {
|
||||
"mode": mode,
|
||||
"target": migration_target(new_compute),
|
||||
}
|
||||
log(f"migrate ({mode}) to {target}")
|
||||
if autostart:
|
||||
conn_new = None
|
||||
try:
|
||||
|
|
@ -212,7 +211,7 @@ def migrate_instance(
|
|||
)
|
||||
conn_new.set_autostart(1)
|
||||
except (libvirtError, OSError) as error:
|
||||
msg = _("%(msg)s; setting its autostart there failed: %(error)s") % {"msg": msg, "error": error}
|
||||
log(f"restore autostart on {target}", error)
|
||||
finally:
|
||||
if conn_new is not None:
|
||||
conn_new.close()
|
||||
|
|
@ -227,11 +226,7 @@ def migrate_instance(
|
|||
)
|
||||
instance.proxy.remove_nvram(nvram, conn_new)
|
||||
except Exception as error: # the migration stands and is recorded
|
||||
msg = _("%(msg)s; removing its NVRAM file %(path)s on the source failed: %(error)s") % {
|
||||
"msg": msg,
|
||||
"path": nvram,
|
||||
"error": error,
|
||||
}
|
||||
log(f"remove NVRAM file {nvram} on the source", error)
|
||||
finally:
|
||||
if conn_new is not None:
|
||||
conn_new.close()
|
||||
|
|
@ -239,11 +234,8 @@ def migrate_instance(
|
|||
try:
|
||||
record_migration(instance, new_compute)
|
||||
except Exception as error:
|
||||
failed = _("%(msg)s, but recording it failed: %(error)s") % {"msg": msg, "error": error}
|
||||
addlogmsg(user.username, source.hostname, instance.name, failed)
|
||||
log(f"record the move to {target}", error)
|
||||
raise
|
||||
|
||||
addlogmsg(user.username, source.hostname, instance.name, msg)
|
||||
return mode
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue