Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ unmuted
uncomment
Uptime
usb
UUID
vdc
VDC
VLC
Expand Down
1 change: 1 addition & 0 deletions configs/qemu.ini
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ storage.0.size=16
#storage.1=/var/lib/mtda/extra-ssd.img
#storage.1.size=16
watchdog=i6300esb
#uuid=11111111-2222-3333-4444-555555555555

# ---------------------------------------------------------------------------
# Shared Storage settings
Expand Down
5 changes: 5 additions & 0 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,11 @@ The following settings are supported:
* ``swtpm``: string [optional]
Path to the ``swtpm`` binary to support emulation of a TPM device.

* ``uuid``: string [optional]
UUID to assign to the QEMU/KVM virtual machine (passed via ``-uuid``).
When not set, a UUID is automatically generated and persisted in
``/var/lib/mtda/qemu-uuid`` so the same value is reused across restarts.

* ``watchdog``: string [optional]
Name of the watchdog driver provided by QEMU/KVM for the selected machine.

Expand Down
30 changes: 30 additions & 0 deletions mtda/power/qemu.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import threading
import time
import multiprocessing
import uuid

# Local imports
from mtda.power.controller import PowerController
Expand Down Expand Up @@ -47,6 +48,7 @@ def __init__(self, mtda):
self.pidOfSwTpm = None
self.pidOfWebsockify = None
self.swtpm = "/usr/bin/swtpm"
self.uuid = None
self.watchdog = None
self.websockify = "/usr/bin/websockify"

Expand Down Expand Up @@ -79,6 +81,11 @@ def configure(self, conf):
self.swtpm = os.path.realpath(conf['swtpm'])
elif os.path.exists(self.swtpm) is False:
self.swtpm = None
if 'uuid' in conf:
try:
self.uuid = str(uuid.UUID(conf['uuid']))
except ValueError:
raise ValueError(f"invalid UUID: {conf['uuid']}")
if 'watchdog' in conf:
self.watchdog = conf['watchdog']
n = 0
Expand Down Expand Up @@ -221,6 +228,29 @@ def start(self):
if self.watchdog is not None:
options += f" -device {self.watchdog},id=watchdog0"

# UUID option
vm_uuid = self.uuid
if vm_uuid is None:
uuid_file = "/var/lib/mtda/qemu-uuid"
if os.path.exists(uuid_file):
with open(uuid_file, "r") as f:
data = f.read().strip()
try:
vm_uuid = str(uuid.UUID(data))
except ValueError:
self.mtda.debug(1, "power.qemu.start(): "
f"invalid UUID in {uuid_file}, "
"generating a new one")
vm_uuid = None
if not vm_uuid:
vm_uuid = str(uuid.uuid4())
os.makedirs("/var/lib/mtda", exist_ok=True)
with open(uuid_file, "w") as f:
f.write(vm_uuid + "\n")
self.mtda.debug(2, "power.qemu.start(): "
f"generated UUID {vm_uuid}")
options += f" -uuid {vm_uuid}"

# swtpm options
if self.swtpm is not None:
with tempfile.NamedTemporaryFile() as pidfile:
Expand Down
Loading