nix: move the agent option namespace under services.hyperhive.agent
Every per-agent harness option lived at the top-level `hyperhive.*` while the host tier has always been `services.hyperhive.*`. Move all 52 agent-tier option leaves (33 top-level names across 16 modules) to `services.hyperhive.agent.*`, repoint every read, and keep existing agent configs evaluating through one `mkRenamedOptionModule` per old leaf path in the new nix/agent-modules/renamed-options.nix. The shims are per leaf rather than per namespace: `user`, `mcp`, `otel`, `queue`, `docs`, `forge`, `frontend`, `github`, `gui`, `logs`, `matrix` and `cargo` are plain attrsets of declarations, not submodule-typed options, so a parent-path rename would not reach their children. Three read-only options (`frontend.mergedDist`, `queue.clientIdFile`, `queue.clientSecretFile`) deliberately get no shim — a rename contributes a definition, which a read-only option refuses; the exclusions are commented in place. Refs #4473
This commit is contained in:
parent
60393d0e32
commit
3662eda440
21 changed files with 531 additions and 290 deletions
|
|
@ -1,4 +1,4 @@
|
|||
# Per-agent unix user: the `hyperhive.user.*` options, the user/group
|
||||
# Per-agent unix user: the `services.hyperhive.agent.user.*` options, the user/group
|
||||
# declarations, passwordless sudo, and the first-boot migration that
|
||||
# chowns the bind-mounted state dirs to the agent user.
|
||||
{
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
...
|
||||
}:
|
||||
let
|
||||
userName = config.hyperhive.user.name;
|
||||
userName = config.services.hyperhive.agent.user.name;
|
||||
homeDir = "/home/${userName}";
|
||||
in
|
||||
{
|
||||
|
|
@ -20,7 +20,7 @@ in
|
|||
# uniquely-named user matching its agent label. UID auto-assigned
|
||||
# by NixOS (the auto-allocation range for normal users); no hard-
|
||||
# coded UID.
|
||||
options.hyperhive.user.name = lib.mkOption {
|
||||
options.services.hyperhive.agent.user.name = lib.mkOption {
|
||||
type = lib.types.strMatching "^[a-z_][a-z0-9_-]{0,30}$";
|
||||
default = "agent";
|
||||
example = "iris";
|
||||
|
|
@ -33,11 +33,11 @@ in
|
|||
|
||||
Constraints match `useradd`'s NAME_REGEX: lowercase / `_` start,
|
||||
total length ≤ 31, no special characters. UID is auto-assigned
|
||||
by NixOS unless `hyperhive.user.uid` is explicitly set.
|
||||
by NixOS unless `services.hyperhive.agent.user.uid` is explicitly set.
|
||||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.user.uid = lib.mkOption {
|
||||
options.services.hyperhive.agent.user.uid = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
example = 1100;
|
||||
|
|
@ -59,24 +59,24 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.user.gid = lib.mkOption {
|
||||
options.services.hyperhive.agent.user.gid = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.int;
|
||||
default = null;
|
||||
example = 1100;
|
||||
description = ''
|
||||
Optional fixed GID for the per-agent unix group. `null` (default)
|
||||
lets NixOS auto-assign. Usually set alongside `hyperhive.user.uid`
|
||||
lets NixOS auto-assign. Usually set alongside `services.hyperhive.agent.user.uid`
|
||||
to the same value (the conventional Unix pattern for per-user
|
||||
groups where uid == gid), but can be set independently.
|
||||
'';
|
||||
};
|
||||
|
||||
options.hyperhive.user.passwordlessSudo = lib.mkOption {
|
||||
options.services.hyperhive.agent.user.passwordlessSudo = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
example = false;
|
||||
description = ''
|
||||
Grant `${config.hyperhive.user.name}` passwordless sudo
|
||||
Grant `${config.services.hyperhive.agent.user.name}` passwordless sudo
|
||||
(`NOPASSWD: ALL`). True by default so claude's `Bash` tool
|
||||
keeps working for tools that expect root inside the container
|
||||
(`systemctl`, package managers in dev shells, etc.) — the
|
||||
|
|
@ -94,10 +94,12 @@ in
|
|||
assertions = [
|
||||
{
|
||||
assertion =
|
||||
config.hyperhive.user.uid == null
|
||||
|| (config.hyperhive.user.uid >= 1000 && config.hyperhive.user.uid < 60000);
|
||||
config.services.hyperhive.agent.user.uid == null
|
||||
|| (
|
||||
config.services.hyperhive.agent.user.uid >= 1000 && config.services.hyperhive.agent.user.uid < 60000
|
||||
);
|
||||
message = ''
|
||||
hyperhive.user.uid must be in [1000, 60000) — values below
|
||||
services.hyperhive.agent.user.uid must be in [1000, 60000) — values below
|
||||
1000 clash with system accounts; values ≥ 60000 are reserved
|
||||
by NixOS for dynamic allocation. Leave unset (null) to let
|
||||
NixOS auto-assign.
|
||||
|
|
@ -105,11 +107,13 @@ in
|
|||
}
|
||||
{
|
||||
assertion =
|
||||
config.hyperhive.user.gid == null
|
||||
|| (config.hyperhive.user.gid >= 1000 && config.hyperhive.user.gid < 60000);
|
||||
config.services.hyperhive.agent.user.gid == null
|
||||
|| (
|
||||
config.services.hyperhive.agent.user.gid >= 1000 && config.services.hyperhive.agent.user.gid < 60000
|
||||
);
|
||||
message = ''
|
||||
hyperhive.user.gid must be in [1000, 60000) — same range
|
||||
constraint as hyperhive.user.uid.
|
||||
services.hyperhive.agent.user.gid must be in [1000, 60000) — same range
|
||||
constraint as services.hyperhive.agent.user.uid.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
|
@ -123,29 +127,29 @@ in
|
|||
home = homeDir;
|
||||
createHome = true;
|
||||
group = userName;
|
||||
extraGroups = lib.optional config.hyperhive.user.passwordlessSudo "wheel";
|
||||
extraGroups = lib.optional config.services.hyperhive.agent.user.passwordlessSudo "wheel";
|
||||
# Matches /bin/bash on NixOS — the harness's claude shell-outs
|
||||
# expect a POSIX shell at $SHELL; bashInteractive is already
|
||||
# the system default for the root user too.
|
||||
shell = pkgs.bashInteractive;
|
||||
}
|
||||
// lib.optionalAttrs (config.hyperhive.user.uid != null) {
|
||||
uid = config.hyperhive.user.uid;
|
||||
// lib.optionalAttrs (config.services.hyperhive.agent.user.uid != null) {
|
||||
uid = config.services.hyperhive.agent.user.uid;
|
||||
};
|
||||
users.groups.${userName} =
|
||||
{ }
|
||||
// lib.optionalAttrs (config.hyperhive.user.gid != null) {
|
||||
gid = config.hyperhive.user.gid;
|
||||
// lib.optionalAttrs (config.services.hyperhive.agent.user.gid != null) {
|
||||
gid = config.services.hyperhive.agent.user.gid;
|
||||
};
|
||||
|
||||
# `NOPASSWD: ALL` for the agent user. Lets claude's Bash tool
|
||||
# keep working with anything that expected root (systemctl,
|
||||
# nix-env, etc.) without prompting. Flip
|
||||
# `hyperhive.user.passwordlessSudo = false` to drop both
|
||||
# `services.hyperhive.agent.user.passwordlessSudo = false` to drop both
|
||||
# the wheel-group membership and this sudoers entry; anything
|
||||
# that needs root then fails loudly instead of silently
|
||||
# succeeding.
|
||||
security.sudo.extraRules = lib.mkIf config.hyperhive.user.passwordlessSudo [
|
||||
security.sudo.extraRules = lib.mkIf config.services.hyperhive.agent.user.passwordlessSudo [
|
||||
{
|
||||
users = [ userName ];
|
||||
commands = [
|
||||
|
|
|
|||
Loading…
Reference in a new issue