Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8813b86eb | ||
|
|
2aa924d85a |
8 changed files with 59 additions and 55 deletions
|
|
@ -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.swarm.matrix.enable = true`).
|
running (`services.hyperhive.deploy.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`
|
||||||
|
|
|
||||||
|
|
@ -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.swarm.matrix.enable = true` pay
|
//! haven't flipped `services.hyperhive.deploy.matrix.enable = true` pay
|
||||||
//! nothing.
|
//! nothing.
|
||||||
//!
|
//!
|
||||||
//! See `docs/matrix.md::Provisioning flow (registration token)` for
|
//! See `docs/matrix.md::Provisioning flow (registration token)` for
|
||||||
|
|
|
||||||
|
|
@ -487,7 +487,7 @@ fn require_matrix_present() -> Result<()> {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
anyhow::bail!(
|
anyhow::bail!(
|
||||||
"no matrix homeserver configured — set services.hyperhive.swarm.matrix.enable = true to run one \
|
"no matrix homeserver configured — set services.hyperhive.deploy.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"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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.swarm.matrix.enable = lib.mkForce false;
|
services.hyperhive.deploy.matrix.enable = lib.mkForce false;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,24 @@ 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;
|
||||||
|
|
|
||||||
|
|
@ -159,28 +159,26 @@ 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) {
|
||||||
lib.optionalAttrs
|
# Matrix homeserver URL for each agent's hive-matrix-daemon — the
|
||||||
(
|
# gateway vhost (`chat.<swarm-domain>`). Forwarded to agents by meta.rs
|
||||||
config.services.hyperhive.swarm.matrix.enable
|
# alongside HIVE_FORGE_URL; shares the same env-forwarding ordering
|
||||||
&& config.services.hyperhive.swarm.matrix.gatewayHost != null
|
# caveat (value baked at config-generation time).
|
||||||
)
|
#
|
||||||
{
|
# Deliberately NOT conditioned on this host running the homeserver. A
|
||||||
# In-cluster matrix homeserver URL for each agent's
|
# swarm has one matrix, and every hive's agents talk to it — the hive
|
||||||
# hive-matrix-daemon — the gateway vhost (`matrix.<domain>`).
|
# that hosts it is not the only hive whose agents need its address.
|
||||||
# Forwarded to agents by meta.rs alongside HIVE_FORGE_URL; shares the
|
# `gatewayHost` is swarm-scoped and names that one homeserver from any
|
||||||
# same env-forwarding ordering caveat (value baked at
|
# member hive, so its being set is the whole question.
|
||||||
# config-generation time).
|
#
|
||||||
#
|
# Null forwards nothing rather than falling back to loopback. That
|
||||||
# A domain-less config forwards nothing rather than falling back to
|
# fallback reads as harmless because hive-c0re shares the host netns —
|
||||||
# loopback. The old fallback read as harmless because hive-c0re shares
|
# but the value is handed to *agents*, which do not, so `127.0.0.1`
|
||||||
# the host netns — but the value it produced was handed to *agents*,
|
# there names the agent itself. An absent forward leaves
|
||||||
# which do not, so `127.0.0.1` there names the agent itself. An absent
|
# `hyperhive.matrix.url` null and the daemon no-ops; that is the honest
|
||||||
# forward leaves `hyperhive.matrix.url` null and the daemon no-ops;
|
# answer when there is no matrix vhost to point at.
|
||||||
# that is the honest answer when the hive has no matrix vhost to point
|
HIVE_MATRIX_URL = "http://${config.services.hyperhive.swarm.matrix.gatewayHost}";
|
||||||
# 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).
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,13 @@ 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.
|
||||||
|
|
@ -177,21 +184,6 @@ 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;
|
||||||
|
|
@ -254,9 +246,9 @@ in
|
||||||
|
|
||||||
apiUrl = lib.mkOption {
|
apiUrl = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = if cfg.enable then "http://127.0.0.1:${toString cfg.httpPort}" else null;
|
default = if deployCfg.matrix.enable then "http://127.0.0.1:${toString cfg.httpPort}" else null;
|
||||||
defaultText = lib.literalExpression ''
|
defaultText = lib.literalExpression ''
|
||||||
if services.hyperhive.swarm.matrix.enable
|
if services.hyperhive.deploy.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
|
||||||
'';
|
'';
|
||||||
|
|
@ -411,8 +403,8 @@ in
|
||||||
gui = {
|
gui = {
|
||||||
enable = lib.mkOption {
|
enable = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = cfg.enable;
|
default = deployCfg.matrix.enable;
|
||||||
defaultText = lib.literalExpression "config.services.hyperhive.swarm.matrix.enable";
|
defaultText = lib.literalExpression "config.services.hyperhive.deploy.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>`
|
||||||
|
|
@ -498,7 +490,7 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf deployCfg.matrix.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
|
||||||
|
|
|
||||||
|
|
@ -48,15 +48,11 @@ 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 = {
|
#
|
||||||
# The last one still spelled `swarm.*.enable`. Everything else that
|
# Everything derives under `deploy.*` now, because "does THIS host run
|
||||||
# used to derive here — the queue, the SSO provider, the collector,
|
# it" is a per-host decision and `swarm.*` has to be identical on every
|
||||||
# the metrics pair, the log store — now derives below under
|
# host. Same switch, same rule, one attribute path.
|
||||||
# `deploy.*`, because "does THIS host run it" is a per-host decision
|
config.services.hyperhive.deploy.matrix.enable = lib.mkDefault swarmCfg.enableRequiredServices;
|
||||||
# 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).
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue