CLI Reference
The network package contract
A network package makes a private network reachable through devmachine
without the CLI knowing the product. It declares a
network: block and ships up to three
scripts. This page says what each one gets and what it must give back.
Every script is Python 3 with no dependencies beyond the standard library,
and must run on Python 3.9: that is what macOS ships, and resolve runs on
your computer. Every script gets the machine’s settings for its package as
one JSON object in the DEVMACHINE_SETTINGS variable: each variable the
package declares, with its default, and any <package>.<name> setting of
the machine on top.
{"exit_node": false, "login_server": "https://net.example.com"}
resolve
Runs on your computer, every time something needs the machine’s
addresses: a connection, devmachine resolve, an SSH alias.
- Argument: the name, as written after the prefix.
tailscale:maingivesmain. It is an argument, never part of a shell line. - Output: the machine’s IP addresses on standard output, one per line, in the order to try them. Anything that is not an IP address is refused.
- Exit 0: the addresses are good.
- Exit 3: the network is not reachable from here — the app is not
installed, not running, or not signed in. Print why on standard error
in a few words (
tailscale is not running). The entry is skipped, not reported as a failure. - Any other exit: something is wrong with the script or the network. The entry is skipped too, and standard error is shown as the reason.
- Time: 5 seconds, then it is stopped and skipped.
It runs from the package’s own folder on your computer: the pinned
release a sync downloaded, or <config>/packages/<name>/.
join
Runs on the machine, as its admin account, for
devmachine login <package>, in a real terminal (ssh -t). It does
whatever signing in to the network takes: printing a URL to open, reading
an auth key, calling the network’s own command. Exit 0 when the machine
joined.
It runs from where sync put the package:
/opt/devmachine/roles/<package>/ for a published package, or
/opt/devmachine/roles.local/<package>/ for one from your own
packages/. So the package has to be synced before login.
self_name
Runs on the machine, as its admin, right after join succeeds. It
prints the name the machine answers to on the network, on one line: letters,
digits, dots, dashes and underscores. devmachine adds <prefix>:<name> as
the first entry of the machine’s hosts in config.yml, unless it is
already there. The public address stays as a fallback.
If it fails, or prints something that cannot be a host entry, the login
still counts, and devmachine prints the hosts: block to paste by hand.
An example
The tailscale package in the packages repository is the reference:
resolve reads tailscale status --json on your computer, join runs
tailscale up with --login-server when tailscale.login_server is set,
and self_name reads the machine’s own tailscale status --json.