identity
Write an operator instance stamp, /etc/vrtmv/instance-id, so a host has its own billing identity. The stamp is a random 128-bit id written as 32 hex characters, mode 0444. It calls no API and bills nothing.
A host is billed as one seat per identity. vrtmv reads the identity from the stamp when there is one, else from /etc/machine-id, else from /var/lib/dbus/machine-id. A host with none of them is refused by the billed commands until it has one.
vrtmv identity # the host you are on
vrtmv identity --root /mnt/web03 # a mounted image or root
vrtmv identity --force # replace a stamp that came with the image
vrtmv identity --ssh root@web03 # a running host, over SSH
vrtmv identity --ssh admin@web03 --sudo --jump ops@bastion
| Flag | Purpose |
|---|---|
--root <path> | Write under this root instead of /. |
--ssh <user@host> | Write the stamp on a running host over SSH. The login must be root, or pass --sudo. Not with --root. |
--ssh-port <port> | SSH port (default 22). |
--ssh-key <path> | SSH identity file (default: the agent and ~/.ssh/config). |
--jump <user@host> | Jump host (ProxyJump). |
--sudo | Write with sudo. Needs passwordless sudo on the host. |
--force | Replace a valid stamp that is already there. This changes the host's billing identity. |
A valid stamp is left alone unless you pass --force, and the command says so and exits non-zero. A stamp that is not valid (too short, or all zeros) is replaced. A directory at the path, or a file that cannot be read or is not UTF-8 text, is refused, even with --force: remove it and run again.
With --ssh, the id is made on the machine you run vrtmv on, and so is the decision. The host sends back the file that is at the path, vrtmv judges it by the rule it bills under, and the stamp is written only if the file has not changed since. Two cases differ from a local run, and no stamp is either one: a file larger than 4096 bytes is refused, and a symlink to nothing is replaced by the stamp rather than written through.
Clones
An identity that is copied with an image is not a host's own. systemd writes a new /etc/machine-id at first boot when the image left it empty. On a host without systemd, such as OpenRC Gentoo, nothing rewrites /var/lib/dbus/machine-id, and nothing rewrites a stamp written in the template. Every clone of that image then reports one identity.
So when the identity comes from /var/lib/dbus/machine-id (there is no /etc/machine-id) or from a stamp, migrate prints a one-line note that says so. The note is a warning, not a refusal. If the host was cloned, run vrtmv identity on it, or vrtmv identity --ssh user@host from where you run vrtmv; if the stamp came from the template, add --force.
A fleet run sees clones directly. When two or more hosts of one run report one identity, they are clones of one image or one host listed under several names, such as a hostname and an IP address. The commands that bill refuse each of those hosts. They emit, attest and report nothing for it, the rest of the fleet goes on, and the run exits non-zero. Those commands are cluster-migrate --emit-roles, coupled-migrate (it refuses the whole cluster), container-fleet, license and cve-scan-fleet (see cve-scan). The refusal names the hosts and the file the identity came from:
web-03, web-07, web-12 report one machine identity (machine-id from /var/lib/dbus/machine-id). They are clones of one image, or one host listed under several names. On each clone, run `vrtmv identity` (add --force if the stamp came from the template); if they are one host, keep one of its names in the manifest. Then re-run. Nothing was emitted or billed for these hosts.
cluster-migrate without --emit-roles, assess-fleet and readiness print the same finding as a warning and go on. If the hosts are one host under two names, remove one of the names from the manifest instead.
Once each clone has its own stamp, each one is its own seat.