Commit graph hyperhive/nix/host-modules
Author SHA1 Message Date
atlas
65a0686297 fix(#2673): set nix fallback in agent + CI containers
Container nix invocations hard-failed whenever the remote builder
muede-pc2 was unreachable, while the identical build on the host
succeeded. Both go through the same host nix-daemon, so the difference
looked impossible.

The cause is that `fallback` is a client-side option: the nix client
transmits it to the daemon per connection (`tryFallback` in setOptions),
so the caller decides whether a failed remote dispatch may degrade to a
local build — even when the build itself runs on the host daemon under
NIX_REMOTE=daemon. Only genuinely daemon-side settings such as
`builders` are inherited from the host. The containers never set
`fallback`, so they took nix's default of false.

Set it in the agent-container base module and in the CI container, and
correct the hive-ci comment that claimed fallback was inherited from
the host daemon along with buildMachines and max-jobs.

Verified in an agent container: `nix fmt` fails outright on the remote
store's connection reset, while the same command with fallback enabled
reports the same connection error and then builds locally and succeeds.
2026-07-25 19:36:31 +02:00
atlas
30a2a2e9de feat(#2641): sudoless hivectl via a hive-admin group on the host socket
The host admin socket `/run/hyperhive/host.sock` was `0660 root:root` (no
SocketGroup), so hivectl needed sudo. Group-own it by a new `hive-admin`
group and add a `services.hyperhive.c0re.adminUsers` allowlist: listed users
join `hive-admin` and drive hivectl without root.

- `SocketGroup = "hive-admin"`, `SocketMode = "0660"` on the hive-c0re.socket
  unit.
- `/run/hyperhive` -> `0751` (traverse-only, no listing) so the group can reach
  the socket path; the socket's own `0660 hive-admin` mode gates the
  connection, and the per-agent subdirs keep their own restrictive perms.
- Empty `adminUsers` (the default) leaves `hive-admin` memberless -> root-only,
  as before.

The admin socket is full hive control (spawn/kill/destroy/deploy), so
`adminUsers` is an explicit, opt-in trust grant. Documented in
docs/boundary.md (host admin socket access) + docs/tools/hivectl.md.
2026-07-22 22:50:27 +02:00
atlas
6559f3e7b5 fix(#2578): route hive-ci's nix through the host daemon (keep distributed builds + gain fallback)
CI's nix flake check ran in hive-ci's OWN in-container nix-daemon, which
offloads to the pc2 remote builder and HARD-FAILS when pc2 is
unreachable (Connection-reset) — reddening every PR's queue hive-wide.
The host daemon builds fine in the same situation (buildMachines +
max-jobs>=1 + fallback → local build when pc2 is down), and the agent
containers already route through it.

Give hive-ci the same wiring: bind-mount the host nix-daemon socket dir
into the container, set NIX_REMOTE=daemon, and disable the container's
own nix-daemon service + socket. Now CI builds through the host daemon —
pc2 offload when it's up, graceful local fallback when it's down. Drops
the now-moot in-container wait-nix-daemon precond. Needs an operator
rebuild to apply.
2026-07-20 18:55:50 +02:00
damocles
a35b67b7c5 fix(#2573): also add /etc/tmpfiles.d to hive-priv ReadWritePaths (same EROFS class) 2026-07-18 16:39:20 +02:00
damocles
6407510744 fix(#2573): add /run/hive-ci to hive-priv ReadWritePaths so the ci-runner token write doesn't EROFS 2026-07-18 16:31:18 +02:00
damocles
618d774467 fix(#2560): make hive-core git non-interactive + bound stalled fetches 2026-07-17 15:01:47 +02:00
atlas
b806aa253e feat(#2502): git credential helper for hive-core forge fetches
hive-core now fetches each agent's config as a forge-hosted flake input
(git+http://<forge>/agent-configs/<n>.git). Add a git credential helper
(git-credential-hive-forge) that reads the live forge-core admin token on
every invocation and authenticates as the forge core user, wired via the
[credential] stanza in hive-core's $HOME/.gitconfig + on the service PATH.
Reading the token file live means zero stale copies and no resync on
rotation; no token ever lands in a flake URL or lock. Mirrors the existing
github.nix credential-helper pattern.
2026-07-17 01:48:27 +02:00
damocles
12d607fe5d fix hive-ci RestartSec eval conflict with lib.mkForce (#2535) 2026-07-16 17:00:46 +02:00
atlas
f4bcc59152 feat(#2415): move hive-ci runner registration off the boot-critical path (nix)
Completes #2415. Registration no longer gates container@hive-ci start:
- Retire the host-side hive-ci-prefetch.service (+ its 100-line script and
  the now-dead coreTokenPath/containerRoot let-bindings) — the forge round-trip
  it did on the boot path now lives in hive-c0re (forge/ci_runner.rs), run out
  of band during the startup sweep.
- Drop the container@hive-ci TimeoutStartSec = mkForce 180s band-aid that
  papered over that boot-path wait tripping the nspawn start timeout (the ~60s
  restart loop of #2410).
- gitea-runner-hive gains an ExecStartPre precond (ahead of the nix-daemon
  wait) that fails fast unless it is already registered (.runner present) or a
  real, non-placeholder token is in place — so missing creds just hold the
  runner down instead of blocking the container. Restart=on-failure (no start
  limit) self-heals it once hive-c0re writes the token; c0re's explicit restart
  is the primary path.
- Set HYPERHIVE_FORGE_CI_ENABLED=1 on hive-c0re.service so the sweep registers.
The tmpfiles TOKEN=placeholder seed + read-only bind-mount are unchanged; the
core admin token still never enters the container.
2026-07-16 12:48:23 +02:00
atlas
419c9659a3 feat(#2007): export per-agent container cpu/mem/disk via otel
hive-c0re already samples each agent container's cgroup load for the
dashboard (stats/container_stats.rs); this rides those gauges out to the
configured OTLP endpoint, reusing the existing services.hyperhive.otel
config (endpoint + auth header) — no new toggle.

- New stats/otel_metrics.rs: exports via the OpenTelemetry Rust SDK (same
  crates as hive-metric) with the semconv container.* metric names +
  container.name attribute so off-the-shelf OTel/Grafana dashboards work,
  plus the hive agent label. container.cpu.time (counter, s, from cumulative
  cpu.stat usage_usec), container.memory.usage, container.memory.usage.limit;
  memory peak / on-disk storage / instantaneous cpu percent stay hyperhive.*
  custom (no semconv equivalent). Observable instruments read a shared
  snapshot an async task refreshes (gather() is async; SDK callbacks sync).
- container_stats: expose cpu_time_usec (cumulative) on ContainerResource.
- The OTLP auth header is loaded onto hive-c0re's own unit via systemd
  LoadCredential and read from $CREDENTIALS_DIRECTORY/otel-headers.
- docs/observability.md documents the host-emitted semconv metrics.

Host-side export, so it covers containers even when their agent is idle.
2026-07-15 22:51:31 +02:00
damocles
cc67a05974 refactor(#2352): extract standalone hivectl crate, hive-c0re daemon-only 2026-07-15 22:36:13 +02:00
atlas
6c4ef5f798 refactor(#2427): extract shared hive-CA trust bind-mount helper
hive-ci and hive-forge both bind the runtime-generated hive CA cert
read-only and order their container@ unit after hive-tls-ca.service so
the bind source exists before nspawn sets the mount up — the same
bind-mount + ordering + rationale duplicated verbatim in two modules.

Extract that language-agnostic half into a pure helper,
nix/host-modules/lib/hive-ca-trust.nix, taking a container name and
returning { useSelfSigned, caContainerPath, bindMount, containerOrdering }.
The per-runtime consumption stays at each call site (hive-ci's additive
NODE_EXTRA_CA_CERTS, hive-forge's Go SSL_CERT_FILE concat). hive-ci folds
containerOrdering into its existing mkMerge alongside the TimeoutStartSec
bump.

The helper is a pure function, not a module: host-modules/default.nix is
an explicit aggregator (not a glob) and the docs eval imports that same
aggregator, so the lib/ file is never picked up as a module. A third
outbound-TLS-trusting container no longer means a third copy-paste.
2026-07-15 20:12:52 +02:00
damocles
3f1643c594 refactor(#2464): rename hive-ag3nt crate to hive-agent, collapse lib into main 2026-07-15 16:09:39 +02:00
damocles
5853ce2c8d fix(#2417): hardcode external,gateway in forgejo webhook allowlist, drop option 2026-07-14 20:26:02 +02:00
damocles
60e4ea8bb8 fix(#2417): keep 'external' in webhook allow-list so public webhooks still deliver 2026-07-14 20:19:49 +02:00
damocles
00c9a15ae6 fix(#2417): make webhook allow-list additive via forge.webhookAllowedHosts option 2026-07-14 20:16:12 +02:00
damocles
cada704856 fix(#2417): allow gateway host in forgejo webhook ssrf list so config-pr webhook delivers 2026-07-14 20:07:27 +02:00
damocles
ffde085c35 fix(#2433): mkforce container@hive-ci timeoutstartsec to resolve nixpkgs conflict 2026-07-14 19:59:32 +02:00
damocles
15e56986ad fix(#2417): trust hive ca in forge container for self-signed webhook delivery 2026-07-14 18:39:11 +02:00
iris
dbf880ac66 extra-forges: fully dashboard-provisioned, no host config
Per mara's feedback on PR #2407 ("better: you can also provide url in
dashboard, same as with matrix, no host config"), drops
services.hyperhive.extraForges and the admin-API mint/revoke flow
entirely. The operator now creates a token on the external forge
themselves and pastes a label + base URL + access token into the
dashboard's FORGES tab, the same shape as the GitHub PAT flow plus the
base-URL field from the matrix extra-account flow. hive-c0re only ever
writes/deletes two local files per account (forge-<label>-token,
forge-<label>.json sidecar for the URL) via hive-priv — no remote
account creation, no admin token, no revoke-on-the-remote-side, no nix
config to enumerate.

- nix/host-modules/hive-forge/default.nix: removed the extraForges
  option, its label-format assertion, and the HYPERHIVE_EXTRA_FORGES
  env forwarding.
- hive-c0re/src/forge/extra.rs: deleted (REST admin-API provisioning,
  no longer needed).
- hive-c0re/src/dashboard/extra_forges.rs: GET /api/extra-forges?
  agent= lists an agent's stored forges by scanning its state dir
  (mirrors matrix_accounts.rs's filename-scan listing), POST
  /api/extra-forge-account (agent/label/base_url/token/
  action=add|remove) stores or removes an account.
- hive-sh4re/priv_proto.rs + hive-priv/main.rs: new
  WriteAgentExtraForgeAccount/DeleteAgentExtraForgeAccount priv
  requests (adds base_url, writes/deletes a JSON sidecar alongside the
  token).
- hive-c0re/src/priv_client.rs: matching wrapper functions.
- frontend/packages/dashboard/src/credentials.{html,js}: FORGES tab is
  a per-agent list + add-account paste form (label/base_url/token), no
  grant/revoke-from-catalog UI.
- docs/web-ui/dashboard.md: FORGES tab section rewritten.

Supersedes the design in PR #2407 (already approved+green on the old
admin-API model) — opening as a fresh PR against the same issues
rather than force-pushing over the approved one.
2026-07-14 18:38:55 +02:00
atlas
2bf6290aa0 fix(#2410): bump container@hive-ci TimeoutStartSec to survive slow runner registration
gitea-runner registration (hive-ci-prefetch, host-side) sits on the
boot-critical path -- nspawn readiness is gated on the runner
registering, itself a forge + core-token round trip that can wait up
to 60s for the core token. The default ~60s TimeoutStartSec can trip
mid-register (especially right after a .runner purge, since every
boot re-registers from scratch), killing the half-started container
and triggering a restart loop until the token/forge settle. Bump to
180s so one register attempt has room to finish.
2026-07-14 17:38:40 +02:00
müde
0d416df1e8 fix: shared-netns infra containers must not run their own firewall 2026-07-14 00:08:33 +02:00
müde
79fec131d6 docs: sweep archaeology comments to present state 2026-07-13 22:16:02 +02:00
müde
e0cfed7fe8 refactor: jq for tea-login, build-time avatar png, shared leaf-sign script 2026-07-13 22:14:25 +02:00
müde
935e967718 feat: hive DNS always follows the host resolver 2026-07-13 22:09:53 +02:00
müde
4a48ce5024 refactor: nix/host-modules + nix/agent-modules layout, update doc paths 2026-07-13 22:05:49 +02:00