Files
2026-09-30 17:33:31 +02:00
..
2026-09-30 17:33:31 +02:00
2026-09-30 17:33:31 +02:00
2026-09-30 17:33:31 +02:00

Dom0 System Update Scripts

These scripts update Linux guests managed by KVM on Dom0, collect OS and kernel information before and after the updates, compare the results, and email a summary.

Requirements

Run the scripts as root on Dom0, from the directory containing the scripts and excluded_vm.txt. The scripts use the current working directory for their input and output files.

Required tools:

  • Bash
  • virsh (libvirt/KVM)
  • ssh and working root SSH access from Dom0 to each VM
  • hostnamectl
  • dnf
  • python3
  • tee, find, and gzip
  • msmtp (for check_update.sh)

The scripts expect eligible guests to be Linux systems that support hostnamectl and dnf. Exclude Windows guests.

Configuration and input

excluded_vm.txt

Place one VM name per line. Lines beginning with #, blank lines, and inline comments are ignored. VM names must match the names reported by virsh and must also resolve as SSH hostnames, for example linux-vm.example.com.

If the file is missing, the scripts warn and process all discovered VMs.

WAIT_FOR_START

Both scripts wait after each VM is confirmed started, even if it was already running. Set WAIT_FOR_START to a non-negative integer number of minutes; the default is 1.

WAIT_FOR_START=5 ./system_update.sh
WAIT_FOR_START=5 ./check_update.sh

After this wait, the scripts check SSH connectivity with up to six attempts, spaced 10 seconds apart.

EMAIL_RECIPIENT

check_update.sh sends the summary to vplesnila@gmail.com by default. Override the address with an environment variable:

EMAIL_RECIPIENT=admin@example.com ./check_update.sh

Email is sent by msmtp -t; configure msmtp on Dom0 separately. The message subject is Update system on <Dom0 static hostname>, and its HTML body displays the summary tables in a monospace <pre> block.

system_update.sh

Run this script first:

./system_update.sh

For every non-excluded VM returned by virsh list --all --name, it starts the VM if necessary, waits WAIT_FOR_START minutes, checks SSH, and records the VM's Operating System and Kernel values from hostnamectl before the update. It then runs dnf update -y over SSH and requests a graceful VM shutdown. After all VMs, it records Dom0's before values and runs dnf update -y on Dom0. This script does not reboot Dom0.

The script overwrites status.before once at the beginning of each execution. It contains a JSON object with a systems array. Each collected system has this shape:

{
  "vm_name": "linux-vm.example.com",
  "before": {
    "operating_system": "Example Linux 9",
    "kernel": "5.14.0-example"
  }
}

Dom0 is recorded with "vm_name": "Dom0". A VM whose startup, SSH connection, or hostname query fails may not have a record in the file. Update failures are logged; the script continues processing.

The script writes operational output to log/system_update_YYYY-MM-DD_HH_MM.log.

check_update.sh

Run this after system_update.sh has successfully created status.before:

./check_update.sh

For each non-excluded VM, it starts the VM if needed, waits WAIT_FOR_START minutes, checks SSH, records its hostnamectl values as after values, and requests a graceful shutdown. It then records Dom0's after values. It does not run updates.

Each run overwrites status.after, which uses the same systems array format as status.before, with an after object instead of a before object:

{
  "vm_name": "linux-vm.example.com",
  "after": {
    "operating_system": "Example Linux 9",
    "kernel": "5.14.0-example"
  }
}

The script joins records from status.before and status.after by vm_name and prints two comparison tables:

  • operating_system: VM name, before OS, after OS, and Changed
  • kernel: VM name, before kernel, after kernel, and Changed

Changed is NO for equal values and YES otherwise. Missing values are shown as not available and therefore compare as changed.

The tables are saved to log/summary_YYYY-MM-DD_HH_MM.log and included in the summary email. Summary files older than 60 days are purged at script startup.

Logs and retention

Both scripts create the log/ directory when it does not exist. Filenames include local Dom0 date and time to the minute; two executions of the same script within one minute can use the same filename.

Current retention caveat: system_update.sh writes files named system_update_*.log, but its cleanup commands currently match dnf_update_all_*.log and .log.gz. Consequently, those commands do not compress or delete the system_update_*.log files. The 60-day summary purge in check_update.sh applies to summary_*.log files.

Operational notes

  • These scripts use the directory from which they are launched, not the directory containing the script, for excluded_vm.txt, status files, and log/.
  • VM shutdowns are requested through virsh shutdown; the scripts do not wait for a VM to finish shutting down.
  • check_update.sh requires a valid status.before JSON file. Run system_update.sh first so both files describe the same update cycle.
  • Review the generated logs and comparison tables for per-VM errors before relying on the update results.