Running agents in a VM on your laptop¶
The system that runs on the Sipfront Raspberry Pi image is also available as a ready-made virtual machine. It runs with QEMU on a Linux or macOS computer, applies the same sipfront.txt configuration, and starts the Sipfront agent on boot, so a laptop can act as a private agent without flashing an SD card. With a USB Bluetooth dongle it can also run real mobile phone tests against a paired phone.
Tip
The VM is meant for engineers who want to run or try a private agent on their own machine, e.g. a field engineer running a mobile phone test from a customer site. For permanent installations, the Raspberry Pi image is the better fit: it boots unattended, survives power cuts and needs no laptop.
Prerequisites¶
Operating system¶
| Host | Agent (SIP, DNS, browser tests) | Mobile phone tests (Bluetooth) |
|---|---|---|
| Linux x86_64 (Debian 12, Ubuntu 22.04 / 24.04 or newer) | yes, native speed with KVM | yes, with a USB Bluetooth dongle |
| Linux arm64 | yes, native speed with KVM | yes, with a USB Bluetooth dongle |
| macOS (Apple Silicon or Intel) | yes, native speed with Hypervisor.framework | no: QEMU on macOS cannot pass a Bluetooth dongle's HCI traffic to the VM |
| Windows | not supported | not supported |
Packages¶
Linux (Debian / Ubuntu):
# x86_64 laptop
sudo apt install qemu-system-x86 python3 usbutils
# arm64 laptop
sudo apt install qemu-system-arm python3 usbutils
# use KVM without root (log out and in again afterwards)
sudo usermod -aG kvm "$USER"
macOS:
brew install qemu
python3 is used by the stop script to ask the VM for a clean shutdown; it is preinstalled on macOS and on most Linux desktops. Without it the stop script still terminates the VM, just without a clean shutdown.
Resources¶
The VM uses 2 CPU cores and 2 GB of RAM by default and roughly 6 GB of disk once the agent image is pulled. A wired or Wi-Fi internet connection on the laptop is enough: the VM shares it and needs no network configuration of its own.
USB Bluetooth dongle (mobile phone tests only)¶
For mobile phone tests the VM needs its own Bluetooth adapter: a USB dongle that is handed over to the VM. The built-in Bluetooth of the laptop stays with the host and is never used.
- Tested and recommended: TP-Link UB500 (Bluetooth 5.0, Realtek RTL8761B, USB id
2357:0604). Other dongles with a Realtek or CSR chipset that Linux drives with thebtusbdriver are expected to work as well; the VM ships the Realtek firmware. - The dongle must be plugged in before the VM is started.
- Linux only. On macOS the VM runs the regular agent, but not mobile phone tests.
Grant your user access to the dongle once (replace the id with the one lsusb shows for your dongle). The rule gives the device to the user logged in at the desktop (uaccess) and to the plugdev group for ssh sessions; nobody else on the machine can touch it:
lsusb # e.g. "Bus 001 Device 004: ID 2357:0604 TP-Link UB500 Adapter"
printf 'SUBSYSTEM=="usb", ATTR{idVendor}=="2357", ATTR{idProduct}=="0604", TAG+="uaccess", GROUP="plugdev", MODE="0660"\n' \
| sudo tee /etc/udev/rules.d/70-sipfront-vm-usb.rules
sudo udevadm control --reload && sudo udevadm trigger
groups | grep -q plugdev || sudo usermod -aG plugdev "$USER" # Debian/Ubuntu desktop users usually are already
If that last command did add you to plugdev, log out and back in (or reconnect your ssh session) before starting the VM; a running shell does not pick up the new group.
Do not start the VM with sudo; the rule above is all the access it needs.
Download¶
| Laptop | Download |
|---|---|
| Linux x86_64 | sipfront-agent-vm-amd64-latest.tar.xz |
| Linux arm64, Apple Silicon Mac | sipfront-agent-vm-arm64-latest.tar.xz |
| Intel Mac | sipfront-agent-vm-amd64-latest.tar.xz |
The commands below pick the bundle for the machine they run on (amd64 on x86_64, arm64 on arm64 and Apple Silicon):
arch=$(uname -m | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')
curl -LO "https://cdn.sipfront.com/sipfront-agent-vm-${arch}-latest.tar.xz"
tar xf "sipfront-agent-vm-${arch}-latest.tar.xz"
cd sipfront-agent-vm-${arch}-*/
The archive unpacks into one directory:
| File | Purpose |
|---|---|
sipfront.txt | your agent pool credentials and settings, edit this first |
run.sh | starts the VM, with its console in the current terminal |
stop.sh | shuts the VM down cleanly, from another terminal |
vm.qcow2 | the VM disk; it holds the pulled agent image and the Bluetooth pairings, so keep it between runs |
vmlinuz, initrd.img, vm.env, arch.sh | boot files and helpers used by run.sh |
Configure the agent pool¶
Edit sipfront.txt in the unpacked directory. It is the same file the Raspberry Pi image reads from its SD card, see Configure the agent pool on the SD card for all options:
# fill in your Sipfront agent credentials
AGENT_POOL_ID="your-pool-id"
AGENT_POOL_SECRET="your-pool-secret"
AGENT_POOL_GROUP="customer-1"
# set to no to disable mobile phone testing via bluetooth
AGENT_PHONE_DRIVER="yes"
run.sh hands this file to the VM on every start, so changing it and restarting the VM is all it takes. The Wi-Fi settings have no effect in the VM: it uses the laptop's network connection.
Mobile agent or regular agent
The VM ships with AGENT_PHONE_DRIVER="yes", because its main purpose is mobile phone tests. With that setting the agent runs as the sipfront-agent-mobile runtime, which is given real mobile phone calls only, never SIP, DNS or browser tests. For a regular agent (SIP, DNS, browser tests, and on macOS, where the VM cannot use a Bluetooth dongle) set AGENT_PHONE_DRIVER="no" before the first start.
Run the VM¶
./run.sh
The VM's console appears in the terminal. On the first start with AGENT_PHONE_DRIVER="yes" the VM reboots once to enable the Bluetooth stack, then it pulls the sipfront/agent:latest image (a few minutes, depending on your connection) and starts the agent. It shows up as a pool group in the Agentpool Section once it is connected. The pulled image is kept on the VM disk, so later starts are fast.
With a USB Bluetooth dongle plugged in on a Linux laptop, run.sh detects it and hands it over to the VM (it prints using USB Bluetooth adapter 2357:0604 (TP-Link UB500 Adapter)); otherwise the VM runs with a virtual adapter that cannot reach a real phone. Pair the phone as described for the Raspberry Pi in Mobile phone tests: the VM is discoverable under its AGENT_HOSTNAME (sipfront-vm by default), pairing is accepted automatically, and the pairing is remembered on the VM disk across restarts.
To stop the VM, run from another terminal in the same directory:
./stop.sh
This asks the VM for a clean shutdown (like pressing the power button) and waits for it. Pressing Ctrl-a x in the console terminal ends QEMU immediately without a shutdown, which is safe for the read-only system but can lose a pairing or an agent image that was just being written.
Logging in¶
You usually do not need to log in. If you do, use the console in the terminal running run.sh, or ssh:
ssh -p 2222 sipfront@localhost
User sipfront, default password Sipfront!, the same as on the Raspberry Pi image. The root filesystem is read-only; rw and ro switch it to writable and back, sudo -s gives you a root shell. The agent's log is journalctl -u sipfront-agent, the running container's is docker logs -f agent-0.
Troubleshooting¶
qemu-system-x86_64: command not found: install the QEMU package for your host architecture (see Packages). On an arm64 laptop use the arm64 download.Could not access KVM kernel module: Permission denied: add your user to thekvmgroup (see above) and log in again. The VM still runs without KVM, only much slower.- The VM cannot reach the internet: it shares the laptop's connection through QEMU's user-mode network, which handles TCP, UDP and DNS.
pingfrom inside the VM does not work on Linux hosts unless unprivileged ICMP is allowed (sudo sysctl -w net.ipv4.ping_group_range='0 2147483647'); usecurlto check connectivity instead. - The agent does not appear in the pool: check
sipfront.txtfor the pool credentials, thenjournalctl -u sipfront-agentinside the VM. The VM waits for its clock to be synchronised and retries the image pull for a while after boot, so give it a few minutes. - No Bluetooth adapter in the VM / the phone cannot find it: the dongle must be plugged in before
./run.sh, the udev rule must match its USB id, and the host must be Linux.run.shprints the adapter it hands over; inside the VMbluetoothctl showlists it, withPowered: yesandDiscoverable: yes. - A call is dropped as soon as the other side rings: this is almost never the phone side. Check the SIP side of the test first, in particular the registration of the called party.
- Port 2222 is already in use: set another ssh port with
VM_SSH_PORT=2223 ./run.sh(and the same for./stop.sh).