Watch
0
0
Fork
You've already forked hyperhive
0

Compare commits

..
8 changed files with 55 additions and 59 deletions

View file

@ -58,7 +58,7 @@ hivectl forge reconcile-config iris --verbose # include the full diff, not
Manual entry to the same idempotent matrix provisioning flow Manual entry to the same idempotent matrix provisioning flow
`hive-c0re` runs at boot. Requires the `hive-matrix` container to be `hive-c0re` runs at boot. Requires the `hive-matrix` container to be
running (`services.hyperhive.deploy.matrix.enable = true`). running (`services.hyperhive.swarm.matrix.enable = true`).
```bash ```bash
hivectl matrix create-user iris # provision (or re-provision) matrix account for agent `iris` hivectl matrix create-user iris # provision (or re-provision) matrix account for agent `iris`

View file

@ -1,7 +1,7 @@
//! Optional matrix-tuwunel wiring: shared registration token (host) + //! Optional matrix-tuwunel wiring: shared registration token (host) +
//! per-agent UIAA registration → `<agent-state>/matrix-token`. No-op //! per-agent UIAA registration → `<agent-state>/matrix-token`. No-op
//! when the `hive-matrix` container isn't running, so operators who //! when the `hive-matrix` container isn't running, so operators who
//! haven't flipped `services.hyperhive.deploy.matrix.enable = true` pay //! haven't flipped `services.hyperhive.swarm.matrix.enable = true` pay
//! nothing. //! nothing.
//! //!
//! See `docs/matrix.md::Provisioning flow (registration token)` for //! See `docs/matrix.md::Provisioning flow (registration token)` for

View file

@ -487,7 +487,7 @@ fn require_matrix_present() -> Result<()> {
return Ok(()); return Ok(());
} }
anyhow::bail!( anyhow::bail!(
"no matrix homeserver configured — set services.hyperhive.deploy.matrix.enable = true to run one \ "no matrix homeserver configured — set services.hyperhive.swarm.matrix.enable = true to run one \
here, or services.hyperhive.swarm.matrix.apiUrl to point at an existing one, before \ here, or services.hyperhive.swarm.matrix.apiUrl to point at an existing one, before \
provisioning matrix users" provisioning matrix users"
) )

View file

@ -54,7 +54,7 @@ let
boot.loader.grub.enable = false; boot.loader.grub.enable = false;
system.stateVersion = "25.11"; system.stateVersion = "25.11";
services.hyperhive.enable = lib.mkForce false; services.hyperhive.enable = lib.mkForce false;
services.hyperhive.deploy.matrix.enable = lib.mkForce false; services.hyperhive.swarm.matrix.enable = lib.mkForce false;
} }
) )
]; ];

View file

@ -152,24 +152,6 @@ in
''; '';
}; };
matrix.enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Run the swarm's matrix homeserver — matrix-tuwunel, in a
`hive-matrix` container — on this host.
Derives from
{option}`services.hyperhive.swarm.enableRequiredServices` with
the other once-per-swarm services. Set it here directly to put
the homeserver somewhere other than the host holding the rest.
Client-side settings stay in
{option}`services.hyperhive.swarm.matrix.*`, which every hive
agrees on; this is only the decision to run it here.
'';
};
nats.enable = lib.mkOption { nats.enable = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = false; default = false;

View file

@ -159,26 +159,28 @@ in
# a reading no correctly-built hive should ever have to make. # a reading no correctly-built hive should ever have to make.
HIVE_RESERVED_NAMES = lib.concatStringsSep " " (import ../../reserved-names.nix); HIVE_RESERVED_NAMES = lib.concatStringsSep " " (import ../../reserved-names.nix);
} }
// lib.optionalAttrs (config.services.hyperhive.swarm.matrix.gatewayHost != null) { //
# Matrix homeserver URL for each agent's hive-matrix-daemon — the lib.optionalAttrs
# gateway vhost (`chat.<swarm-domain>`). Forwarded to agents by meta.rs (
# alongside HIVE_FORGE_URL; shares the same env-forwarding ordering config.services.hyperhive.swarm.matrix.enable
# caveat (value baked at config-generation time). && config.services.hyperhive.swarm.matrix.gatewayHost != null
# )
# Deliberately NOT conditioned on this host running the homeserver. A {
# swarm has one matrix, and every hive's agents talk to it — the hive # In-cluster matrix homeserver URL for each agent's
# that hosts it is not the only hive whose agents need its address. # hive-matrix-daemon — the gateway vhost (`matrix.<domain>`).
# `gatewayHost` is swarm-scoped and names that one homeserver from any # Forwarded to agents by meta.rs alongside HIVE_FORGE_URL; shares the
# member hive, so its being set is the whole question. # same env-forwarding ordering caveat (value baked at
# # config-generation time).
# Null forwards nothing rather than falling back to loopback. That #
# fallback reads as harmless because hive-c0re shares the host netns — # A domain-less config forwards nothing rather than falling back to
# but the value is handed to *agents*, which do not, so `127.0.0.1` # loopback. The old fallback read as harmless because hive-c0re shares
# there names the agent itself. An absent forward leaves # the host netns — but the value it produced was handed to *agents*,
# `hyperhive.matrix.url` null and the daemon no-ops; that is the honest # which do not, so `127.0.0.1` there names the agent itself. An absent
# answer when there is no matrix vhost to point at. # forward leaves `hyperhive.matrix.url` null and the daemon no-ops;
HIVE_MATRIX_URL = "http://${config.services.hyperhive.swarm.matrix.gatewayHost}"; # that is the honest answer when the hive has no matrix vhost to point
} # at.
HIVE_MATRIX_URL = "http://${config.services.hyperhive.swarm.matrix.gatewayHost}";
}
// lib.optionalAttrs (config.services.hyperhive.swarm.matrix.apiUrl != null) { // lib.optionalAttrs (config.services.hyperhive.swarm.matrix.apiUrl != null) {
# Client-server API base hive-c0re uses to provision matrix (register # Client-server API base hive-c0re uses to provision matrix (register
# agent users, create the hive space + chat room, invite members). # agent users, create the hive space + chat room, invite members).

View file

@ -164,13 +164,6 @@ in
[ "services" "hyperhive" "matrix" ] [ "services" "hyperhive" "matrix" ]
[ "services" "hyperhive" "swarm" "matrix" ] [ "services" "hyperhive" "swarm" "matrix" ]
) )
# "does THIS host run it" is a per-host decision, and `swarm.*` is the
# namespace every host in the swarm agrees on. The rest of the matrix
# settings genuinely are swarm-wide and stay where they are.
(lib.mkRenamedOptionModule
[ "services" "hyperhive" "swarm" "matrix" "enable" ]
[ "services" "hyperhive" "deploy" "matrix" "enable" ]
)
(lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "matrix" "sso" "enable" ] '' (lib.mkRemovedOptionModule [ "services" "hyperhive" "swarm" "matrix" "sso" "enable" ] ''
SSO is no longer optional: a homeserver that runs at all delegates SSO is no longer optional: a homeserver that runs at all delegates
login to the swarm's authelia. login to the swarm's authelia.
@ -184,6 +177,21 @@ in
]; ];
options.services.hyperhive.swarm.matrix = { options.services.hyperhive.swarm.matrix = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Run hive-matrix — a private matrix-tuwunel homeserver (in a
nixos-container) for hyperhive agents.
Matrix is a swarm-wide service — one homeserver, not one per
hive — so `services.hyperhive.swarm.enableRequiredServices`
turns this on as part of saying the swarm's shared services live
on this host. Set it here directly to run the homeserver
somewhere other than the host that holds the rest of them.
'';
};
package = lib.mkOption { package = lib.mkOption {
type = lib.types.package; type = lib.types.package;
default = pkgs.matrix-tuwunel; default = pkgs.matrix-tuwunel;
@ -246,9 +254,9 @@ in
apiUrl = lib.mkOption { apiUrl = lib.mkOption {
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
default = if deployCfg.matrix.enable then "http://127.0.0.1:${toString cfg.httpPort}" else null; default = if cfg.enable then "http://127.0.0.1:${toString cfg.httpPort}" else null;
defaultText = lib.literalExpression '' defaultText = lib.literalExpression ''
if services.hyperhive.deploy.matrix.enable if services.hyperhive.swarm.matrix.enable
then "http://127.0.0.1:''${toString services.hyperhive.swarm.matrix.httpPort}" then "http://127.0.0.1:''${toString services.hyperhive.swarm.matrix.httpPort}"
else null else null
''; '';
@ -403,8 +411,8 @@ in
gui = { gui = {
enable = lib.mkOption { enable = lib.mkOption {
type = lib.types.bool; type = lib.types.bool;
default = deployCfg.matrix.enable; default = cfg.enable;
defaultText = lib.literalExpression "config.services.hyperhive.deploy.matrix.enable"; defaultText = lib.literalExpression "config.services.hyperhive.swarm.matrix.enable";
description = '' description = ''
Serve a matrix web client at `matrix.''${services.hyperhive.domain}/`. Serve a matrix web client at `matrix.''${services.hyperhive.domain}/`.
Requires `matrix.gatewayHost != null` (default `matrix.<hive>` Requires `matrix.gatewayHost != null` (default `matrix.<hive>`
@ -490,7 +498,7 @@ in
}; };
}; };
config = lib.mkIf deployCfg.matrix.enable { config = lib.mkIf cfg.enable {
# Matrix's own gateway surface: the sub-domain vhost, the name the # Matrix's own gateway surface: the sub-domain vhost, the name the
# hive resolver answers for, and the Accept-header map that vhost's # hive resolver answers for, and the Accept-header map that vhost's
# SPA fallback reads. All three are matrix knowledge and none of # SPA fallback reads. All three are matrix knowledge and none of

View file

@ -48,11 +48,15 @@ in
# Same precedence reasoning as ./local-defaults.nix: fills in for an # Same precedence reasoning as ./local-defaults.nix: fills in for an
# operator who hasn't spoken, yields to one who has. # operator who hasn't spoken, yields to one who has.
# config.services.hyperhive.swarm = {
# Everything derives under `deploy.*` now, because "does THIS host run # The last one still spelled `swarm.*.enable`. Everything else that
# it" is a per-host decision and `swarm.*` has to be identical on every # used to derive here — the queue, the SSO provider, the collector,
# host. Same switch, same rule, one attribute path. # the metrics pair, the log store — now derives below under
config.services.hyperhive.deploy.matrix.enable = lib.mkDefault swarmCfg.enableRequiredServices; # `deploy.*`, because "does THIS host run it" is a per-host decision
# and `swarm.*` has to be identical on every host. Same switch, same
# rule, different attribute path.
matrix.enable = lib.mkDefault swarmCfg.enableRequiredServices;
};
# The collector that feeds the pair above (note: no `swarm.` prefix, # The collector that feeds the pair above (note: no `swarm.` prefix,
# this is ./otel.nix's existing per-hive option). # this is ./otel.nix's existing per-hive option).