Labtris docs

Nodes and images

Docker and QEMU, bringing your own images, and the two settings that stop a guest booting.

Labtris runs two kinds of node. Which one you want depends on how the software you are labbing is shipped, not on preference.

DockerQEMU
Starts inabout a secondas long as that OS takes to boot
Coststens of MBwhatever the image asks for
Good forLinux hosts, FRR, containerised NOSes — SR Linux, XRd, cEOSanything shipped as a disk: vendor appliances, Windows, BSD
Consolea real shellthe guest's serial port, or VNC for graphical guests
Snapshotsno — pause onlyyes, real savevm/loadvm

If the thing you want exists as a container, use the container. It starts in a second and costs nothing, and you can run twenty.

Bringing your own images

Labtris redistributes no vendor software. That is not a limitation to work around — it is the licence wall every network emulator sits behind. What differs is only how much help you get finding the file.

Docker images come from whatever registry you point at. If you can docker pull it, you can run it.

QEMU images are files you provide. The catalogue records, per image, where it came from and what it needs.

Importing the GNS3 registry

The GNS3 project maintains 228 appliance definitions — how to run a device, not the device itself. Labtris can read them, which turns an empty palette into a usable one.

git clone https://github.com/GNS3/gns3-registry
curl -X POST http://<host>:8081/api/v1/system/registry/import \
  -H 'content-type: application/json' \
  -d '{"path": "/path/to/gns3-registry/appliances"}'
import httpx, subprocess
subprocess.run(["git", "clone", "https://github.com/GNS3/gns3-registry"], check=True)
r = httpx.post(
    "http://<host>:8081/api/v1/system/registry/import",
    json={"path": "/path/to/gns3-registry/appliances"},
)
r.raise_for_status()
print(r.json())

It previews by default and tells you the honest numbers:

228 definitions
217 on runtimes Labtris has (QEMU or Docker)
144 obtainable without a vendor account
 71 send you to a vendor login

The 71 are the ones people usually want — Cisco CSR1000v, Juniper vMX, PA-VM, Arista vEOS. Importing them still helps: you get the correct RAM, NIC model, disk bus and console type, plus the exact page to download from.

The registry is GPL-3.0 and Labtris is Apache-2.0. Labtris reads the format but does not ship the files, which is why you clone them yourself. A file format cannot be copyrighted; bundling the files would carry their licence.

The two settings that stop a guest booting

Both are recorded per image, and both fail in ways that do not look like what they are.

NIC model

virtio-net-pci is fast and needs a driver the guest may not have. A guest without it boots fine and has no network at all — the interface simply is not there. e1000 is emulated hardware from 2002 that everything can drive.

Symptom: the node runs, the console works, and ip link shows only loopback.

Anything old, minimal, or shipped as an appliance usually wants e1000. The image catalogue records which, and you can override it per node.

Disk bus

Same problem, one layer down. A guest handed a virtio disk when its kernel has no virtio-blk driver does not boot — and it does not say so. QEMU starts, the console shows a bootloader or nothing at all, and it hangs.

Symptom: the node says running, the console is blank or stuck at a BIOS screen, and it looks like the host is broken.

Of the 182 QEMU appliances in the GNS3 registry, 67 need IDE rather than virtio — better than one in three. If a guest will not boot and you have checked everything else, this is the thing.

Set it per node under Disk controller in the QEMU options. Leave it blank and the image's own setting is used, which is what you want almost always; the override is there for a bring-your-own image whose needs nothing has recorded.

The names do not agree between tools. QEMU's -drive if= takes virtio, ide, scsi and sd, and refuses sata, nvme and usb — while the GNS3 registry uses sata freely. Labtris translates rather than passing the name through, so an imported appliance starts instead of dying at launch with a complaint about a bus you never chose. sata becomes ide and nvme becomes virtio: approximations, but ones that boot.

Installing an OS from an ISO

Labtris does not (yet) boot an ISO with a scratch disk attached from the UI — booting a bootable CD-ROM plus a blank install target is a different QEMU command shape from booting an existing disk image, and the surface for it in Labtris is not built. Do the install once at the shell, then upload the resulting .qcow2 — the "Upload image" dialog and labtris-image add described below both take that file straight in.

1. Create the empty disk. Pick a size the installer will accept:

qemu-img create -f qcow2 myvm.qcow2 20G

qcow2 is thin-provisioned, so a 20 GB file uses only the bytes actually written — an OS install ends up 3–8 GB whatever number you picked.

2. Boot QEMU with the ISO as CD-ROM. For a graphical install you can drive over the network by VNC:

qemu-system-x86_64 \
  -m 2048 -cpu qemu64 -smp 2 -accel kvm \
  -drive file=myvm.qcow2,if=virtio,format=qcow2 \
  -cdrom installer.iso -boot d \
  -netdev user,id=n1 -device virtio-net-pci,netdev=n1 \
  -vnc :10 -display none

Attach a VNC viewer to <host>:5910 and complete the install. -boot d says "boot from CD-ROM this once"; on a normal reboot the machine will fall back to the disk. If your installer supports a serial console (Ubuntu's autoinstall does, most vendor installers do not), swap -vnc :10 -display none for -nographic -serial mon:stdio and drive it from the terminal.

3. Reboot without the ISO to verify the disk boots on its own, and take the one-time opportunity to do things you cannot easily do per node later: apply initial updates, install an SSH key, remove the installer packages, cloud-init clean if you want the next boot to re-run cloud-init.

qemu-system-x86_64 \
  -m 2048 -cpu qemu64 -smp 2 -accel kvm \
  -drive file=myvm.qcow2,if=virtio,format=qcow2 \
  -netdev user,id=n1 -device virtio-net-pci,netdev=n1 \
  -vnc :10 -display none

4. Sparsify. After the install, a qemu-img convert -O qcow2 -c produces a smaller file that unpacks to the same content — commonly 5–10× smaller than the raw install. Labtris does this on flatten too, but the smaller file uploads faster.

qemu-img convert -O qcow2 -c myvm.qcow2 myvm-shrunk.qcow2

Bake once, boot many

The point of doing the install once and uploading the result — rather than running the ISO every time — is that every node using the image starts from the same bytes. So keep the base image generic: don't bake in the hostname, don't fix an IP, don't keep the SSH host keys. If the guest has cloud-init, leave it enabled and let it re-personalise per boot. If it does not, the first-boot experience is going to include running whatever setup wizard the vendor ships.

Upload it to Labtris

Two ways in, same shape out:

`` sudo -u labtris /opt/labtris/.venv/bin/labtris-image add \ /path/to/myvm.qcow2 \ --name "my custom vm" \ --ram-mb 2048 --nic-model virtio-net-pci --disk-bus virtio \ --iface-scheme ens ``

--help lists every knob. The CLI writes into the same image cache the service uses, so it has to run as the labtris user (or root) — a permissions error prints the sudo -u labtris line to re-run.

Either path stores the disk under its content hash and drops a Your templates entry pointing at it. Uploading the same file twice under different names stores it once and gives you two entries — content-addressed storage means dedup is free.

Only .qcow2 and other disk formats (.img, .vmdk, .vdi, .vhd, .raw) upload directly. .iso is refused with a pointer at this page — the "boot the CD-ROM with a scratch qcow2" flow lives outside Labtris for now, which is what this whole section is about.

Recipes

Ready-made install-and-register scripts for the ISOs people ask for most often live in packaging/recipes/. Each one is the four-step flow above with the right flags baked in, and calls labtris-image add for you at the end. The interactive part (VNC into the installer, click through its wizard, set a password) is still yours — everything around it isn't.

VyOS (installer ISO from community-downloads.vyos.dev)sudo packaging/recipes/vyos.sh

Add more by copying vyos.sh; the shape is the same for any appliance whose vendor ships a bootable installer instead of a ready qcow2.

Saving a configured guest as a template

Booting a vendor appliance, accepting its licence and configuring it is an afternoon's work. You should do it once.

Stop the node, select it, and Export as template. For a QEMU node that flattens the node's disk — its overlay and everything under it — into a new standalone image, and records it in the palette under Your templates. Drag it out again and you get the machine as you left it.

The node has to be stopped. A disk that a running guest is still writing has no consistent moment to copy, and the damage shows up days later on a template people had started to trust.

A few things worth knowing:

For a Docker node this is metadata only — an image reference already names immutable content, so there is nothing to copy.

Sizing

Each node can override the image's defaults for RAM, vCPU and NIC model. None of it can change on a running guest; it is what the node boots with next time.

The image's numbers are a floor that someone actually booted, not a guess. Going below them usually produces a guest that starts and then fails in a way that takes an hour to attribute to memory.

Where images live

QEMU disks are cached under the image cache directory and shared between nodes using the same image, so ten Ubuntu nodes are one download. A node's own writes go to its own overlay, which is what makes wiping a node cheap.

See Running the server for moving that directory somewhere larger.

Next

Networking — how nodes are joined, and what each kind of segment does.