a73x

docs/joining.md

Ref:   Size: 4.7 KiB   History

# Joining a host

*Putting a machine into your fleet, Linux or Mac*

A host is any machine that runs VMs for you. Joining is one command per
machine, whichever plane it reports to: the console prints a one-shot join
blob, the agent dials out with it, and the host comes **online**. Nothing
listens for an inbound connection, so a machine behind NAT needs no open
ports.

Where the console lives differs. On the hosted service it is
<https://console.eitri.sh> ([quickstart](quickstart.md)); on your own plane it
is your server ([self-hosting](self-hosting.md)), and the join command comes
from your own **+ Add host**.

## Join a Linux host

On the machine that will serve VMs—Linux with KVM (`ls -l /dev/kvm`)—download
and verify the host bundle:

```sh
curl -fsSLO https://eitri.sh/dl/latest/SHA256SUMS
V=$(sed -n 's/.*eitri-server_\(v[^_]*\)_linux_amd64\.tar\.gz$/\1/p' SHA256SUMS)
curl -fsSLO "https://eitri.sh/dl/latest/eitri-server_${V}_linux_amd64.tar.gz"
sha256sum -c SHA256SUMS --ignore-missing
tar xzf "eitri-server_${V}_linux_amd64.tar.gz" && cd "eitri-server_${V}_linux_amd64"
```

`/dl/latest/` is the current release. Its filenames carry the version, so
`SHA256SUMS`—which you need to verify anyway—is where you read it from.

The Linux host bundle is named for the `eitri-server` it also carries: a box
that only runs VMs installs the `eitri-agent` inside it and nothing else. On an
arm64 host, `_arm64` replaces `_amd64` throughout.

Then click **+ Add host** in the console and run the command it prints
from the unpacked bundle—it installs the agent and joins this machine
to your tenant:

```sh
sudo install -m 0755 eitri-agent /usr/local/bin/eitri-agent
sudo install -m 0644 eitri-agent.service /etc/systemd/system/eitri-agent.service
sudo eitri-agent --state-dir /var/lib/eitri-agent join eitri_join_<blob-from-console>
sudo systemctl daemon-reload
sudo systemctl enable --now eitri-agent
```

The agent dials out—a machine behind NAT needs no open ports. It goes
online in the console within seconds.

## Join a Mac

A Mac joins the same way, with two differences. It runs guests through
[vfkit](https://github.com/crc-org/vfkit) on Apple's Virtualization.framework,
and you install that yourself:

```sh
brew install vfkit
```

Homebrew's is the copy to use. Without vfkit, VMs placed on this host fail at
once, saying so; the agent installs cloud-hypervisor for you on Linux, but it
cannot install this.

Take the darwin bundle instead of the linux one:
`eitri-agent_<version>_darwin_arm64.tar.gz`, the agent and its LaunchAgent
installer, no server. macOS ships no `sha256sum`, so `shasum` checks the one
line of `SHA256SUMS` that names it:

```sh
curl -fsSLO https://eitri.sh/dl/latest/SHA256SUMS
V=$(sed -n 's/.*eitri-agent_\(v[^_]*\)_darwin_arm64\.tar\.gz$/\1/p' SHA256SUMS)
curl -fsSLO "https://eitri.sh/dl/latest/eitri-agent_${V}_darwin_arm64.tar.gz"
grep " eitri-agent_${V}_darwin_arm64.tar.gz$" SHA256SUMS | shasum -a 256 -c -
tar xzf "eitri-agent_${V}_darwin_arm64.tar.gz" && cd "eitri-agent_${V}_darwin_arm64"
```

Nothing here needs `sudo`, and nothing goes in a system directory:

```sh
mkdir -p ~/.local/bin && cp eitri-agent ~/.local/bin/
~/.local/bin/eitri-agent join eitri_join_<blob-from-console>
./eitri-agent-launchagent.sh install ~/.local/bin/eitri-agent
```

State lands in `~/.eitri/agent`, logs in `~/Library/Logs/eitri-agent.log`, and
the agent starts with your session.

The agent dials its guests over vmnet, and macOS gates local-network dialing
per app: the agent needs the **Local Network** permission. Run from a
terminal, the agent is prompted for it; installed as a LaunchAgent, it may
never be. Grant it under System Settings → Privacy & Security → Local
Network. Without
it, guests boot and take a vmnet lease but stay unreachable through the
gate—`eitri ssh` fails with "cannot reach VM".

Keep the binary somewhere this account owns—the agent replaces it in place
when it upgrades, and the installer refuses a root-owned prefix like
`/usr/local/bin` rather than leave you unable to upgrade.

## What a Mac host does differently

- **arm64 guests only.** A VM created without an explicit image gets the arm64
  default; if you name an image, name an arm64 one—nothing downstream checks,
  and one built for the wrong architecture boots into nothing.
- **Guest addresses come from macOS.** A Mac's guests sit on vmnet's subnet,
  which is what the console shows. `eitri ssh`, the console and reconcile are
  the same as anywhere else.
- **The agent runs with your session**, unprivileged, as a LaunchAgent. For a
  machine that must run guests with nobody logged in, move the generated plist
  to `/Library/LaunchDaemons` and add a `UserName` key naming this account;
  leave the binary and state where they are.