Running an OTA Update in QEMU¶
This guide covers building a SWUpdate package, publishing it through the device management platform,
and triggering an OTA streaming update on a ToloMEO QEMU image using natscli from inside the guest.
Table of Contents¶
- Running an OTA Update in QEMU
- Table of Contents
- Prerequisites
- Build the Update Package
- Prepare the Working Directory
- Run QEMU
- Trigger the OTA Update
- Monitor the Update
Prerequisites¶
- QEMU installed with
qemu-system-x86_64available - QEMU boot artifacts already available (see
meta-tolomeo-qemu/README.md) - An image built with
update-otainDISTRO_FEATURES(see Configure Update Modes) - The signed
.swupackage published through the device management platform and marked as a new release for this device
Build the Update Package¶
Build a full SWUpdate package from inside the devcontainer:
The recipe uses the stable,update software selection and targets /dev/vdb via GPT partition swap.
After the build completes, the .swu package is collected under:
artifacts/tolomeo-qemux86-64/image-prod/<version>/updates/imgen-update-full/
└── imgen-update-full-tolomeo-qemux86-64.rootfs.swu
Upload the package to the device management platform and mark it as a new release for the target device before proceeding.
Prepare the Working Directory¶
Your working directory should contain the following before launching QEMU:
.
├── bzImage
├── image-prod-tolomeo-qemux86-64.rootfs.ext4
├── qemu-disk.img # provisioned disk with certificates
└── shared/ # local directory for shared mount
Create the shared directory if it does not exist:
Run QEMU¶
The QEMU command for OTA updates is identical to the standalone mode guide — no USB-specific flags are required. Launch the VM:
qemu-system-x86_64 \
-kernel bzImage \
-append 'root=/dev/vda rw mem=1024M ip=dhcp console=ttyS0 console=ttyS1 oprofile.timer=1 tsc=reliable no_timer_check rcupdate.rcu_expedited=1 swiotlb=0' \
-drive file=image-prod-tolomeo-qemux86-64.rootfs.ext4,if=virtio,format=raw \
-drive file=qemu-disk.img,if=virtio,format=raw,id=qemu-disk \
-virtfs local,path=shared,mount_tag=shared,security_model=mapped-xattr \
-device virtio-net-pci,netdev=net0,mac=52:54:00:12:35:02 \
-netdev user,id=net0,hostfwd=tcp:127.0.0.1:2222-:22,hostfwd=tcp:127.0.0.1:2323-:23 \
-object rng-random,filename=/dev/urandom,id=rng0 \
-device virtio-rng-pci,rng=rng0 \
-cpu IvyBridge -machine q35,i8042=off \
-smp 4 -m 1024 \
-usb -device usb-tablet -usb -device usb-kbd \
-serial mon:stdio -serial null -nographic
KVM acceleration: Add
-enable-kvmfor better performance. This may requiresudodepending on your system configuration.
Trigger the OTA Update¶
Once the VM has booted, connect via SSH from a second terminal:
Use natscli inside the guest to interact with the swupdate management service. Run GetOTAStatus
first to confirm the update is visible to the device before proceeding.
Check update availability:
timestamp=$(date +%s.%3N)
nats pub commands.swupdate.req \
'[{"bn":"", "t":'"$timestamp"',"n":"GetOTAStatus","vs":"{\"id\":\"swupdate\"}"}]'
Start the download:
timestamp=$(date +%s.%3N)
nats pub commands.swupdate.req \
'[{"bn":"", "t":'"$timestamp"',"n":"StartOTADownload","vs":"{\"id\":\"swupdate\"}"}]'
Install the downloaded update:
timestamp=$(date +%s.%3N)
nats pub commands.swupdate.req \
'[{"bn":"", "t":'"$timestamp"',"n":"InstallOTAUpdate","vs":"{\"id\":\"swupdate\"}"}]'
Monitor the Update¶
In the same SSH session (or a parallel one), subscribe to the events topic to follow the status progression in real time:
A typical successful run produces the following sequence of events:
[#1] Received on "events.params"
[{"bn": "urn:cpt:device:sn:TVD_0000:", "n": "GetOTAStatus", "vs": "{\"id\": \"swupdate\", \"result\": \"success\", \"status\": \"update_available\"}"}]
[#2] Received on "events.params"
[{"bn": "urn:cpt:device:sn:TVD_0000:", "n": "StartOTADownload", "vs": "{\"id\": \"swupdate\", \"result\": \"success\", \"status\": \"downloading\"}"}]
[#3] Received on "events.params"
[{"bn": "urn:cpt:device:sn:TVD_0000:", "n": "GetOTAStatus", "vs": "{\"id\": \"swupdate\", \"result\": \"success\", \"status\": \"update_ready\"}"}]
[#4] Received on "events.params"
[{"bn": "urn:cpt:device:sn:TVD_0000:", "n": "InstallOTAUpdate", "vs": "{\"id\": \"swupdate\", \"result\": \"success\", \"status\": \"updating\"}"}]
After the updating event the VM reboots into the new image. Once it comes back up, confirm the
rollback guard was cleared:
The value should be unset once the new image has booted and confirmed itself healthy.