Repository navigation
service linux
mbregistry install-service, the unit and udev rule it writes, drop-ins, logs, upgrade and uninstall. Covers Raspberry Pi OS, Debian and Ubuntu.
This page assumes mbtools is installed in /opt/mbtools (see
Installing mbtools).
The steps are the same on Raspberry Pi OS / Debian (aarch64) and Ubuntu
(x86_64).
sudo /opt/mbtools/bin/mbregistry install-service
sudo systemctl daemon-reload
sudo systemctl enable --now mbregistry.service
sudo udevadm control --reload-rules
sudo udevadm trigger
sudo usermod -aG plugdev "$USER" # then open a new login session
mbregistry list # as a normal userinstall-service writes two files and prints (does not run) the
systemctl / udevadm / usermod commands above. It is idempotent: it
rewrites identical content and never touches the running service. Without
root it fails with could not write ...: Permission denied and exits 1.
| Flag | Default |
|---|---|
--output PATH |
/etc/systemd/system/mbregistry.service |
--udev-output PATH |
/etc/udev/rules.d/99-mbregistry-cmsis-dap.rules |
--user NAME |
$SUDO_USER, then $USER, then current user. Only affects the printed usermod line |
The unit's ExecStart= uses the Python interpreter that ran
install-service. Run it from the venv you want the service to use.
With /opt/mbtools/bin/python3 as that interpreter:
[Unit]
Description=mbregistry -- micro:bit device registry daemon
After=network.target
[Service]
Type=simple
ExecStart=/opt/mbtools/bin/python3 -m mbtools.registry.cli run
Restart=on-failure
RestartSec=2
RuntimeDirectory=mbregistry
StateDirectory=mbregistry
[Install]
WantedBy=multi-user.targetThe service runs as root, so it uses the system paths.
StateDirectory= and RuntimeDirectory= create them:
| Path | |
|---|---|
| Database | /var/lib/mbregistry/devices.db |
| Local API socket |
/run/mbregistry/api.sock (mode 0666: any local user can use it) |
A normal user's mbregistry list, mbdeploy, mbserial and mbrelay try
their own per-user socket first and then this one, so they need no flags.
For comparison, mbregistry run as a normal user (foreground, testing)
uses $XDG_STATE_HOME/mbregistry/devices.db (default
~/.local/state/mbregistry/devices.db) and
$XDG_RUNTIME_DIR/mbregistry/api.sock (or ~/.cache/mbregistry/api.sock
without $XDG_RUNTIME_DIR). Don't run both. One daemon per host.
# CDC-ACM tty device node (mbserial, and pyOCD's DAPLink serial transport)
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", GROUP="plugdev", MODE="0660", TAG+="uaccess"
# Raw USB device node (CMSIS-DAP v2 / WinUSB transport, opened directly by pyOCD)
SUBSYSTEM=="usb", ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", GROUP="plugdev", MODE="0660", TAG+="uaccess"
# hidraw device node (CMSIS-DAP v1 / HID transport)
KERNEL=="hidraw*", ATTRS{idVendor}=="0d28", ATTRS{idProduct}=="0204", GROUP="plugdev", MODE="0660", TAG+="uaccess"
(The real file also starts with a comment header.) The rule is for local
clients run by a normal user. The root daemon doesn't need it. On an
SSH-only host the plugdev group does the work, and a new membership needs
a new login session.
Don't edit the unit, because install-service overwrites it. Use a
drop-in:
sudo systemctl edit mbregistry.service[Service]
# env-var settings (see Command reference for the full list)
Environment=MBREGISTRY_REMOTE_PORT=7440
# flags with no env var (--peer, --no-relay-pool, --interval) need ExecStart replaced:
ExecStart=
ExecStart=/opt/mbtools/bin/python3 -m mbtools.registry.cli run --no-relay-pool --peer host-asudo systemctl restart mbregistrySet --no-relay-pool on hosts with no relay boards. See
Robot-console compatibility.
systemctl status mbregistry
systemctl is-active mbregistry
sudo systemctl restart mbregistry
journalctl -u mbregistry -f # follow
journalctl -u mbregistry -b # since bootThe log is quiet by design. It holds the start-up line plus warnings and errors, with no INFO messages. The start-up line names everything bound:
mbregistry: listening on /run/mbregistry/api.sock (local api), 7440 (remote api), store at /var/lib/mbregistry/devices.db, peering active (pub 7442, snapshot 7443), relay pool on 7444, names API on 7445
Restart=on-failure / RestartSec=2 means a crash (e.g. a port already in
use) shows up as a restart loop. journalctl shows the traceback.
sudo /opt/mbtools/bin/pip install --upgrade "git+https://github.com/League-Microbit/mbtools.git" # or @<tag>
sudo /opt/mbtools/bin/mbregistry install-service
sudo systemctl daemon-reload
sudo systemctl restart mbregistry
mbregistry listThe database is kept and its schema migrates itself on start. If you
recreate the venv instead (e.g. uv venv --clear), stop the service
first. The root daemon leaves root-owned __pycache__ files behind.
Upgrade one host at a time and check mbregistry list on it and on one
peer.
sudo systemctl disable --now mbregistry
sudo rm /etc/systemd/system/mbregistry.service /etc/udev/rules.d/99-mbregistry-cmsis-dap.rules
sudo systemctl daemon-reload && sudo udevadm control --reload-rules
sudo rm -rf /opt/mbtools /var/lib/mbregistry # optionalA host that ran mbdeploy serve (mbdeploy.service) or the legacy
mbrelay.service needs those stopped and disabled before
mbregistry starts, because they hold the same USB ports:
sudo systemctl disable --now mbdeploy.service # if present
sudo systemctl disable --now mbrelay.service # if present (relay hosts)Keep their unit files until the new service has proven itself. Rollback
is disable --now mbregistry followed by enable --now of the old unit.
Which hosts have been migrated is recorded on the internal Robot Garage
wiki.