188 Commits

Author SHA1 Message Date
self b522f743aa fix: keep DRM enabled for installer consoles
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m18s
Keep DRM/KMS support in tribes-linux so the kexec installer can show a local console on Proxmox/QEMU and generic real hardware.

This restores VGA console output while retaining the other kernel slimming options.
2026-06-11 22:08:37 +02:00
self e62a3d30b1 fix: preserve HAProxy bind capability for QUIC
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m1s
Build HAProxy with Linux capability support and preserve cap_net_bind_service in the generated service configuration so QUIC can bind privileged port 443 after HAProxy drops to the haproxy user.
2026-06-11 01:16:41 +02:00
self 2ec1a43460 fix: avoid eager Hyper-V kexec modules
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m40s
Do not eagerly load Hyper-V, VMware, or Xen frontend modules in the kexec installer initrd. The broadened compatibility list caused Hetzner CPX31 kexec boots to fall back to the Ubuntu disk before installer SSH became reachable; the KVM/QEMU and common emulated NIC subset boots successfully.\n\nAlso require cpio in the local kexec image build script so missing cpio fails before writing an incomplete image.
2026-06-10 23:42:20 +02:00
self b85de2ba63 chore: Bump base channel to feature/substitute-read-timeout 2026-06-10 23:42:12 +02:00
self 9269bb0b13 ci: warm substitutes from node OS closures, not curated manifests
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m33s
The deployed node materializes a real operating-system via `guix system
init`/reconfigure, so the authoritative substitute set is the closure of
that operating-system -- which CI already builds in substitute-system-jobs.
The hand-curated manifests/substitutes/{base,installer,tribes-node}.scm only
approximated a node's closure and drifted from it.

Add (tribes ci artifacts-substitutes), emitting the node OS closures and
bootloader files for the guix-tribes-substitutes jobset, and move those jobs
out of artifacts-master (now just the docker image and sender-runtime pack).

Building a node's full closure pulls every transitive upstream dependency
into our store, so the mirror keeps serving everything an install needs
without depending on bordeaux/ci.  To preserve mirroring of the operator
toolkit -- which lived only in the old tribes-node manifest, not in any
system -- carry ripgrep/fd/tmux/neovim/btop in the node system profile, so
they are both installed on nodes and covered by the closure.

Drop the redundant manifests/substitutes/*.scm.
2026-06-10 16:56:49 +02:00
self 324091a366 ci: re-trigger after daemon fix
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m31s
2026-06-10 15:47:06 +02:00
self 1fe532e294 fix: broaden kexec installer VM support
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m34s
Include common Xen, Hyper-V, VMware, virtio, and emulated QEMU storage/network modules in the kexec installer initrd.\n\nAlso log to both VGA and serial consoles and raise kernel log verbosity so manual-host kexec failures are easier to diagnose.
2026-06-10 13:53:43 +02:00
self 46991aa6c8 fix(ci): preserve store mtimes in kexec image
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m33s
2026-06-10 04:22:50 +02:00
self 6666432cbc fix(ci): build canonical time-machine profile
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m33s
Reconstruct public channel URLs for the substitute-channel-profile job before calling latest-channel-derivation. Cuirass passes custom jobs store-checkout URLs, which do not match the profile Legion installers compute with guix time-machine -C channels.scm.
2026-06-10 01:25:50 +02:00
self 149bf4e921 ci: materialize base-edge substitute target
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m33s
Build the base-edge substitute system through the same host-configuration plus system-facts materialization path used by Legion installs. This keeps the existing Cuirass substitute-system-base-edge job but makes it warm the installer module graph more closely.
2026-06-09 22:55:39 +02:00
self 41866bf0ff fix(ci): wrap sources manifest in define-module
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m49s
The channel-instance build compiles every .scm file in the channel as
a Guile module; a bare-script sources.scm with top-level use-modules +
(manifest ...) failed compilation with 'no code for module (manifests
sources)'.  Mirror the dual-use shape of manifests/substitutes/*.scm:
declare define-module, bind the manifest to a name, and end with a
bare reference so primitive-load still returns the manifest value.
2026-06-09 21:22:22 +02:00
self 35e8044ae6 fix(ci): import (gnu packages) in sources manifest
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
fold-packages lives in (gnu packages), not (guix packages); the
sources canary manifest was missing the import and aborted with an
unbound-variable on evaluation.
2026-06-09 21:14:27 +02:00
self 0957da2e5a ci: split CI into per-concern specifications
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m33s
Restructure the Cuirass jobs so each concern lives in its own spec,
mirroring how ci.guix.gnu.org partitions things:

  * tribes/ci/channel.scm: new entry point emitting only the
    channel-instance derivation -- a cheap canary that fails fast
    when channel modules don't compile or the checkout is unreachable.

  * manifests/sources.scm: new manifest of upstream origins for every
    package defined by the tribes (and nbde) channel modules.  Drives
    a network canary that catches stale upstream URLs / commit refs
    (e.g. force-pushed pins) without depending on actual package builds.

  * tribes/ci/artifacts-master.scm: drop channel-profile and
    substitute-manifest jobs -- they move out to their own specs
    consumed via Cuirass's built-in 'manifests build type.

  * tribes/ci/artifacts.scm: remove the now-dead substitute-manifest
    plumbing along with its imports and exports.

The accompanying Cuirass spec list (deployed separately) registers
guix-tribes-channel, guix-tribes-source, guix-tribes-substitutes,
guix-tribes, and guix-tribes-kexec-installer.
2026-06-09 20:23:04 +02:00
self 8978b62a93 fix(ci): build substitute-channel-profile from pre-fetched checkouts
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m32s
Cuirass rewrites each channel URL to the /gnu/store/<hash>-<name>-<commit>
checkout it has already fetched, but those derivation outputs are flat
working trees with no .git/ directory.  latest-channel-derivation calls
latest-channel-instances, which runs libgit2's update-cached-checkout on
the URL and crashes with GIT_ENOTFOUND, aborting the entire evaluation.

Skip the (re-)fetch by constructing channel-instance records directly from
the already-resolved (url, commit) pair via the public
checkout->channel-instance helper, then feed those to
channel-instances->derivation -- the same path "guix pull" uses internally.
2026-06-09 19:24:19 +02:00
self 77d9717707 chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m32s
2026-06-09 18:33:09 +02:00
self 05f7ec5b60 ci: build substitute channel profile artifact
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 34m7s
Add a Cuirass artifact job for the Guix channel profile produced from the evaluated channel arguments. This restores the pre-Cuirass warmup coverage for the time-machine profile used by installers.
2026-06-09 17:11:20 +02:00
self b45ae0c87b fix: enable postgres slow query logging
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m32s
Log PostgreSQL statements slower than one second on Tribes nodes. The existing syslog-ng configuration already routes postgres syslog entries to /var/log/postgresql.log and the combined JSONL log, which supertest remote log capture collects from /var/log.
2026-06-09 13:49:01 +02:00
self db6ed5b6dd fix: raise Parrhesia sync read pool
Live mixed-provider supertest runs showed control-lane SYNC-PAGE handlers timing out while waiting for Parrhesia DB read connections under catch-up load. Set larger Parrhesia main/read pool sizes in the Tribes service environment so sync-page queries can proceed concurrently during node joins.
2026-06-09 13:48:55 +02:00
self 54f23bc863 chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m34s
2026-06-09 03:16:53 +02:00
self cd0297edaf chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m48s
2026-06-08 22:48:25 +02:00
self 94ca870450 chore: Bump tribes + aether
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m50s
2026-06-08 21:56:38 +02:00
self f81eb2e12e ci: split artifact jobsets into per-spec modules
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 31m49s
The kexec-installer jobset shared (tribes ci artifacts) cuirass-jobs
with master, so its evaluations re-emitted the docker/sender-runtime
and substitute jobs from whatever the master branch's checkout
happened to look like, while the kexec image itself stopped being
emitted once that helper was simplified.

Split into two thin per-jobset entry points:

  - (tribes ci artifacts-master): docker + sender-runtime + substitutes
  - (tribes ci artifacts-kexec): guix-kexec-installer only

The shared module now just exports the helpers and image builders.
2026-06-08 18:31:22 +02:00
self 31e622899b chore: Bump guix channel
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m40s
2026-06-08 17:26:42 +02:00
self 168e79994e chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 13m1s
2026-06-08 15:38:14 +02:00
self d3e0daf74e fix: normalize channel signer fingerprints
Trust checks now compare compact uppercase fingerprints so spaced OpenPGP fingerprints in channel introductions match stored TrustedSigner rows.
2026-06-08 15:38:08 +02:00
self 2ea4cae872 chore: Bump tribes pin
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m48s
2026-06-08 03:44:01 +02:00
self 635d5b24a2 feat: support commit update candidates
Add an advanced local-control update discovery mode that lists recent branch commits, while keeping semver tags as the default mode.
2026-06-08 03:44:01 +02:00
self cacb8c56f9 fix: record exact pulled channel pins
Have the local-control helper report the pulled profile's guix describe channel data after guix pull. Generation records now store exact commits for branch-based channel plans, and generations responses expose current system channel provenance as a fallback for initial installs.
2026-06-08 03:44:00 +02:00
self d20a5ec923 feat: discover channel update candidates
Add a local-control endpoint that uses Guix channel Git checkouts to fetch refs and list semver tag candidates for configured channels. Persist resolved channel pins on local-control generation records so Tribes can compare available updates with the commit actually prepared and activated.
2026-06-08 03:43:52 +02:00
self f25b2d9254 chore: Bump tribes pin
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m34s
2026-06-07 14:44:22 +02:00
self 755d0bec32 fix: move kexec pin to branch
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m30s
Remove the legacy kexec-installer sexp pin and stop the normal master artifact jobset from producing kexec installer archives; the kexec-installer branch now selects the installer source commit.
2026-06-06 01:34:22 +02:00
self 79ec9e572d fix: use versioned mirror artifacts
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m27s
Update pinned E2E downloads and the kexec installer pin for the /tribes-1 mirror layout with explicit Guix system filenames.
2026-06-06 00:45:54 +02:00
self af6bcb4b77 fix: avoid duplicating kexec initrd in artifact
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
Match the old kexec image builder by excluding already-copied boot artifacts from the embedded store squashfs. The Cuirass derivation was including the installer initrd and parameters store items from the system references graph, adding about 50 MiB to the archive.
2026-06-06 00:16:27 +02:00
self 722fff45ce fix: repair Cuirass substitute jobs
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m31s
Exclude CI-only modules from the tribes-command package build so it no longer tries to compile modules that depend on top-level substitute manifests.

Include the trust plugin in the kobold CI target because kobold requires the alliance trust capability, and add a regression test for the target plugin set.
2026-06-05 23:26:51 +02:00
self d1f82d27e8 feat: add Cuirass artifact and substitute jobs
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m28s
Export Cuirass custom jobs for release artifacts, substitute warmup manifests, deployment system targets, and bootloader files. This lets the Guix container delegate artifact and substitute builds to Cuirass instead of the sync script.
2026-06-05 22:25:05 +02:00
self 39da8d4d32 chore: Bump kexec installer pin
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m36s
2026-06-05 16:41:30 +02:00
self e40f2f4d8f docs: Explain Tribes kernel hardening choices
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m41s
Replace the generic Nixpkgs reference with per-option rationale tied to Tribes deployment behavior. Drop CONFIG_DEBUG_LIST because CONFIG_BUG_ON_DATA_CORRUPTION already selects the cheaper LIST_HARDENED checks without enabling heavier debug-list machinery.
2026-06-04 21:36:17 +02:00
self 700886b53a fix: Reduce kexec installer closure size
Avoid embedding the already-copied kexec initrd and boot parameters in the squashfs store closure while keeping the system path and runtime closure available. Add conservative extra tribes-linux trims for niche mesh/IoT network stacks and rare local filesystems.
2026-06-04 21:36:17 +02:00
self 2ea3cfd211 feat: Add shared Tribes Linux kernel
Add a shared tribes-linux package with conservative hardening and server/text-console slimming. Wire build-host, kexec installer, and installed NBDE systems to use it, and assert substitute targets use the shared kernel.
2026-06-04 21:36:11 +02:00
self ba888a1f6d fix: Pin sender ffmpeg to 8.0.2
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m13s
Use the upstream FFmpeg 8.0.2 release tarball for the headless sender-ffmpeg variant while keeping the existing Sender-specific configure subset.
2026-06-04 17:46:29 +02:00
self a73891fe2b feat: Use headless sender ffmpeg
Add a sender-ffmpeg package inheriting FFmpeg 8.0 with the headless streaming codec/protocol subset and without display/GPU stacks. Use it for the Sender plugin extra package and the external sender runtime pack, while preserving fallback lookup for existing stock ffmpeg plugin packages.
2026-06-04 17:46:20 +02:00
self 6feab76abc feat: Add sender runtime pack
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m17s
Define a Guix tarball pack for external Sender runtime nodes, including ffmpeg, Vinyl, node_exporter, vmagent, and a private Shepherd launcher. The launcher defaults to /etc/tribes/sender-runtime.env and includes an example env file plus optional boot hook installation.
2026-06-04 16:19:27 +02:00
self 5f46a9610e chore: Bump tribes + plugins
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m49s
2026-06-02 00:26:08 +02:00
self 858b4bf5ad chore: standardize build host option
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m9s
Use --build-host consistently for optional remote Guix pin refreshes while keeping local Guix as the default.
2026-06-01 21:38:04 +02:00
self e1d71d6177 chore: bump Tribes and plugin pins
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
Refresh the Tribes source pin and plugin pins after fixing update-plugin-pin to hash Sender dependencies with the same setup used by the package definition.
2026-06-01 18:43:27 +02:00
self 5e1a7383bc fix: hash plugin deps with package config
Make update-plugin-pin derive its dependency hashing setup from the plugin package's reuse-host-libs and include-mix-deps settings instead of always injecting the host source setup.
2026-06-01 18:43:21 +02:00
self 3895c2f63c fix: build node 24 with Argon2 OpenSSL
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m24s
Pin Node 24's OpenSSL input to 3.5.5 so Guix-built Node exposes working crypto Argon2 support instead of only the API surface.
2026-06-01 15:19:48 +02:00
self 9d56a5ca59 chore: Bump tribes + plugins
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 34m23s
2026-06-01 04:47:56 +02:00
self 9978970683 fix: pin kexec image to signed channel commit
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 34m9s
Update the kexec installer source pin from the unsigned local commit hash to the signed guix-tribes commit currently present on master.
2026-05-31 01:20:44 +02:00
self d2363b0801 refactor: use upstream OTP packages
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
Drop the custom OTP 28 package set and use upstream Guix Erlang, Elixir, Hex, and rebar3 packages throughout Mix builders and substitute manifests.
2026-05-31 01:02:52 +02:00
self d9498659e8 fix: use Guix auth introduction commit
Keep the pinned Guix target at the trace-framing commit while using the earlier .guix-authorizations commit as the channel introduction.
2026-05-31 01:02:43 +02:00
self 1242f64308 build: include Guix pin in kexec image
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 34m20s
Advance the kexec installer source pin to the channel commit that carries the trace-framing Guix base-channel update.
2026-05-31 00:03:05 +02:00
self 5e1e2b5286 build: pin Guix fork trace framing branch
Move the shared Guix base channel to guix-fork refactor/substituter-trace-framing at 83b0e7d44546968002fb0c0043004da4e9bedc0d and use that signed commit as the channel introduction.
2026-05-31 00:03:04 +02:00
self da53ef8915 refactor: drop repo-specific development shell config
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m20s
Keep development environment details in each consuming repository and leave guix-tribes responsible for shared package definitions.
2026-05-30 22:36:46 +02:00
self 3fea7c5612 feat: add prettier to Guix development environment
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m14s
Package Prettier 3.6.2 from the npm tarball and include it in the Tribes Guix development shell so shared PATH-based hooks can format web assets.
2026-05-30 21:58:26 +02:00
self e5b6d56131 feat: add prek to Guix development environment
Package prek 0.3.11 from crates.io and include it in the Tribes Guix development manifest so existing repo hooks can find the prek executable on PATH.
2026-05-30 21:58:26 +02:00
self 0eb837dfed feat: add Guix development shell support
Add a reusable tribes/development namespace with a development manifest and tribes-dev helper. Move the Node 24 package into guix-tribes so development shells and downstream packages can share it.
2026-05-30 21:58:19 +02:00
self 942b316ed0 feat: add npm builder
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m58s
Adds (tribes packages npm) with fetch-npm-deps (network-enabled
fixed-output node_modules tree via npm ci, in the style of
fetch-mix-deps) and npm-binary-package (extracts an npm tarball or
source dir, drops in the prefetched node_modules, and creates /bin
wrappers that invoke node with PATH-INPUTS prepended).

Both helpers take a #:node keyword so callers can pin against a
specific node version (e.g. node-24).
2026-05-29 23:43:42 +02:00
self 28f6791073 chore: Bump tribes + kobold
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m4s
2026-05-29 22:31:56 +02:00
self 87f5c625ff chore: Bump tribes + kobold
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m15s
2026-05-29 04:27:52 +02:00
self f03b7fa01c feat: keep disabled plugins installed
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m11s
Resolve disabled plugins into the Guix generation while passing their names to Tribes as runtime-disabled, preserving package/schema/data for later re-enable.
2026-05-28 21:51:14 +02:00
self 3aa7e4737e build: update access policy package pins
Bump Tribes, Kobold, and Trust to the commits that add generic access policy support and Trust-gated Kobold dataset access.\n\nPin hashes were refreshed with pguix after the local Guix build could not resolve cached Hex metadata offline.
2026-05-28 21:51:14 +02:00
self 853a8c61c0 fix: preserve core guix channel for rollouts
When local-control writes rollout channels from a SystemTarget plan, preserve the current core guix channel if the plan only contains the Tribes plugin channel.\n\nGuix pull requires a channel named guix; SystemTarget channel entries currently model the Tribes channel selected for plugin/package resolution, so overwriting channels.scm with only that channel breaks prepare.
2026-05-28 21:51:13 +02:00
self 951804641f fix: discover plugin packages from channel modules
Limit plugin catalog discovery to tribes/plugins modules present on the active Guix load path.\n\nThe local-control catalog path runs under guix repl where channel modules are available on %load-path but not necessarily in %package-module-path, causing fold-packages to return an empty catalog.\n\nAlso update the deploy executor test expectation for the current aether registry version.
2026-05-28 21:51:07 +02:00
self 5393a19225 build: update supertest scheduler probe pin
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m9s
Pin tribes-plugin-supertest to the scheduler probe fixture commit and refresh its source and mix dependency hashes.\n\nValidated tribes-plugin-supertest on pguix.
2026-05-28 18:19:05 +02:00
self f8c1022469 fix: update plugin capability pins
Handle keyword-style #:provides and #:requires entries in plugin package definitions, including both pinned and local package variants.\n\nVerified update-plugin-pin with --use-build-host pguix for supertest and sender temp checkouts.
2026-05-28 18:19:05 +02:00
self 191066fc38 build: package plugin API and update Tribes pin
Move the Guix Tribes source pin to the monorepo commit that prepares tribes_plugin_api as a standalone Hex package.\n\nAdd a tribes-plugin-api Guix package from the monorepo subproject and install built-in plugin ebin files by manifest otp_app so tribes_ui assembles correctly.\n\nValidated on pguix with builds for tribes, tribes-plugin-api, external plugin packages, and an assembled tribes-full-with-plugins expression.
2026-05-28 18:18:58 +02:00
self f98f039fc1 build: slim Guix plugin packages
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m16s
Derive plugin registry records from package metadata, reuse host release libs for plugin compilation, and make native/private Mix deps opt-in.\n\nUpdate the Tribes pin to the scheduler commit and verify plugin builds on pguix without shipping host OTP apps.
2026-05-28 13:32:56 +02:00
self 14882a5f01 feat: package Trust and update Kobold pin
Add the Trust plugin package to guix-tribes, include it in plugin pin refreshes and registry substitute packages, and update the Kobold package pin for the dataset foundation.
2026-05-28 13:32:55 +02:00
self aca1dff50a feat: discover plugins from Guix channels
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m17s
Generate the plugin catalog dynamically from Guix package metadata exposed by the pulled channel environment. Remove the static catalog service path, write rollout target channels before pull, expose the local-control catalog endpoint, and update the Tribes source pin.
2026-05-28 00:15:49 +02:00
self f069da99c2 feat: namespace plugin manifests in packaging
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m2s
Validate id/slug manifests and fully-qualified capabilities during release assembly, add Kobold to the plugin registry, and
 refresh Tribes/plugin pins.
2026-05-27 19:21:35 +02:00
self 23a8577c09 chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m18s
2026-05-26 20:03:35 +02:00
self 5847838e16 chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m16s
2026-05-26 15:46:08 +02:00
self 7e93d51ad2 ci: preserve devenv path for pinned e2e
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m50s
Run the pinned Tribes e2e preparation in a non-login shell so devenv's PATH remains active. The login shell reset PATH and made mix unavailable before dependency preparation.
2026-05-26 04:56:45 +02:00
self a32f930f63 ci: prepare pinned Tribes e2e deps
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m32s
Install local Hex/Rebar and fetch Mix dependencies in the checked-out pinned Tribes harness before running the Docker e2e script. The e2e script invokes mix run for host-side assertions, which otherwise fails on a fresh checkout without deps.
2026-05-26 02:51:58 +02:00
self 65664d268d fix: make debug Docker entrypoint self-contained
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m15s
Use store-qualified tools in the Guix-built Docker entrypoint, seed PATH for the Mix release launcher, and provide a default release cookie for e2e containers. Also normalize Tribes release launcher installation so debug package variants expose bin/tribes-app consistently.
2026-05-26 02:00:29 +02:00
self 2d3ecab909 chore: Bump tribes + plugins 2026-05-26 02:00:29 +02:00
self 45a91d0472 chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m50s
2026-05-25 23:47:12 +02:00
self fe4045105a fix: use loaded Docker image tag in pinned e2e
Read the image reference reported by docker load and pass that exact tag to the pinned Tribes e2e harness. This avoids trying to pull an assumed repo:commit tag when guix pack loads the image as repo.commit:latest.
2026-05-25 23:47:04 +02:00
self 05179472c2 chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m3s
2026-05-25 21:49:36 +02:00
self 2936597311 chore: Bump tribes
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 34m26s
2026-05-25 20:59:10 +02:00
self 3deb38725f feat: normalize Shepherd kmsg logs
Rewrite Shepherd messages copied through /proc/kmsg to program=shepherd with notice severity and stripped kernel timestamp prefix. Keep the normalized entries in combined JSONL and conventional messages logs without duplicating raw kernel copies.
2026-05-25 20:59:04 +02:00
self cb473d5cff chore: Bump tribes + plugins
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m9s
2026-05-25 18:17:42 +02:00
self 8119ce5ed9 ci: use host nix for pinned docker e2e
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 33m2s
Run the pinned Docker E2E workflow on the host-Nix runner and reuse the host daemon/store instead of installing Nix inside the job container. This avoids unsandboxed in-container builds and the /homeless-shelter purity failure while keeping the existing gated E2E flow.
2026-05-25 04:13:42 +02:00
self bdb9706417 chore: Bump tribes 2026-05-25 04:13:36 +02:00
self db1b2b9e3e build: reuse host libs for lightweight plugins
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 35m9s
Compile Aether and Supertest against the already-built Tribes release libs instead of rebuilding the shared host dependency closure. Keep Sender on the existing standalone path until plugin-only dependency handling is added.
2026-05-25 00:40:09 +02:00
self 21c9e33768 ci: gate pinned e2e runs
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
Cancel superseded pinned E2E runs and skip automatic jobs for unsigned agent pushes so only signed self pushes or manual dispatch run the expensive workflow.
2026-05-24 23:58:56 +02:00
self 365d27d027 chore: Bump tribes + plugins
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 35m7s
2026-05-24 23:49:11 +02:00
self a80189ad08 chore: Bump tribes + plugins
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
2026-05-24 17:27:03 +02:00
self 0747a0f8db ci: run pinned-e2e on ubuntu-22.04 with Nix-bootstrapped devenv
Pinned Docker E2E / pinned-docker-e2e (push) Failing after 32m28s
The tribes-ci self-hosted label was never declared by the runner, so all
runs sat queued. Switch to the docker-backed ubuntu-22.04 label and
install Nix + devenv inside the job so the e2e harness can run.
2026-05-24 14:57:44 +02:00
self 6079649b00 build: mix-fod-deps: Build on 6 cores (was 4)
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
2026-05-23 22:16:38 +02:00
self 6549ac8f40 fix: import (guix build utils) into debug Docker entrypoint builder
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
The trivial-build-system does not propagate (guix build utils) into the
build sandbox by default, so the builder failed with "no code for module
(guix build utils)" when resolving mkdir-p. Wrap the gexp with
with-imported-modules and move chmod out of call-with-output-file so it
actually runs after the file is closed.
2026-05-23 22:04:53 +02:00
self 9405c89574 chore: Bump tribes + plugins
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
2026-05-23 21:21:41 +02:00
self 1ce2fad983 feat: make pin updates local-first
Default pin refresh scripts to local Guix and require an explicit --use-build-host HOST for remote hashing/builds. Update the README to describe current channel contents and pin maintenance commands without local host-specific names.
2026-05-23 21:21:35 +02:00
self 9557d3c5fa fix: import nss for debug Docker package
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
The channel package cache evaluates tribes-debug-docker-entrypoint during guix pull; import (gnu packages nss) so nss-certs is bound with current Guix.
2026-05-23 20:16:51 +02:00
self f600edefc6 feat: add combined pin update script
Add a wrapper that refreshes the Tribes pin and each listed external plugin pin by calling the existing update scripts.

Support an optional --commit flag that stages only the affected pin files and commits them with the requested bump message.
2026-05-23 20:16:51 +02:00
self 9e3d39672e ci: add debug Docker e2e workflow
Pinned Docker E2E / pinned-docker-e2e (push) Has been cancelled
Add a Guix-packed debug Docker image and Gitea workflow for pinned multi-node e2e validation. The debug image is built with admin debug methods enabled and published under debug-specific names so it is not confused with a real release image.
2026-05-23 19:05:40 +02:00
self a3f70dadb1 chore: Bump tribes 2026-05-23 14:19:20 +02:00
self 048979ae25 chore: Bump tribes 2026-05-22 21:34:02 +02:00
self aa7eb0bc81 fix: preserve minimal Git metadata for Mix deps
Mix validates Git dependencies with remote.origin.url as well as HEAD during offline builds. Keep a tiny sanitized .git directory for SCM deps so vendored dependency trees remain reproducible without tripping lock mismatch checks.

Update the fixed-output hashes for the raw and prepared Tribes Mix dependency trees.
2026-05-22 19:46:57 +02:00
self 824d92732f chore: Bump tribes 2026-05-22 17:38:28 +02:00
self fff523d732 fix: rely on Tribes sync defaults
Remove the guix-tribes sync-overlap-seconds service field and host JSON key so deployments use the Tribes release default instead of carrying a second drift-prone default.

This also removes the example and CI substitute configuration override for TRIBES_SYNC_OVERLAP_SECONDS.
2026-05-20 23:24:57 +02:00
self 83da38fb95 chore: Bump tribes 2026-05-20 21:29:27 +02:00
self f0013360dc build: bump Tribes for log prefix import
Pin Tribes to the importer fix that recognizes source/type markers after release logger metadata so deployed log roundtrip entries import with structured metadata.
2026-05-19 23:39:27 +02:00
self c801e01c98 fix: cover native and node exporter logs
Move Chrony from a tailed file source to native syslog per-service output, and add the Prometheus node exporter Shepherd log to syslog-ng tail inputs. This keeps combined JSONL coverage aligned with the files produced by deployed nodes.
2026-05-19 22:52:50 +02:00
self a6939d976e build: bump Tribes for log query fix
Update the Tribes package pin to include the admin log_entries.list filter fix and quieter JSONL importer tests.
2026-05-19 21:20:08 +02:00
self ab2435c5e6 fix: allow Tribes to read combined logs
Make the syslog-ng combined JSONL importer input group-readable by the tribes group instead of world-readable. Activation now creates the file as root:tribes 0640, and the syslog-ng destination preserves that group and mode so the Tribes importer can read it without exposing per-service logs broadly.
2026-05-19 19:06:57 +02:00
self f1cb802256 fix: pass ffmpeg path to Sender via env
Keep Sender's development default as ffmpeg on PATH, but when the sender plugin contributes Guix ffmpeg to the Tribes runtime, set SENDER_FFMPEG_EXECUTABLE to the exact store ffmpeg binary. This keeps the deployment model explicit without forcing ffmpeg into base nodes.
2026-05-19 17:01:38 +02:00
self 33bc61667b fix: provide inotifywait to Tribes runtime
Set FILESYSTEM_FSINOTIFY_EXECUTABLE_FILE to the Guix inotify-tools binary and include inotify-tools in the Tribes profile/PATH so the Elixir file_system backend can start on deployed nodes instead of falling back to polling.
2026-05-19 17:01:37 +02:00
self cc108b3427 build: bump Tribes for log importer fallback
Update the Tribes pin to include the JSONL importer fix that treats an unavailable file watcher as a polling fallback on systems without inotify-tools.
2026-05-19 17:01:37 +02:00
self 396b8363c1 feat: add syslog-ng system logging
Package a minimal syslog-ng build without Python runtime support and wire it in as the system syslogd provider. Write combined Tribes JSONL logs plus conventional and per-service logs directly under /var/log, and update the Tribes source pin for the amended importer default.
2026-05-19 13:42:28 +02:00
self 14dc316dca feat: read local NBDE boot key from boot partition
Teach the NBDE mapped-device initrd logic to mount the boot partition and try /boot/nbde/local-boot.key at boot time instead of baking local key material into the initrd.

Update system facts defaults, materialisation, tests, and NBDE documentation for the boot-key model.
2026-05-19 13:42:27 +02:00
self b0b5b8f60e chore: Bump guix-fork, new channel pin updater 2026-05-19 00:27:29 +02:00
self 1ece6e6542 chore: Bump sender plugin 2026-05-18 18:32:54 +02:00
self 34af7edabf build: bump Tribes source pin
Pick up the mesh sync identity fix so live Guix-based cluster provisioning verifies the internal sync listener against the peer node pubkey.
2026-05-18 15:05:50 +02:00
self 9d12749fad chore: Bump tribes + plugins 2026-05-18 13:20:55 +02:00
self 74552df172 feat: add chrony service to tribes nodes
Define a local Chrony service using Guix's chrony package and the default Guix NTP pool configuration.

Install the service on every Tribes node and add node tests for service inclusion plus rendered chrony.conf defaults.
2026-05-18 13:20:49 +02:00
self 0611f08d96 fix: start Tribes after node reboot
Add a boot-time Shepherd one-shot that starts the Tribes service once Legion-managed secret files exist. This keeps the first secrets-free install boot explicit-start only, while allowing already-installed nodes to recover after provider reboots.

Document the behavior and assert the service auto-start shape in the node service test.
2026-05-18 11:13:14 +02:00
self ed742a24d4 chore: Bump sender plugin 2026-05-17 22:34:28 +02:00
self a2dea1add7 fix: stage boot store paths after rollouts
Install the NBDE boot-store staging hook into every generated node OS so Guix generation switches copy GRUB-referenced store items into the unencrypted /boot partition. This keeps new kernel and initrd store paths bootable when the real store lives on encrypted root.

Also move the provider NIC initrd module list into the shared installed base so immutable rollout snapshots keep the modules that Legion previously injected only during initial install.
2026-05-17 22:27:04 +02:00
self b112ef46d5 fix: trust forwarded IPs for vinyl exporter
Bump vinyl-exporter to v0.2.0 and expose trusted proxy configuration so HLS IP fallback can use X-Forwarded-For from the local HAProxy/Vinyl edge path.
2026-05-17 22:26:58 +02:00
self ae6968c5b8 chore: Bump sender plugin 2026-05-17 17:06:41 +02:00
self aa0823862a build: update Guix fork pin
Point the base and Legion channel pin files at guix-fork commit 5205cfb34c2e1c070bc026541ac9ab02319ee8c7 so deployments use the current diagnostic fixes.
2026-05-17 10:05:19 +02:00
self 323f376d5e fix: preserve Guix helper failure diagnostics
Capture stderr together with stdout when invoking Guix commands so malformed progress/reporting failures remain visible to Legion and supertest logs.\n\nAlso log the exact Guix command, exit status, selected binary, profile root, and Guix-related load path environment for future provisioning failures.
2026-05-17 10:05:19 +02:00
self 2aa25ceb98 chore: Bump guix-fork (atomic write fix) 2026-05-17 01:51:36 +02:00
self 9d594c3ea6 fix: use pulled Guix modules for child commands
Set GUIX_UNINSTALLED while invoking the selected current Guix profile so the packaged guix launcher does not prepend its own older module tree ahead of the profile load paths. This makes child commands such as system switch-generation actually run channel-provided Guix fixes.

Extend the current-guix environment test to cover the new variable and restoration behavior.
2026-05-16 23:49:30 +02:00
self b3ea498eb1 fix: include switch output in rollout failures
Preserve the captured guix system switch-generation output tail in local-control failure details. This keeps the actual Guix error path visible when a rollout fails before the profile switch, as seen in the cluster sender test.
2026-05-16 22:21:49 +02:00
self 3013cee55a chore: Bump tribes and sender 2026-05-16 17:16:30 +02:00
self 5fdfba88e7 fix: expose bootloader substitute targets
Add explicit BIOS and EFI bootloader configuration targets for substitute prewarming. Plain guix system build does not lower the bootloader config or installer helper paths, so those GRUB artifacts could be missing from our cache even when the OS closure was present.

Use minimal synthetic operating systems for these targets so the bootloader artifacts can be built without pulling the full Tribes node closure.
2026-05-16 16:24:16 +02:00
self 49c4be0fc9 build: update kexec installer pin
Point the mirrored Legion kexec installer image at the current signed guix-tribes master commit so the Guix mirror builder publishes a fresh tarball for this channel baseline.
2026-05-16 01:08:26 +02:00
self 55acab32ff build: update pinned Guix fork
Move the guix-fork channel pin to the signed status trace hardening commit b73ddc8cc1dc530bcabc1227013b9e3be7a257db.

Keep the existing e75105240061d201b7d523018d07e3b230479a26 introduction commit as the channel authentication root.
2026-05-16 00:46:16 +02:00
self dbf0c2ce70 fix: label sender hls metrics by stream
Configure edge vinyl_exporter to strip the Sender HLS prefix before deriving stream labels so playlist metrics use the Sender stream id instead of collapsing under the generic sender path component.
2026-05-15 23:35:56 +02:00
self 7d6de20e7d feat: add substitute OS targets
Expose channel-level operating-system targets for phase1, a base edge node, and a Sender-enabled edge node so the substitute builder can warm full deployment closures, not just package manifests.
2026-05-15 22:55:43 +02:00
self 59363f5e4f feat: add Vinyl exporter node service
Package the Vinyl metrics exporter, run it alongside the edge Vinyl cache, add it to local vmagent scraping and the node substitute manifest, and update the Tribes and sender pins consumed by the node build.
2026-05-15 16:17:52 +02:00
self 338031d8e6 build: update tribes and plugin pins
Pin guix-tribes to the Alliance refactor commit and refresh Aether, Sender, and Supertest plugin source hashes.

Also carry the VictoriaMetrics scraper adjustment so vmagent scrapes the Tribes /metrics endpoint on port 4000.
2026-05-14 20:45:58 +02:00
self 7f9497312d fix: retain VictoriaMetrics data for 90 days
Set the default VictoriaMetrics retention period for Tribes nodes to 90d and add a node-system test expectation so the policy remains explicit.
2026-05-12 18:48:13 +02:00
self 42f4e8d86e feat: scrape node exporter on Tribes nodes
Run Guix's Prometheus node exporter on every default Tribes node, bind it to loopback, and include it in the node substitute manifest. Add the exporter endpoint to vmagent's default scrape config and cover the service wiring in the node system tests.
2026-05-12 18:39:49 +02:00
self 4e95d3db80 feat: add VictoriaMetrics node monitoring
Package VictoriaMetrics 1.143.0 with the Tribes Go helper, install the single-node server plus vmagent and backup tools, and enable loopback-only VictoriaMetrics/vmagent services on every Tribes node. Add the package to the node substitute manifest and cover the default service wiring in the node system tests.
2026-05-12 18:29:53 +02:00
self aa07d658c5 feat: link HAProxy QUIC against AWS-LC
Add a scoped AWS-LC 1.73.0 package for HAProxy and build HAProxy's QUIC support against it instead of OpenSSL compatibility mode.

Remove the limited-quic runtime knob and update the rendered node config test to assert native QUIC configuration.
2026-05-12 11:44:05 +02:00
self b0d3b184cc feat: enable HAProxy QUIC listener
Upgrade the HAProxy package to 3.3.10 and build it with QUIC support via the OpenSSL compatibility layer used by the current Guix OpenSSL 3.0 input.\n\nExpose default HTTP/3 UDP listeners, advertise h3 through Alt-Svc, and cover the generated edge proxy config in the node system tests.
2026-05-12 02:18:21 +02:00
self b68182c838 refactor: remove obsolete Hitch package and service
HAProxy now owns the edge listener path, so keep guix-tribes from exporting or maintaining the old local Hitch package and service module.
2026-05-12 01:40:35 +02:00
self dd87cb201c refactor: route HTTP edge traffic through HAProxy
Let HAProxy own both public edge listeners so ACME challenge paths are proxied directly to Lego's standalone challenge server while all other HTTP traffic redirects to HTTPS. Remove the HTTP-only Vinyl instance and keep Vinyl focused on the private cache backend.
2026-05-12 01:31:08 +02:00
self bade8dd709 feat: replace edge TLS proxy with HAProxy
Add HAProxy 3.3.9 to the Tribes Guix channel and introduce a Shepherd service for the public TLS edge. Wire node edge deployments and Lego reloads to HAProxy while keeping Vinyl's HTTP challenge and cache topology unchanged.
2026-05-11 23:14:51 +02:00
self e00e40e61e fix: derive rollout capabilities from built-ins
Move rollout dependency resolution off the old hard-coded host capability baseline and onto the same host/built-in plugin contract used by package assembly. The resolver now recognizes the built-in tribes_ui provider for ui@1 and rejects unsatisfied host/built-in contracts before planning external plugin dependencies.
2026-05-11 16:30:06 +02:00
self eacd35d952 fix: avoid textual-ports in plugin assembly
Replace the assembled plugin package builder's get-string-all dependency with a local read-char loop. This keeps the builder module closure compatible with node-side Guix builds that use the rollout Guile package and avoids failures resolving (ice-9 custom-ports).

(cherry picked from commit 8b433f9d90)
2026-05-11 16:30:06 +02:00
self dd7abb9231 fix: include guix build output in rollout failures
Return a bounded tail of captured guix system build output in local-control build_failed frames. This keeps rollout diagnostics actionable when the node is destroyed before the full helper stderr can be inspected.
2026-05-11 16:30:06 +02:00
self 74efeb9821 fix: resolve plugins against built-in ui provider
Treat capabilities provided by built-in Tribes plugins as baseline resolver capabilities so channel plugins that require ui@1 can be previewed and rolled out without adding a separate external UI plugin. Add a sender regression case to the deploy executor tests.
2026-05-11 16:30:06 +02:00
self f48063085b build: package sender muontrap binary
Bump the sender plugin pin to the current packaged source and assert that plugin builds containing muontrap include an executable priv/muontrap binary. The Guix package build now fails early if the native Mix dependency is compiled without its runtime helper.
2026-05-11 16:30:00 +02:00
self 0723473037 chore: Bump tribes 2026-05-11 13:25:56 +02:00
self 21a87d3485 fix: expose plugin runtime binaries to Tribes
Add the effective Tribes package and plugin extra package bin directories to the Tribes launcher PATH. This lets runtime plugin code find executables, such as sender resolving ffmpeg from its Guix extra package, after a rollout switches to the plugin-enabled system generation.
2026-05-10 06:24:16 +02:00
self 419bea8fe5 chore: Bump tribes & plugins 2026-05-09 19:50:55 +02:00
self 1b72d966de feat: validate host API plugin assembly 2026-05-09 19:45:46 +02:00
self 97efdc4465 fix: compile all bundled Tribes plugins 2026-05-09 15:52:13 +02:00
self 833b43bdda fix: defer Tribes startup until secrets exist 2026-05-08 21:59:21 +02:00
self d7f93c0f41 chore: bump Tribes mesh sync refresh baseline 2026-05-08 21:37:29 +02:00
self e9ec7e1b08 chore: bump Tribes bootstrap state baseline 2026-05-06 21:52:17 +02:00
self 0f526fa706 chore: bump Tribes rollout barrier fix 2026-05-06 20:14:42 +02:00
self f343b5b82b fix: include nftables on Tribes nodes 2026-05-06 17:46:11 +02:00
self 360623b923 chore: bump Tribes rollout sync baseline 2026-05-06 15:15:50 +02:00
self a0019c1986 fix: bind release rpc to loopback 2026-05-06 13:49:13 +02:00
self 7860f8ba94 chore: Bump tribes 2026-05-05 14:16:03 +02:00
self a895e9afc0 fix: reuse prepared guix for post-switch activation 2026-05-05 12:25:17 +02:00
self 586274f8c9 fix: preload shepherd service file closures 2026-05-05 04:31:37 +02:00
self 337aa58346 fix: realize rollout closure references incrementally 2026-05-05 01:07:05 +02:00
self 53a64c16c8 fix: preload rollout store closures before switch
Prepare already builds the target system and lowers the Shepherd service-upgrade program, but substituted store items can still leave referenced outputs absent locally.  That let activation or Shepherd service loading fetch or build large dependencies during the switch phase.

Realize the target system closure and the lowered service-upgrade gexp closure during prepare with Guix store topological closure walking plus ensure-path.  Keep the same closure realization in local-eval as defense-in-depth for any post-switch gexp evaluation.
2026-05-04 23:56:05 +02:00
self c9e0541ee4 fix: preload service upgrade inputs before switch 2026-05-04 22:46:12 +02:00
self 9c20577a15 fix: build from recorded system channels 2026-05-04 21:21:28 +02:00
self 03fc829d22 fix: build rollouts from system channel provenance 2026-05-04 18:58:22 +02:00
self 5e381828b0 chore: Bump tribes 2026-05-03 15:56:05 +02:00
self 9a63a96d83 fix: run local-control builds in current Guix environment 2026-05-03 13:16:15 +02:00
self 3baa493154 fix: point kexec installer pin at published commit 2026-05-03 07:45:53 +02:00
self 14ef741198 chore: pin kexec installer image source 2026-05-03 07:26:56 +02:00
self b820951a42 feat: add kexec installer image builder 2026-05-03 07:26:39 +02:00
self 4a88712709 fix: trim Vinyl runtime build 2026-05-03 05:46:11 +02:00
self e05af14a45 fix: skip Vinyl package test suite 2026-05-03 04:25:02 +02:00
self 9661aac5ab fix: silence host Ash domain warnings in plugin builds 2026-05-03 04:22:40 +02:00
self 8d6b093e14 feat: build channel plugins in substitute baseline 2026-05-03 01:53:30 +02:00
self 0b4d3a77a9 fix: compile bundled tribes_ui plugin
Compile the in-tree tribes_ui Mix project during the Tribes release build and install its ebin output into the packaged plugin directory so the runtime plugin loader can load the entry module.
2026-05-02 23:44:09 +02:00
self 05c493bcf9 test: avoid running guile suites on import 2026-05-02 21:27:57 +02:00
self 29502781d8 chore: Bump tribes 2026-05-02 20:25:40 +02:00
self e13c136c09 test: harden local-control worker state 2026-05-02 19:39:28 +02:00
self 8849107168 fix: resolve herd for rollback migrations 2026-05-01 16:50:07 +02:00
self 39b1ed800a fix: skip no-op pulls and stabilize generation diagnostics 2026-05-01 16:42:42 +02:00
self 5a348e7c54 fix: run plugin rollback migrations 2026-05-01 15:30:58 +02:00
self 2484fe208e fix: skip wx-dependent OTP apps 2026-05-01 12:51:25 +02:00
self 2932ca1e95 fix: disable Erlang wx application
Use OTP's supported --without-wx configure flag instead of --disable-wx so the wx application is actually excluded from the lean build baseline.
2026-04-30 17:47:48 +02:00
self c471473a54 fix: establish lean plugin build baseline
Disable wx in the OTP 28 package used by Tribes builds and route Mix/Rebar through the matching Rebar package so server builds do not pull in the wx/GUI dependency graph.

Make plugin builds closer to the host build foundation by avoiding Node unless assets are built and vendoring libsecp256k1 for hermetic NIF compilation. Add diffutils for secp256k1 configure checks.
2026-04-30 17:06:07 +02:00
self ebe790f2a0 feat: introduce supertest plugin
Add the supertest fixture plugin to the Guix plugin registry so rollout preview can resolve the plugin name from the baseline channel while development continues on the signed supertest-dev branch.
2026-04-30 13:13:01 +02:00
24 changed files with 236 additions and 241 deletions
+1 -3
View File
@@ -5,6 +5,4 @@
(version 0)
(("6688 9153 C51C 4613 A493 A525 2F0D FD14 EF99 DAC3"
(name "steffen")) ("F29B A6DA 96E5 EC29 FDDE D994 8F4F 75B3 B19D 4784"
(name "tribes-supertest-dev"))
))
(name "steffen"))))
-7
View File
@@ -1,7 +0,0 @@
{
"mode" : "tree-sync",
"previous_dev_commit" : "593745da5e4135abc63956442e853dd2643e46ae",
"source_branch" : "origin/master",
"source_commit" : "54f23bc863ebef8173faf2aaf21801050e09fb53",
"synced_at" : "2026-06-09T07:43:46Z"
}
+54
View File
@@ -0,0 +1,54 @@
;;; Manifest of upstream source origins for every package defined by the
;;; tribes channel. Consumed by Cuirass's `manifests' build type as a
;;; network-bound canary: fast-fails when an upstream URL or commit ref
;;; becomes unreachable, without depending on any actual package build.
(define-module (manifests sources)
#:use-module (gnu packages)
#:use-module (guix discovery)
#:use-module (guix packages)
#:use-module (guix profiles)
#:use-module (ice-9 match)
#:use-module (ice-9 vlist)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (sources-manifest))
(define (channel-module-path prefix)
(delete-duplicates
(filter-map (lambda (dir)
(let ((path (string-append dir "/" prefix)))
(and (file-exists? path) (cons dir prefix))))
%load-path)
equal?))
(define (channel-packages)
(fold-packages cons '()
(append (all-modules (channel-module-path "tribes/packages"))
(all-modules (channel-module-path "nbde/packages")))))
(define (upstream-origin source)
(origin (inherit source) (snippet #f) (patches '())))
(define (channel-origins)
(let loop ((packages (channel-packages))
(origins '())
(visited vlist-null))
(match packages
((head . tail)
(let ((new (remove (cut vhash-assq <> visited)
(package-direct-sources head))))
(loop tail (append new origins)
(fold (cut vhash-consq <> #t <>)
visited new))))
(() origins))))
(define sources-manifest
(manifest (map (lambda (origin)
(manifest-entry
(name (or (origin-actual-file-name origin) "origin"))
(version "0")
(item (upstream-origin origin))))
(channel-origins))))
sources-manifest
-49
View File
@@ -1,49 +0,0 @@
(define-module (manifests substitutes base)
#:use-module (gnu packages)
#:use-module (gnu packages elixir)
#:use-module (gnu packages erlang)
#:use-module (guix profiles)
#:use-module (nbde packages crypto)
#:use-module (tribes packages terminals)
#:export (base-manifest))
(define %base-specifications
'("bash-minimal"
"coreutils"
"diffutils"
"findutils"
"gawk"
"grep"
"gzip"
"inetutils"
"iproute2"
"less"
"nss-certs"
"openssh"
"postgresql"
"procps"
"rsync"
"sed"
"tar"
"which"
"xz"
"cryptsetup"
"dosfstools"
"e2fsprogs"
"gptfdisk"
"kmod"
"parted"
"util-linux"))
(define base-manifest
(packages->manifest
(append (map specification->package %base-specifications)
(list clevis
tang
luksmeta
erlang
elixir
elixir-hex
ghostty-terminfo))))
base-manifest
-48
View File
@@ -1,48 +0,0 @@
(define-module (manifests substitutes installer)
#:use-module (gnu packages)
#:use-module (guix profiles)
#:use-module (nbde packages crypto)
#:export (installer-manifest))
(define %installer-specifications
'("bash-minimal"
"coreutils"
"diffutils"
"findutils"
"gawk"
"git-minimal"
"grep"
"gzip"
"guix"
"inetutils"
"iproute2"
"kexec-tools"
"less"
"curl"
"nss-certs"
"procps"
"rsync"
"sed"
"tar"
"which"
"zstd"
"xz"
"console-setup"
"cryptsetup"
"dosfstools"
"grub-efi"
"grub-pc"
"mdadm"
"e2fsprogs"
"gptfdisk"
"kmod"
"parted"
"util-linux"))
(define installer-manifest
(packages->manifest
(append (map specification->package %installer-specifications)
(list clevis
luksmeta))))
installer-manifest
-60
View File
@@ -1,60 +0,0 @@
(define-module (manifests substitutes tribes-node)
#:use-module (gnu packages)
#:use-module (gnu packages elixir)
#:use-module (gnu packages erlang)
#:use-module (gnu packages monitoring)
#:use-module (guix profiles)
#:use-module (tribes packages monitoring)
#:use-module (tribes packages source)
#:use-module (tribes packages terminals)
#:use-module (tribes packages web)
#:use-module (tribes plugins registry)
#:export (tribes-node-manifest
make-tribes-node-manifest))
(define %tribes-node-specifications
'("nss-certs"
"openssh"
"postgresql"
"rsync"
"ripgrep"
"fd"
"tmux"
"neovim"
"btop"))
(define (getenv/default name default)
(or (getenv name) default))
(define (tribes-node-package)
(let ((source-directory (getenv "TRIBES_SOURCE_DIRECTORY")))
(if source-directory
(local-tribes-package
source-directory
#:version (getenv/default "TRIBES_RELEASE_VERSION" "dev")
#:mix-deps-sha256 (getenv "TRIBES_MIX_DEPS_SHA256")
#:raw-mix-deps-sha256 (getenv "TRIBES_RAW_MIX_DEPS_SHA256")
#:npm-deps-sha256 (getenv "TRIBES_NPM_DEPS_SHA256"))
tribes-package)))
(define (make-tribes-node-manifest)
(packages->manifest
(append
(map specification->package %tribes-node-specifications)
(list erlang
elixir
elixir-hex
ghostty-terminfo
haproxy
vinyl
lego
prometheus-node-exporter
victoriametrics
vinyl-exporter
(tribes-node-package))
(guix-tribes-plugin-substitute-packages))))
(define tribes-node-manifest
(make-tribes-node-manifest))
tribes-node-manifest
+14 -4
View File
@@ -55,7 +55,10 @@
util-linux)))
(define %build-host-kexec-initrd-modules
'("ahci"
'(;; Common block/storage basics.
"ahci"
"ata_piix"
"cdrom"
"dm-crypt"
"fat"
"loop"
@@ -64,13 +67,19 @@
"nvme"
"overlay"
"sd_mod"
"sr_mod"
"squashfs"
"vfat"
;; KVM/QEMU and common emulated or non-virtio NICs.
"virtio_blk"
"virtio_console"
"virtio_net"
"virtio_pci"
"virtio_scsi"))
"virtio_scsi"
"e1000"
"e1000e"
"r8169"))
(define build-host-kexec-installer-os
(operating-system
@@ -83,10 +92,11 @@
(initrd-modules %build-host-kexec-initrd-modules)
(initrd kexec-installer-initrd)
(kernel-arguments
'("console=ttyS0,115200n8"
'("console=tty0"
"console=ttyS0,115200n8"
"net.ifnames=0"
"panic=30"
"loglevel=4"))
"loglevel=6"))
(bootloader
(bootloader-configuration
(bootloader grub-bootloader)
+3 -3
View File
@@ -1,10 +1,10 @@
(list (channel
(name 'guix)
(url "https://git.teralink.net/tribes/guix-fork.git")
(branch "refactor/substituter-trace-framing")
;; guix-fork refactor/substituter-trace-framing
(branch "feature/substitute-read-timeout")
;; guix-fork feature/substitute-read-timeout
(commit
"8514f9c1a98468c044e8b5f65e4a90d097a63a47")
"4574af27f27c7a5d2dc4d4823ef4518a392dc973")
(introduction
(make-channel-introduction
"093f27dde01cdbda68f2ec4b81e5a34ae180aab9"
+3 -3
View File
@@ -2,10 +2,10 @@
(channel
(name 'guix)
(url "https://git.teralink.net/tribes/guix-fork.git")
(branch "refactor/substituter-trace-framing")
;; guix-fork refactor/substituter-trace-framing
(branch "feature/substitute-read-timeout")
;; guix-fork feature/substitute-read-timeout
(commit
"8514f9c1a98468c044e8b5f65e4a90d097a63a47")
"4574af27f27c7a5d2dc4d4823ef4518a392dc973")
(introduction
(make-channel-introduction
"093f27dde01cdbda68f2ec4b81e5a34ae180aab9"
+1
View File
@@ -109,6 +109,7 @@ load_guix_env
require_tool guix
require_tool guile
require_tool mksquashfs
require_tool cpio
require_file "$channels" "channels file"
require_file "$script_dir/kexec-run" "kexec runner"
require_file "$root_dir/examples/build-host-kexec-installer.scm" "system file"
+2 -2
View File
@@ -7,11 +7,11 @@ base_output="${NBDE_BASE_CHANNELS_OUTPUT:-$root_dir/pins/base-channels.sexp}"
legion_output="${NBDE_LEGION_CHANNELS_OUTPUT:-$root_dir/pins/legion-channels.sexp}"
fork_url="https://git.teralink.net/tribes/guix-fork.git"
fork_branch="refactor/substituter-trace-framing"
fork_branch="feature/substitute-read-timeout"
fork_introduction_commit="093f27dde01cdbda68f2ec4b81e5a34ae180aab9"
fork_introduction_signer="6688 9153 C51C 4613 A493 A525 2F0D FD14 EF99 DAC3"
fork_checkout="$root_dir/../guix-fork"
fork_comment="guix-fork refactor/substituter-trace-framing"
fork_comment="guix-fork feature/substitute-read-timeout"
official_url="https://git.teralink.net/tribes/guix.git"
official_branch="master"
-11
View File
@@ -1,11 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEafMY7xYJKwYBBAHaRw8BAQdAX7Cs0UPcvEpHOwmTDkjNBfeH6/FH6sqKZbRi
sd3oBCy0U1RyaWJlcyBTdXBlcnRlc3QgRGV2IChBSSBsb2NhbCBkZXZlbG9wbWVu
dCBrZXkpIDx0cmliZXMtc3VwZXJ0ZXN0LWRldkB0ZXJhbGluay5uZXQ+iJYEExYK
AD4WIQTym6baluXsKf3e2ZSPT3WzsZ1HhAUCafMY7wIbAwUJAeEzgAULCQgHAgYV
CgkICwIEFgIDAQIeAQIXgAAKCRCPT3WzsZ1HhMp8AP4gGrPkBoGLKMyubISESFpH
fnqYUGDGucIoLRvtbl+ULQD/SlC9u/Ek9WSYvsskd0jD09lc2TxBnubl8yRi3bTM
sA8=
=JA7U
-----END PGP PUBLIC KEY BLOCK-----
+2
View File
@@ -332,6 +332,8 @@
(not (contains? text "limited-quic")))
(test-assert "haproxy logs to syslog-ng"
(contains? text "log /dev/log local0"))
(test-assert "haproxy preserves privileged bind capability for QUIC"
(contains? text "setcap cap_net_bind_service"))
(test-assert "haproxy binds configured certificate"
(contains? text
"bind 0.0.0.0:443 ssl crt /var/lib/lego/tribes/full.pem alpn h2,http/1.1"))
+17 -18
View File
@@ -3,26 +3,25 @@
#:use-module (srfi srfi-1)
#:export (cuirass-jobs))
;; Publishable artifacts: the debug Docker image and the Sender runtime pack.
;; Node operating-system closures and bootloader files are warmed by the
;; dedicated (tribes ci artifacts-substitutes) jobset instead.
(define (cuirass-jobs store arguments)
(let ((tribes-commit (arguments->channel-commit arguments 'tribes)))
(append-map
(lambda (system)
(append
(list (artifact-job store
"tribes-debug-docker"
(lambda ()
(tribes-debug-docker-image
#:image-tag
(if tribes-commit
(string-append "tribes-guix-debug:"
tribes-commit)
"tribes-guix-debug:latest")))
system)
(artifact-job store
"tribes-sender-runtime"
tribes-sender-runtime-pack
system))
(substitute-manifest-jobs store system)
(substitute-system-jobs store system)
(substitute-file-jobs store system)))
(list (artifact-job store
"tribes-debug-docker"
(lambda ()
(tribes-debug-docker-image
#:image-tag
(if tribes-commit
(string-append "tribes-guix-debug:"
tribes-commit)
"tribes-guix-debug:latest")))
system)
(artifact-job store
"tribes-sender-runtime"
tribes-sender-runtime-pack
system)))
(arguments->systems arguments))))
+21
View File
@@ -0,0 +1,21 @@
(define-module (tribes ci artifacts-substitutes)
#:use-module (tribes ci artifacts)
#:use-module (srfi srfi-1)
#:export (cuirass-jobs))
;; Warm the substitute mirror with the closures of the real Tribes node
;; operating-systems and their bootloader files, so deployed nodes pull every
;; required store path from guix.tribe-one.org during `guix system
;; init'/reconfigure without depending on upstream availability. This is the
;; authoritative substitute set: it is computed from the very operating-systems
;; nodes materialize, so it cannot drift the way the hand-curated
;; manifests/substitutes/*.scm package lists did, and it transitively covers
;; everything the node closure contains -- including the operator toolkit now
;; carried in the node system profile and the upstream dependencies pulled in
;; while building the closure.
(define (cuirass-jobs store arguments)
(append-map
(lambda (system)
(append (substitute-system-jobs store system)
(substitute-file-jobs store system)))
(arguments->systems arguments)))
+53 -26
View File
@@ -9,6 +9,7 @@
#:use-module (gnu packages nss)
#:use-module (gnu system)
#:use-module (guix build-system gnu)
#:use-module (guix channels)
#:use-module (guix derivations)
#:use-module (guix gexp)
#:use-module (guix monads)
@@ -17,9 +18,6 @@
#:use-module (guix scripts pack)
#:use-module (guix store)
#:use-module (ice-9 match)
#:use-module (manifests substitutes base)
#:use-module (manifests substitutes installer)
#:use-module (manifests substitutes tribes-node)
#:use-module (nbde system build-host-kexec-installer)
#:use-module (srfi srfi-1)
#:use-module (tribes ci substitutes)
@@ -33,7 +31,7 @@
artifact-job
arguments->systems
arguments->channel-commit
substitute-manifest-jobs
substitute-channel-profile-jobs
substitute-system-jobs
substitute-file-jobs))
@@ -173,7 +171,8 @@
(file-exists? path))
(copy-recursively path
(string-append squashfs-root "/"
(basename path)))))
(basename path))
#:keep-mtime? #t)))
(delete-duplicates
(append (list system boot-path)
(read-lines "system-graph"))))
@@ -249,10 +248,55 @@
(repository
(repository-field 'commit repository))))
(define %substitute-manifest-targets
`((base . ,base-manifest)
(installer . ,installer-manifest)
(tribes-node . ,tribes-node-manifest)))
(define (arguments->channels arguments)
(filter-map sexp->channel (or (assoc-ref arguments 'channels) '())))
(define (canonical-time-machine-channel channel)
;; Cuirass passes channel sexps whose URLs point at its pre-fetched
;; /gnu/store checkouts and whose introductions were dropped when Cuirass
;; created channel instances from those checkouts. That is correct for
;; evaluating custom jobs inside Cuirass, but it does not match the profile
;; computed by `guix time-machine -C channels.scm` on Legion installers,
;; where the channel URLs and introductions come from the public channel
;; file. Reconstruct those canonical fields while preserving the evaluated
;; commits.
(let* ((channel-name* (channel-name channel))
(canonical-url (match channel-name*
('guix "https://git.teralink.net/tribes/guix-fork.git")
('tribes "https://git.teralink.net/tribes/guix-tribes.git")
(_ (channel-url channel))))
(canonical-introduction
(or (channel-introduction channel)
(match channel-name*
('guix
(make-channel-introduction
"093f27dde01cdbda68f2ec4b81e5a34ae180aab9"
(openpgp-fingerprint
"6688 9153 C51C 4613 A493 A525 2F0D FD14 EF99 DAC3")))
('tribes
(make-channel-introduction
"607c69a5c1662acca07ad72c3e18646c73500856"
(openpgp-fingerprint
"6688 9153 C51C 4613 A493 A525 2F0D FD14 EF99 DAC3")))
(_ #f)))))
((@@ (guix channels) make-channel)
channel-name*
canonical-url
(channel-branch channel)
(channel-commit channel)
canonical-introduction
#f)))
(define (substitute-channel-profile-jobs store arguments system)
(let ((channels (map canonical-time-machine-channel
(arguments->channels arguments))))
(if (null? channels)
'()
(list (artifact-job store
"substitute-channel-profile"
(lambda ()
(latest-channel-derivation channels))
system)))))
(define %substitute-file-targets
`((bios-bootloader-configuration . ,bios-bootloader-configuration)
@@ -260,12 +304,6 @@
(efi-bootloader-configuration . ,efi-bootloader-configuration)
(efi-bootloader-configuration-installer . ,efi-bootloader-configuration-installer)))
(define (manifest-profile manifest)
(profile
(content manifest)
(hooks %default-profile-hooks)
(locales? #t)))
(define (artifact-job store name proc system)
(let ((drv (parameterize ((%current-system system)
(%graft? #f))
@@ -279,17 +317,6 @@
#:max-silent-time 3600
#:timeout 72000)))
(define (substitute-manifest-jobs store system)
(map (match-lambda
((name . manifest)
(artifact-job store
(string-append "substitute-manifest-"
(symbol->string name))
(lambda ()
(lower-object (manifest-profile manifest)))
system)))
%substitute-manifest-targets))
(define (substitute-system-jobs store system)
(map (match-lambda
((name . os)
+12
View File
@@ -0,0 +1,12 @@
(define-module (tribes ci channel)
#:use-module (srfi srfi-1)
#:use-module (tribes ci artifacts)
#:export (cuirass-jobs))
;; Cheap canary spec: emit only the channel-instance derivation, so a
;; "tribes modules compile and the checkout is reachable" signal is
;; independent of any package or system build.
(define (cuirass-jobs store arguments)
(append-map (lambda (system)
(substitute-channel-profile-jobs store arguments system))
(arguments->systems arguments)))
+1
View File
@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAITestLegionSharedBuilder legion@example.invalid
+26 -1
View File
@@ -15,11 +15,13 @@
#:use-module (nbde system initrd)
#:use-module (nbde system mapped-devices)
#:use-module (tribes config host)
#:use-module (tribes config system-facts)
#:use-module (tribes packages plugins)
#:use-module (tribes packages source)
#:use-module (tribes plugins registry)
#:use-module (tribes services tribes)
#:use-module (tribes system installer)
#:use-module (tribes system materialize)
#:use-module (tribes system node)
#:export (phase1-operating-system
base-edge-operating-system
@@ -153,6 +155,25 @@
(cache-port 6081)
(cache-storage '("malloc,256M"))))))
(define (ci-authorized-keys-file-name)
(or (search-path %load-path "tribes/ci/fixtures/root-authorized_keys")
(error "failed to locate CI authorized_keys fixture")))
(define %ci-system-facts
(tribes-system-facts
(host-name "tribes-ci-base-edge")
(interface "eth0")
(boot-mode "bios")
(bootloader-targets (list "/dev/sda"))
(boot-partition-uuid "11111111-2222-3333-4444-555555555555")
(boot-partition-file-system-type "ext4")
(root-luks-uuid "66666666-7777-8888-9999-aaaaaaaaaaaa")
(root-mapper-name "cryptroot")
(root-file-system-type "ext4")
(authorized-keys-file (ci-authorized-keys-file-name))
(local-boot-key-file "/boot/nbde/local-boot.key")
(tang-port 7654)
(initrd-network-timeout-seconds 20)
(enable-bbr? #t)))
(define* (ci-operating-system name plugins
#:key
(bootloader
@@ -170,6 +191,10 @@
#:interface "eth0"
#:authorized-keys-file %ci-authorized-keys-file
#:extra-services %ci-nbde-services))
(define (ci-materialized-operating-system plugins)
(tribes-host-configuration+system-facts->operating-system
(ci-host-configuration plugins)
%ci-system-facts))
(define* (bootloader-ci-operating-system name bootloader file-systems)
(operating-system
@@ -228,7 +253,7 @@
(ci-operating-system "tribes-ci-phase1" '()))
(define base-edge-operating-system
(ci-operating-system "tribes-ci-base-edge" '()))
(ci-materialized-operating-system '()))
(define aether-edge-operating-system
(ci-operating-system "tribes-ci-aether-edge"
+4 -3
View File
@@ -33,9 +33,10 @@
"CONFIG_X86_USER_SHADOW_STACK=y"))
(define %tribes-linux-disabled-options
'(;; Headless/text-console targets: keep VGA/framebuffer consoles, but drop
;; DRM/KMS GPU drivers and display acceleration stacks.
"DRM"
'(;; Keep DRM/KMS enabled so the installer has a local console on generic
;; virtual and real hardware. This costs roughly 15 MiB in the kexec image
;; compared to disabling DRM wholesale, but preserves Proxmox/QEMU VGA and
;; common real-hardware GPU/BMC consoles.
;; No audio output/input stack on Tribes server deployments.
"SOUND"
+2 -2
View File
@@ -54,7 +54,7 @@
"https://git.teralink.net/tribes/tribes.git")
(define %tribes-commit
"408c39553e4258dd75409eebfa0ffa4380591be0")
"f096578ec153342b29abfc5e900a82aefa378cb7")
(define %tribes-revision "1")
@@ -62,7 +62,7 @@
(git-version "0.2.0" %tribes-revision %tribes-commit))
(define %tribes-source-sha256
"16xn3vs6py74z4wrclwapzh18frrp5i663clvwid4l4kmivz833y")
"0hcrf3b8ddp6a65si92slr3vrnvib855h4pyccgrsk10q34qapas")
(define %tribes-upstream-source
(origin
+1
View File
@@ -79,6 +79,7 @@ QUIC support.")
#:make-flags
#~(list "LUA_LIB_NAME=lua"
"TARGET=linux-glibc"
"USE_LINUX_CAP=1"
"USE_LUA=1"
"USE_OPENSSL_AWSLC=1"
"USE_PCRE2=1"
+1
View File
@@ -119,6 +119,7 @@
(haproxy-lines
(append
(list "log /dev/log local0"
"setcap cap_net_bind_service"
(string-append "user " user)
(string-append "group " group)
"maxconn 32768"
+18 -1
View File
@@ -1,4 +1,5 @@
(define-module (tribes system node)
#:use-module (gnu packages)
#:use-module (gnu packages databases)
#:use-module (gnu packages linux)
#:use-module (gnu packages monitoring)
@@ -74,7 +75,12 @@
tribes-node-configuration?
(postgresql tribes-node-configuration-postgresql
(default (postgresql-configuration
(postgresql postgresql))))
(postgresql postgresql)
(config-file
(postgresql-config-file
(extra-config
'(("log_min_duration_statement" 1000)
("log_line_prefix" "%m [%p] user=%u db=%d app=%a client=%h "))))))))
(tribes tribes-node-configuration-tribes
(default (tribes-configuration)))
(edge tribes-node-configuration-edge
@@ -248,6 +254,14 @@
(tribes-edge-configuration-challenge-port edge)))
(pem-files (list (lego-certificate-full-pem certificate))))))))
;; Interactive toolkit installed into every node's system profile. These are
;; vanilla upstream packages an operator reaches for over SSH; shipping them in
;; the system closure means they are both present on the node and served by our
;; substitute mirror, instead of forcing a fallback to bordeaux/ci on first use.
(define %tribes-node-operator-tools
(map specification->package
'("ripgrep" "fd" "tmux" "neovim" "btop")))
(define (tribes-node-bbr-services config)
(if (tribes-node-configuration-enable-bbr? config)
(list
@@ -280,6 +294,9 @@
(simple-service 'tribes-node-network-tools
profile-service-type
(list nftables))
(simple-service 'tribes-node-operator-tools
profile-service-type
%tribes-node-operator-tools)
(service prometheus-node-exporter-service-type
(prometheus-node-exporter-configuration
(package prometheus-node-exporter)