Skip to content

Test on real VMs with Vagrant

The Helvilette repository ships a Vagrant environment under vagrant/ that builds a working two-node lab: Othela and Gitea on one Debian VM, an agent on another, both under systemd. It is the manual-testing rig, and it replaces the hand-built Proxmox VMs the first-flight test plan originally assumed.

Use it when what you are testing is the agent meeting a real operating system.

The E2E suite is faster and is the right tool for the dispatch path, the clone logic and the Ansible invocation. It stops being sufficient one layer down.

  • The agent runs as a systemd service and talks to systemd over D-Bus. Inside a container systemd is absent or crippled.
  • The test playbooks manage packages, services and sysctl, all of which behave differently in a container.
  • Snapshot and rollback, and later tests such as pulling power mid-run, need a real VM.

A container makes you debug the environment instead of Helvilette.

  • Vagrant
  • libvirt with KVM/QEMU, plus vagrant-libvirt. The Vagrantfile sets libvirt as the provider
  • Ansible on the host, which Vagrant uses to provision both VMs
  • Around 2 GB of RAM and two spare CPU cores

Synced folders use rsync rather than NFS, so you do not need nfsd on the host.

Terminal window
cd vagrant
make up

That runs vagrant up and then the helvilette-setup.yml playbook, which:

  1. Installs Go, Git and Make on both VMs, builds othela and agent from the synced source tree, and installs both to /usr/local/bin.
  2. On the Othela node, creates a helvilette system user and /var/lib/helvilette/othela, then installs and starts othela.service.
  3. On the agent node, installs Ansible and starts helvi-agent.service.
  4. Installs Docker on the Othela node and starts Gitea in a container.

The two VMs:

RoleHostnameAddressServices
Control planeothela-node192.168.121.10Othela on :8080, Gitea on :3000
Managed nodeagent-node-1192.168.121.11helvi-agent.service

Debian 12 (Bookworm) is the box on both, chosen because it is boring: standard systemd, Python 3.11 present, and an apt that does not interrupt itself. When something breaks it is very probably Helvilette that broke.

Othela starts with --fleet-repo=http://192.168.121.10:3000/helvi-test/baseline.git, which does not exist until you create it. Gitea needs a one-time manual setup:

  1. Open http://192.168.121.10:3000 and complete the installer.
  2. Register a user named helvi-test. The first user registered becomes the administrator.
  3. Create a repository named baseline.

Then put a playbook and a manifest in vagrant/baseline-repo/ on your host and push them:

Terminal window
cd vagrant
make repo

That target initialises baseline-repo/, commits it, and pushes to http://192.168.121.10:3000/helvi-test/baseline.git on main. The directory is gitignored, so its contents are yours to write.

Terminal window
make othela # ssh to the control plane VM
sudo journalctl -u othela -f
Terminal window
make agent # ssh to the managed node
sudo journalctl -u helvi-agent -f

The manifest Othela loads is a normal helvilette.yml, and every failure mode in diagnose a manifest that deploys nothing applies unchanged. The one difference from a local run is that both processes are under systemd, so their output is in the journal rather than on a terminal.

CommandEffect
make upvagrant up with provisioning, then prints the Gitea setup steps
make reloadvagrant reload --provision, to re-run provisioning after a source change
make downvagrant destroy -f
make teardownDestroy and rebuild from scratch
make othelaSSH into the control plane VM
make agentSSH into the managed node

Take a snapshot of both VMs before a test run. Nothing about a test is permanent damage when you can roll back, and you will want a clean baseline to compare a second run against.