feat: guest-agent over vsock acceptance test - #16
Merged
Merged
Conversation
Install the LiquidMetal guest-agent into the microVM guest via apt during cloud-init and add an e2e test that drives it over AF_VSOCK. flintlock v0.11.0 attaches a vsock device when the spec sets allow_guest_agent (host CID 2 <-> guest CID 3) and reports the host-side UDS in MicroVMStatus.vsock_path; brigade v0.2.0 carries those fields natively. The guest-agent (v0.1.0) listens on vsock control port 1024 and the host drives it with the vsock-connect CLI. - spec.py: opt-in guest_agent flag adds allow_guest_agent, NIC nameservers, and cloud-init that installs + enables guest-agent from the apt repo. Default path (SSH-reachability test) is untouched. - provision_host.sh.j2: install the vsock-connect host client on each droplet. - config.py/.env.example: GUEST_AGENT_VERSION knob; pin FLINTLOCK_REF=v0.11.0 and BRIGADE_REF=v0.2.0 (matched flintlock API). - re-vendor protos from flintlock v0.11.0 (allow_guest_agent, vsock_path). - new tests/test_guest_agent_vsock.py: create a VM with guest_agent, read vsock_path via brigade, find the hosting droplet, and run vsock-connect exec/ping/info asserting output + exit-code propagation.
There was a problem hiding this comment.
Pull request overview
Adds an end-to-end acceptance path for LiquidMetal’s in-guest guest-agent reachable via AF_VSOCK, complementing the existing SSH reachability checks by validating a host-local control channel that doesn’t depend on guest networking.
Changes:
- Add a new e2e test that locates the flintlock host-side
vsock_pathand runsvsock-connectcommands via SSH on the hosting droplet. - Extend flintlock spec building to optionally enable
allow_guest_agent, add NIC nameservers, and use cloud-init that installs/enablesguest-agent. - Add config/env and host provisioning support for pinning and installing the matching
vsock-connectclient version, plus proto updates forallow_guest_agent/vsock_path.
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_guest_agent_vsock.py | New e2e test exercising guest-agent over vsock via host-local vsock_path. |
| tests/test_cleanup.py | Offline/unit checks for guest-agent spec behavior and host provisioning template output. |
| proto/fltypes/microvm.proto | Vendored proto updates adding allow_guest_agent and vsock_path. |
| proto/flapi/microvms.proto | Minor vendored proto formatting/closure alignment. |
| liquidmetal_at/flintlock/spec.py | Add guest_agent opt-in to spec/request builders and guest-agent cloud-init. |
| liquidmetal_at/config.py | Add guest_agent_version config knob with env defaulting/pinning commentary. |
| liquidmetal_at/bootstrap/templates/provision_host.sh.j2 | Install vsock-connect on hosts (intended non-fatal). |
| liquidmetal_at/bootstrap/host.py | Thread guest_agent_version into host provisioning template rendering. |
| .env.example | Pin refs for brigade/flintlock versions supporting vsock guest-agent and add GUEST_AGENT_VERSION. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+64
to
+80
| for droplet in cluster.droplets: | ||
| ssh = SSH(host=droplet.public_ip, user="root", key_path=config.ssh_private_key_path) | ||
| ssh.connect(timeout=config.timeout_ssh) | ||
| try: | ||
| rc, _, _ = ssh.run(f"test -S {quoted}", check=False, timeout=15) | ||
| if rc == 0: | ||
| rc, out, err = ssh.run( | ||
| f"vsock-connect ping --uds {quoted} --port 1024", | ||
| check=False, | ||
| timeout=30, | ||
| ) | ||
| if rc == 0: | ||
| return ssh | ||
| last = f"ping rc={rc}: {(err or out).strip()}" | ||
| except Exception as exc: # noqa: BLE001 - agent lives behind one host | ||
| last = str(exc) | ||
| ssh.close() |
Comment on lines
+91
to
+95
| if curl -fsSL "$GA_URL" -o "$GA_TMP/vc.tgz"; then | ||
| tar -xzf "$GA_TMP/vc.tgz" -C "$GA_TMP" | ||
| GA_BIN=$(find "$GA_TMP" -type f -name vsock-connect | head -1) | ||
| [ -n "$GA_BIN" ] && install -m0755 "$GA_BIN" /usr/local/bin/vsock-connect | ||
| fi |
| // not supplied a autogenerated MAC address will be used. | ||
| optional string guest_mac = 4; | ||
| // Address is an optional static IP address to manually assign to this interface. | ||
| // Address is an optional static IP address to manually assign to this interface. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Installs the LiquidMetal guest-agent into the microVM guest via apt during cloud-init, and adds an e2e test that connects to it over AF_VSOCK and runs commands.
Why
flintlock v0.11.0 (PR liquidmetal-dev/flintlock#1151) adds a vsock guest-agent channel:
allow_guest_agenton the spec attaches a vsock device (host CID 2 ↔ guest CID 3) and reports the host-side UDS inMicroVMStatus.vsock_path. brigade v0.2.0 (PR liquidmetal-dev/brigade#21) bumps to that flintlock API, so the fields cross brigade natively. This gives the suite a host-controlled guest channel that needs no guest network — a different, complementary path to the existing SSH-reachability test.How
spec.py— opt-inguest_agentflag: setsallow_guest_agent, adds NIC nameservers (apt needs guest DNS), and swaps in cloud-init that installs + enablesguest-agentfrom the LiquidMetal apt repo. The default path (SSH test) is untouched.provision_host.sh.j2— installs thevsock-connecthost client on each droplet (non-fatal on download miss).config.py/.env.example—GUEST_AGENT_VERSIONknob (0.1.0); pinsFLINTLOCK_REF=v0.11.0+BRIGADE_REF=v0.2.0.allow_guest_agent,vsock_path); stubs regenerated.tests/test_guest_agent_vsock.py(new) — creates a VM withguest_agent, readsvsock_pathvia brigade, finds the hosting droplet (UDS lives on exactly one host), and runsvsock-connect exec/ping/infoover SSH — assertinghostname == vm-id, an arbitrary command, and exit-code propagation.vsock is host-local (and host flintlockd
:9090is firewalled to peers), so the test runsvsock-connecton the droplet holding the UDS rather than from the runner.Testing
make lint✅ andpytest tests/test_cleanup.py✅ (13 offline tests, incl. 3 new: guest-agent spec, default-off, provision installs vsock-connect).make test(full e2e, real DO infra, ~20-40 min, costs money) withFLINTLOCK_REF=v0.11.0+BRIGADE_REF=v0.2.0.Residual runtime risks (flagged, fail loudly + guest serial console captured)