Skip to content

List machines

Source · io.systemd.Machine · systemd v257+ · Unprivileged

machinectl list over Varlink: stream every container and VM registered with systemd-machined. It also shows a real-world quirk: machined answers "nothing registered" with an error rather than an empty stream.

Run it

go run ./examples/machines
Output (illustrative)
MACHINE  CLASS      SERVICE         UNIT                        LEADER
web      container  systemd-nspawn  systemd-nspawn@web.service  48213
win11    vm         libvirt-qemu    machine-qemu-1-win11.scope  50122

2 machines listed.

The code

examples/machines/main.go
// Command machines lists containers and VMs registered with
// systemd-machined, like `machinectl list`.
//
//  go run ./examples/machines
package main

import (
    "context"
    "errors"
    "fmt"
    "log"
    "os"
    "text/tabwriter"

    "github.com/rossedman/sdvarlink/systemd/v257/machine"
    "github.com/rossedman/sdvarlink/varlink"
)

func main() {
    ctx := context.Background()
    c, err := machine.Dial(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer c.Close()

    w := tabwriter.NewWriter(os.Stdout, 0, 4, 2, ' ', 0)
    fmt.Fprintln(w, "MACHINE\tCLASS\tSERVICE\tUNIT\tLEADER")
    n := 0
    for m, err := range c.ListMore(ctx, machine.ListIn{}) {
        if errors.Is(err, machine.ErrNoSuchMachine) {
            break // machined answers NoSuchMachine when nothing is registered
        }
        if err != nil {
            log.Fatal(err)
        }
        leader := int64(0)
        if m.Leader != nil {
            leader = m.Leader.PID
        }
        fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%d\n", m.Name, m.Class, varlink.Deref(m.Service), varlink.Deref(m.Unit), leader)
        n++
    }
    w.Flush()
    fmt.Printf("\n%d machines listed.\n", n)
}

How it works

  • Empty is an error. With no machines registered, ListMore yields io.systemd.Machine.NoSuchMachine. errors.Is(err, machine.ErrNoSuchMachine) turns that into "zero machines".
  • Nested optional structs. Leader is a *ProcessID; the example checks for nil before reading PID.
  • Pointers for optional strings, read with varlink.Deref.

See also