Files
mesh-catalog/modules/openrazer/README.md
T
jochen da57051fa3
mesh/merge-gate pass: builds openrazer → g14, shanks; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery covered: a later merge that contains it was delivered: novox/mesh-catalog@5d7d9020b8c7 (merged as bf542128 into main, walk plan-17914696454…
mesh/delivery-group group feat/module-groups delivered: every member is delivered
Declare the operator's account in the openrazer group (hq ADR 0252, issue 247)
The daemon refuses to start outside the group, and the fix was a sudo step by hand that nothing
recorded. The module now declares it; the operator logs in again once.
2026-10-08 12:04:08 +02:00

120 lines
7.4 KiB
Markdown

# openrazer
The Razer peripherals' kernel driver and the account's daemon that drives it, on the workstations, as
a module (novox/hq ADR 0208: one module per piece of software). The tray that shows the devices is
the `polychromatic` module's. This module needs no display: the daemon speaks to the driver and to its
clients on the session bus.
## Owns
| what | where |
|---|---|
| the kernel driver's source, built by DKMS for each installed kernel (`razerkbd`, `razermouse`, `razerkraken`, `razeraccessory`) | package `openrazer-driver-dkms` |
| the daemon (`org.razer` on the session bus) and its user unit | package `openrazer-daemon` |
| the client library every front end speaks to the daemon through | package `python-openrazer` |
| the operator's account in the group `openrazer` | a `user` resource naming the account and that group, nothing else of it |
All three from the official repositories (`extra`). On both workstations they are installed today as
dependencies of the AUR tray, and become the mesh's here.
**Why two modules and not one `razer`:** the driver and the daemon are one project, in the official
repositories, and any front end uses them. The tray is another project, outside the official
repositories. That is the line between `bluetooth` and `blueman` too. A machine can hold the stack
without the tray, for a front end of the operator's own or for the daemon's persistence of the
devices' lighting and DPI.
Not this module's:
- **The kernel headers DKMS builds against** (`linux-headers`). They are the kernel's, and every DKMS
driver on a machine needs them (the laptop also builds `nvidia`, the desktop `vboxhost` and `xone`).
No module declares them yet. `openrazer_check` says when the driver is not built for the running
kernel.
- **`dkms` itself**, which the driver package depends on.
- **The account's shell, home and other groups**: the login shell's module's, and the operator's.
## The group: declared here, and a new login once
The driver's udev rules give each device's files to the group `openrazer`, which the driver package
creates (sysusers). The daemon refuses to start for an account outside that group: *User is not a
member of the openrazer group*.
**The module puts the operator's account in `openrazer`** (novox/hq ADR 0252, issue 247). It declares
the account as a `user` resource with that one group and nothing else of it. The `zsh` module declares
the same account to set its shell; the controller lets several modules add groups to one account, and
refuses only two that set its shell or home. The resource is written after the three packages, and the
controller keeps it there, so the group exists when the account is put in it.
- **The account's other groups are never touched.** The node-engine appends (`usermod --append`).
- **A new login is needed.** The account's running service manager, and the daemon it starts, keep the
groups they started with. The node-engine says so in the apply's outcome, and on every look until the
running manager has the group: the module's resource `openrazer.account`, of kind `account`, is
unhealthy with *relogin needed*, and the controller raises it as openrazer's condition on that machine.
It clears on the first look after a new login.
- **Unassigned, the account leaves `openrazer`**, but only if the mesh put it there and no other module
still asks for it. An account that was in the group before is left in it.
**On both workstations the account is not in it today, so the daemon has failed at every start**
since openrazer moved from `plugdev` to its own group. The tray runs, and shows no devices. The account
is still in `plugdev`, which openrazer no longer uses. Another device's rules may (the laptop has a
Logitech receiver rule that does), so it stays.
## How it starts: D-Bus activation, and nothing else
The package installs `org.razer` as a D-Bus service whose `SystemdService` is the user unit
`openrazer-daemon.service`. The first client that asks for `org.razer` starts the daemon through that
unit: at login, the tray's helper (`polychromatic-helper --autostart`). **That activation is the
daemon's one start.** One unit, so it is never two daemons.
- The unit is **not enabled** on either workstation, and the module does not enable it. Enabling it
would start the same unit at login a moment earlier, with nothing gained.
- Asked by a tool, the bus is always called with `--auto-start=no`, so asking never starts it.
## Tools
They are served by the node's runtime as the operator account (ADR 0175).
| tool | does |
|---|---|
| `openrazer_status` (r) | <ul><li>the three packages' versions</li><li>the driver: the running kernel, DKMS's state for it, the modules loaded, the devices bound (USB id, driver, interfaces)</li><li>the group: whether the account is in it, and whether the account's running service manager has it</li><li>the daemon: its unit's active and enabled states, its process, its version, and, when its unit failed, the reason it gave</li><li>each device the daemon sees: name, type, firmware, battery and charging where the device has them. Never its serial</li></ul> |
| `openrazer_restart` (a) | restarts `openrazer-daemon.service` in the account's service manager and answers the devices it then sees. When it fails, the answer carries the daemon's own reason |
| `openrazer_check` (r) | <ul><li>the packages are installed</li><li>the driver is built for the running kernel, and loaded</li><li>a device is bound</li><li>the account is in `openrazer`, and its service manager has the group (a group added after login needs a new login)</li><li>one start: the activation file is present, no window-manager exec</li><li>one daemon runs, from its unit, and answers</li><li>it sees every device the driver holds</li></ul>Each finding says what to do |
Every command has a timeout and capped output. Everything runs through an injected runner and a fake
root in the tests.
## What changes when it is assigned
| | laptop | desktop |
|---|---|---|
| packages | none: the three are installed, 3.12.4, as dependencies of the tray | the same |
| driver | none: built for the running kernel, `razermouse` loaded, a Basilisk V3 Pro bound | the same, a Basilisk V2 bound |
| the account | put in `openrazer`; its other groups as they are | the same |
| daemon | none: the unit stays disabled; it failed at login (not in the group) | the same |
## Migration (ADR 0182)
On each workstation, once, after the push that sends this module's account resource:
1. The apply puts the account in `openrazer`, and openrazer's health says *relogin needed*.
2. Log out of every session, or reboot. The account's service manager takes its groups when it
starts, and the daemon runs under it.
3. The condition clears, `openrazer_check` answers `ok`, and the tray shows the devices.
`plugdev` stays. Nothing else is required, and nothing is done with `sudo` by hand.
## Leaves as found
- The daemon's settings and persistence under `~/.config/openrazer/`, and its log under
`~/.local/share/openrazer/`.
- `plugdev` and every other group of the account.
- The kernel headers and DKMS.
## Relies on
- **A node-engine that gives back what it put the account in, and says a new login is needed** (ADR
0252). An older one puts the account in the group just the same, says nothing of the login, and
never takes the group back.
- **A client to start the daemon.** At login that is the `polychromatic` module's tray helper.
Without a client nothing asks, and nothing needs it to run.
- **The kernel headers of every installed kernel**, for DKMS.