Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d23896dbb | ||
|
|
f7beea3a6f | ||
|
|
38c222fadd |
6 changed files with 35 additions and 24 deletions
|
|
@ -153,7 +153,8 @@ let
|
||||||
|
|
||||||
- [host options](host.md) — options exposed by
|
- [host options](host.md) — options exposed by
|
||||||
`hyperhive.nixosModules.default` to operator host configurations
|
`hyperhive.nixosModules.default` to operator host configurations
|
||||||
(`services.hyperhive.{enable,domain,c0re,forge,matrix,gateway}.*`).
|
(`services.hyperhive.{enable,domain,c0re,gateway}.*`,
|
||||||
|
`services.hyperhive.swarm.{forge,matrix}.*`).
|
||||||
- [per-agent options](agent.md) — options declared in
|
- [per-agent options](agent.md) — options declared in
|
||||||
`nix/agent-modules/`, visible from every `agent.nix`
|
`nix/agent-modules/`, visible from every `agent.nix`
|
||||||
(`hyperhive.model`, `hyperhive.allowedRecipients`,
|
(`hyperhive.model`, `hyperhive.allowedRecipients`,
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ let
|
||||||
safeDirGitconfig = pkgs.writeText "hyperhive-safe-gitconfig" ''
|
safeDirGitconfig = pkgs.writeText "hyperhive-safe-gitconfig" ''
|
||||||
[safe]
|
[safe]
|
||||||
directory = *
|
directory = *
|
||||||
[credential "http://${config.services.hyperhive.forge.domain}"]
|
[credential "http://${config.services.hyperhive.swarm.forge.domain}"]
|
||||||
helper = hive-forge
|
helper = hive-forge
|
||||||
username = core
|
username = core
|
||||||
[http]
|
[http]
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ in
|
||||||
# agents via meta.rs for their forge-notify client. The forge is
|
# agents via meta.rs for their forge-notify client. The forge is
|
||||||
# mandatory, so this is unconditional (the whole env block is already
|
# mandatory, so this is unconditional (the whole env block is already
|
||||||
# gated on hyperhive being enabled). See `docs/gateway.md::HIVE_FORGE_URL`.
|
# gated on hyperhive being enabled). See `docs/gateway.md::HIVE_FORGE_URL`.
|
||||||
HIVE_FORGE_URL = "http://${config.services.hyperhive.forge.domain}";
|
HIVE_FORGE_URL = "http://${config.services.hyperhive.swarm.forge.domain}";
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
lib.optionalAttrs
|
lib.optionalAttrs
|
||||||
|
|
@ -147,17 +147,17 @@ in
|
||||||
# dashboard doesn't need to learn the gateway is unconditional.
|
# dashboard doesn't need to learn the gateway is unconditional.
|
||||||
HIVE_GATEWAY_ENABLED = "1";
|
HIVE_GATEWAY_ENABLED = "1";
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs (config.services.hyperhive.forge.publicUrl != null) {
|
// lib.optionalAttrs (config.services.hyperhive.swarm.forge.publicUrl != null) {
|
||||||
# Public URL of the forge, for the dashboard to build browser-facing
|
# Public URL of the forge, for the dashboard to build browser-facing
|
||||||
# forge links from instead of guessing `<hostname>:3000` (which
|
# forge links from instead of guessing `<hostname>:3000` (which
|
||||||
# breaks the moment the operator's browser hostname isn't the forge
|
# breaks the moment the operator's browser hostname isn't the forge
|
||||||
# host, e.g. through the gateway or a reverse proxy). Sourced from
|
# host, e.g. through the gateway or a reverse proxy). Sourced from
|
||||||
# `services.hyperhive.forge.publicUrl`, which itself defaults to the
|
# `services.hyperhive.swarm.forge.publicUrl`, which itself defaults to the
|
||||||
# gateway vhost URL when `behindGateway = true` and `null` otherwise
|
# gateway vhost URL when `behindGateway = true` and `null` otherwise
|
||||||
# — see that option's doc for the "hide, don't guess" rationale.
|
# — see that option's doc for the "hide, don't guess" rationale.
|
||||||
# Absent here whenever `publicUrl` is `null`; the dashboard hides
|
# Absent here whenever `publicUrl` is `null`; the dashboard hides
|
||||||
# forge links rather than emitting one it can't justify.
|
# forge links rather than emitting one it can't justify.
|
||||||
HIVE_FORGE_PUBLIC_URL = config.services.hyperhive.forge.publicUrl;
|
HIVE_FORGE_PUBLIC_URL = config.services.hyperhive.swarm.forge.publicUrl;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
lib.optionalAttrs
|
lib.optionalAttrs
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
cfg = config.services.hyperhive.forge.ci;
|
cfg = config.services.hyperhive.swarm.forge.ci;
|
||||||
forgeCfg = config.services.hyperhive.forge;
|
forgeCfg = config.services.hyperhive.swarm.forge;
|
||||||
gatewayCfg = config.services.hyperhive.gateway;
|
gatewayCfg = config.services.hyperhive.gateway;
|
||||||
networkCfg = config.services.hyperhive.network;
|
networkCfg = config.services.hyperhive.network;
|
||||||
tlsCfg = config.services.hyperhive.tls;
|
tlsCfg = config.services.hyperhive.tls;
|
||||||
|
|
@ -52,14 +52,14 @@ in
|
||||||
# nspawn containers can't create the user-namespaces that nix sandboxing
|
# nspawn containers can't create the user-namespaces that nix sandboxing
|
||||||
# requires. See docs/gotchas.md.
|
# requires. See docs/gotchas.md.
|
||||||
|
|
||||||
options.services.hyperhive.forge.ci = {
|
options.services.hyperhive.swarm.forge.ci = {
|
||||||
enable = lib.mkOption {
|
enable = lib.mkOption {
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
default = false;
|
default = false;
|
||||||
example = true;
|
example = true;
|
||||||
description = ''
|
description = ''
|
||||||
Run a Forgejo Actions runner in a `hive-ci` nixos-container.
|
Run a Forgejo Actions runner in a `hive-ci` nixos-container.
|
||||||
Grouped under `services.hyperhive.forge` because the runner is
|
Grouped under `services.hyperhive.swarm.forge` because the runner is
|
||||||
tightly coupled to the forge instance it registers against.
|
tightly coupled to the forge instance it registers against.
|
||||||
Disabled by default; the internal forge it registers against is
|
Disabled by default; the internal forge it registers against is
|
||||||
always present (mandatory), so enabling this is all that's needed.
|
always present (mandatory), so enabling this is all that's needed.
|
||||||
|
|
@ -142,8 +142,8 @@ in
|
||||||
{
|
{
|
||||||
assertion = forgeCfg.behindGateway;
|
assertion = forgeCfg.behindGateway;
|
||||||
message = ''
|
message = ''
|
||||||
services.hyperhive.forge.ci.enable requires
|
services.hyperhive.swarm.forge.ci.enable requires
|
||||||
services.hyperhive.forge.behindGateway = true.
|
services.hyperhive.swarm.forge.behindGateway = true.
|
||||||
The CI container runs with a private network namespace and
|
The CI container runs with a private network namespace and
|
||||||
reaches the forge through the gateway vhost on the bridge IP.
|
reaches the forge through the gateway vhost on the bridge IP.
|
||||||
Set behindGateway = true (it defaults to true alongside
|
Set behindGateway = true (it defaults to true alongside
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
cfg = config.services.hyperhive.forge;
|
cfg = config.services.hyperhive.swarm.forge;
|
||||||
gatewayCfg = config.services.hyperhive.gateway;
|
gatewayCfg = config.services.hyperhive.gateway;
|
||||||
hyperhiveDomain = config.services.hyperhive.domain;
|
hyperhiveDomain = config.services.hyperhive.domain;
|
||||||
tlsCfg = config.services.hyperhive.tls;
|
tlsCfg = config.services.hyperhive.tls;
|
||||||
|
|
@ -53,7 +53,7 @@ let
|
||||||
# blip otherwise reds every `actions/checkout@vN` fetch from
|
# blip otherwise reds every `actions/checkout@vN` fetch from
|
||||||
# data.forgejo.org). Auto-append a pull-mirror of it and point
|
# data.forgejo.org). Auto-append a pull-mirror of it and point
|
||||||
# forgejo's DEFAULT_ACTIONS_URL at this instance so `uses:` resolves local.
|
# forgejo's DEFAULT_ACTIONS_URL at this instance so `uses:` resolves local.
|
||||||
ciEnabled = config.services.hyperhive.forge.ci.enable;
|
ciEnabled = config.services.hyperhive.swarm.forge.ci.enable;
|
||||||
actionCheckoutMirror = {
|
actionCheckoutMirror = {
|
||||||
upstream = "https://github.com/actions/checkout";
|
upstream = "https://github.com/actions/checkout";
|
||||||
dest = "actions/checkout";
|
dest = "actions/checkout";
|
||||||
|
|
@ -82,11 +82,21 @@ in
|
||||||
# (base URL), the same shape as the GitHub PAT / matrix extra-account
|
# (base URL), the same shape as the GitHub PAT / matrix extra-account
|
||||||
# flows. See `hive-c0re/src/dashboard/extra_forges.rs`.
|
# flows. See `hive-c0re/src/dashboard/extra_forges.rs`.
|
||||||
|
|
||||||
|
# Forge moved under `swarm` when the swarm-global services were
|
||||||
|
# consolidated. One rename for the namespace: the subtree comes with it,
|
||||||
|
# so existing hives keep evaluating and get one warning naming both paths.
|
||||||
|
imports = [
|
||||||
|
(lib.mkRenamedOptionModule
|
||||||
|
[ "services" "hyperhive" "forge" ]
|
||||||
|
[ "services" "hyperhive" "swarm" "forge" ]
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
# The internal forge is mandatory — it's the canonical store for the
|
# The internal forge is mandatory — it's the canonical store for the
|
||||||
# meta flake + every agent's config repo (and the `internal/*` repos),
|
# meta flake + every agent's config repo (and the `internal/*` repos),
|
||||||
# so there is no enable/disable toggle. It deploys whenever hyperhive
|
# so there is no enable/disable toggle. It deploys whenever hyperhive
|
||||||
# itself is enabled (`services.hyperhive.enable`).
|
# itself is enabled (`services.hyperhive.enable`).
|
||||||
options.services.hyperhive.forge = {
|
options.services.hyperhive.swarm.forge = {
|
||||||
httpPort = lib.mkOption {
|
httpPort = lib.mkOption {
|
||||||
type = lib.types.port;
|
type = lib.types.port;
|
||||||
default = 3000;
|
default = 3000;
|
||||||
|
|
@ -244,7 +254,7 @@ in
|
||||||
|
|
||||||
**Breaking change**: this used to default to `true`. If you
|
**Breaking change**: this used to default to `true`. If you
|
||||||
relied on the old default for external reach, add
|
relied on the old default for external reach, add
|
||||||
`services.hyperhive.forge.openFirewall = true;` to your host
|
`services.hyperhive.swarm.forge.openFirewall = true;` to your host
|
||||||
config before rebuilding.
|
config before rebuilding.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
@ -283,7 +293,7 @@ in
|
||||||
so a host-resolver blip leaves a *stale* mirror, never a hard
|
so a host-resolver blip leaves a *stale* mirror, never a hard
|
||||||
failure on whatever reads it.
|
failure on whatever reads it.
|
||||||
|
|
||||||
When `services.hyperhive.forge.ci.enable` is set, an
|
When `services.hyperhive.swarm.forge.ci.enable` is set, an
|
||||||
`actions/checkout` mirror is auto-appended to this list and
|
`actions/checkout` mirror is auto-appended to this list and
|
||||||
forgejo's `DEFAULT_ACTIONS_URL` is pointed at this instance, so CI
|
forgejo's `DEFAULT_ACTIONS_URL` is pointed at this instance, so CI
|
||||||
`uses: actions/checkout@vN` steps resolve entirely on loopback with
|
`uses: actions/checkout@vN` steps resolve entirely on loopback with
|
||||||
|
|
@ -298,7 +308,7 @@ in
|
||||||
{
|
{
|
||||||
assertion = cfg.rootUrl == null || lib.hasSuffix "/" cfg.rootUrl;
|
assertion = cfg.rootUrl == null || lib.hasSuffix "/" cfg.rootUrl;
|
||||||
message = ''
|
message = ''
|
||||||
services.hyperhive.forge.rootUrl must end with "/". forgejo's
|
services.hyperhive.swarm.forge.rootUrl must end with "/". forgejo's
|
||||||
ROOT_URL contract requires a trailing slash for correct
|
ROOT_URL contract requires a trailing slash for correct
|
||||||
relative-link generation; without it forgejo emits URLs like
|
relative-link generation; without it forgejo emits URLs like
|
||||||
`https://forge.example.com.user.id` instead of
|
`https://forge.example.com.user.id` instead of
|
||||||
|
|
@ -313,7 +323,7 @@ in
|
||||||
# loud.
|
# loud.
|
||||||
assertion = cfg.domain != "";
|
assertion = cfg.domain != "";
|
||||||
message = ''
|
message = ''
|
||||||
services.hyperhive.forge.domain = "" is rejected. The
|
services.hyperhive.swarm.forge.domain = "" is rejected. The
|
||||||
rendered URLs would be invalid (nginx wildcard catch-all
|
rendered URLs would be invalid (nginx wildcard catch-all
|
||||||
for an empty server_name, /etc/hosts rejects empty entries).
|
for an empty server_name, /etc/hosts rejects empty entries).
|
||||||
Either leave at default (auto-derives to
|
Either leave at default (auto-derives to
|
||||||
|
|
@ -326,7 +336,7 @@ in
|
||||||
# splits on the single slash to create the org + repo.
|
# splits on the single slash to create the org + repo.
|
||||||
assertion = lib.all (m: lib.length (lib.splitString "/" m.dest) == 2) effectiveMirrors;
|
assertion = lib.all (m: lib.length (lib.splitString "/" m.dest) == 2) effectiveMirrors;
|
||||||
message = ''
|
message = ''
|
||||||
Every services.hyperhive.forge.mirrors[].dest must be exactly
|
Every services.hyperhive.swarm.forge.mirrors[].dest must be exactly
|
||||||
"<owner>/<repo>" (one slash). Got: ${lib.concatMapStringsSep ", " (m: m.dest) effectiveMirrors}
|
"<owner>/<repo>" (one slash). Got: ${lib.concatMapStringsSep ", " (m: m.dest) effectiveMirrors}
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
@ -344,7 +354,7 @@ in
|
||||||
])
|
])
|
||||||
) effectiveMirrors;
|
) effectiveMirrors;
|
||||||
message = ''
|
message = ''
|
||||||
services.hyperhive.forge.mirrors[].dest must not place a mirror
|
services.hyperhive.swarm.forge.mirrors[].dest must not place a mirror
|
||||||
in a hive-c0re-managed org (config / shared / agents / core) —
|
in a hive-c0re-managed org (config / shared / agents / core) —
|
||||||
those are provisioned by hive-c0re and a mirror there would
|
those are provisioned by hive-c0re and a mirror there would
|
||||||
collide. Use a dedicated org (e.g. "actions/checkout").
|
collide. Use a dedicated org (e.g. "actions/checkout").
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ let
|
||||||
cfg = config.services.hyperhive.gateway;
|
cfg = config.services.hyperhive.gateway;
|
||||||
hyperhiveDomain = config.services.hyperhive.domain;
|
hyperhiveDomain = config.services.hyperhive.domain;
|
||||||
matrixCfg = config.services.hyperhive.matrix;
|
matrixCfg = config.services.hyperhive.matrix;
|
||||||
forgeCfg = config.services.hyperhive.forge;
|
forgeCfg = config.services.hyperhive.swarm.forge;
|
||||||
networkCfg = config.services.hyperhive.network;
|
networkCfg = config.services.hyperhive.network;
|
||||||
|
|
||||||
# Dashboard SPA dist, static-served by nginx. Read in OUTER scope so
|
# Dashboard SPA dist, static-served by nginx. Read in OUTER scope so
|
||||||
|
|
@ -411,8 +411,8 @@ in
|
||||||
networking.hosts = lib.mkIf cfg.localHostsEntry {
|
networking.hosts = lib.mkIf cfg.localHostsEntry {
|
||||||
"127.0.0.1" = lib.unique (
|
"127.0.0.1" = lib.unique (
|
||||||
[ hyperhiveDomain ]
|
[ hyperhiveDomain ]
|
||||||
++ lib.optional (config.services.hyperhive.forge.behindGateway or false
|
++ lib.optional (config.services.hyperhive.swarm.forge.behindGateway or false
|
||||||
) config.services.hyperhive.forge.domain
|
) config.services.hyperhive.swarm.forge.domain
|
||||||
++ lib.optional (matrixCfg.enable && matrixCfg.gatewayHost != null) matrixCfg.gatewayHost
|
++ lib.optional (matrixCfg.enable && matrixCfg.gatewayHost != null) matrixCfg.gatewayHost
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue