Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 46 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,56 @@ on:
jobs:
test:
runs-on: ubuntu-latest
env:
# Ubuntu ships the Guile 3 binary as `guile-3.0`; the Makefile takes
# GUILE ?= guile, so we point it at that. (manifest.scm lists guile + jq.)
GUILE: guile-3.0
timeout-minutes: 30
steps:
- uses: actions/checkout@v4

- name: Install Guile 3, guile-json and jq
# hexol is a Guix project: manifest.scm is the source of truth for
# dependencies (guile + guile-json + guile-libyaml + jq). We provision
# the same environment in CI rather than re-deriving it from apt — among
# other things, the (yaml) module comes from guile-libyaml, which isn't
# packaged for Ubuntu.
#
# We install Guix from the official binary tarball (the interactive
# guix-install.sh hangs in CI), start the daemon, authorize the official
# substitute key so dependencies download instead of building, then run
# the suite inside `guix shell -m manifest.scm`. It's one step so the
# backgrounded daemon stays alive for the build.
- name: Provision Guix and run the suite
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends guile-3.0 guile-json jq
${GUILE} --version | head -1
set -eux
GUIX_VERSION=1.4.0
GUIX_PROFILE=/var/guix/profiles/per-user/root/current-guix
GUIX_BIN="$GUIX_PROFILE/bin"

- name: Build (compile every module — surfaces load/compile errors)
run: make build
cd /tmp
wget -q "https://ftp.gnu.org/gnu/guix/guix-binary-${GUIX_VERSION}.x86_64-linux.tar.xz"
sudo tar --warning=no-timestamp -xf "guix-binary-${GUIX_VERSION}.x86_64-linux.tar.xz" -C /

- name: Test (kernel, surface, construct, k8s, cmdb)
run: make test
# Build users + daemon, per the Guix manual's binary-install steps.
sudo groupadd --system guixbuild || true
for i in $(seq -w 1 10); do
sudo useradd -g guixbuild -G guixbuild -d /var/empty \
-s "$(command -v nologin)" -c "Guix build user $i" --system "guixbuilder$i" || true
done
sudo mkdir -p /root/.config/guix
sudo ln -sf "$GUIX_PROFILE" /root/.config/guix/current

- name: Test examples (render each standalone example, check it exits 0)
run: make test-examples
sudo "$GUIX_BIN/guix-daemon" --build-users-group=guixbuild &
sleep 5

# Download prebuilt binaries instead of compiling from source.
sudo "$GUIX_BIN/guix" archive --authorize \
< "$GUIX_PROFILE/share/guix/ci.guix.gnu.org.pub"

"$GUIX_BIN/guix" --version

# examples/terraform.scm reads an SSH public key from ~/.ssh at render
# time. The suite runs as root below, so give root a throwaway key —
# it's read as data for the rendered config, never used to connect.
sudo mkdir -p /root/.ssh
sudo ssh-keygen -t ed25519 -N '' -f /root/.ssh/id_ed25519 -q

# Run as root (daemon owner) to avoid socket-permission friction.
cd "$GITHUB_WORKSPACE"
sudo "$GUIX_BIN/guix" shell -m manifest.scm -- make build test test-examples
6 changes: 2 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ GUILE ?= guile

help:
@echo "targets:"
@echo " make test run the smoke tests (kernel, surface, res, cmdb)"
@echo " make test run the smoke tests (kernel, surface, res, k8s)"
@echo " make test-examples render the standalone examples, check they exit 0"
@echo " make build compile all modules (surfaces any load/compile error)"
@echo " make clean remove this project's Guile compile cache"
Expand All @@ -19,14 +19,12 @@ test:
$(GUILE) -L . test.scm
$(GUILE) -L . test/construct.scm
$(GUILE) -L . test/k8s-res.scm
$(GUILE) -L . test/cmdb-store.scm
$(GUILE) -L . test/cmdb-server.scm

test-examples:
GUILE=$(GUILE) ./test/examples.sh

build:
@$(GUILE) -L . -c '(begin (use-modules (hexol) (hexol k8s) (hexol terraform) (hexol apply) (hexol ansible) (hexol ledger) (hexol sql) (cmdb json)) (display "build ok\n"))'
@$(GUILE) -L . -c '(begin (use-modules (hexol) (hexol k8s) (hexol terraform) (hexol apply) (hexol ansible) (hexol ledger) (hexol sql) (hexol json)) (display "build ok\n"))'

clean:
rm -rf ~/.cache/guile/ccache/*$(CURDIR)*
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,26 @@ A few things this buys you over plain manifests:

## Install

Hexol runs on [Guile](https://www.gnu.org/software/guile/) 3.x — install that,
clone the repo, and run `./bin/hexol` (it auto-compiles on first use):
Hexol runs on [Guile](https://www.gnu.org/software/guile/) 3.x and needs two
Guile libraries: **guile-json** (the `(json)` module) and **guile-libyaml**
(the `(yaml)` module). It also uses `jq`. All of these are declared in
[`manifest.scm`](manifest.scm), which is the source of truth for dependencies.

The easy path is [Guix](https://guix.gnu.org/), which reads that manifest
directly — no manual install:

```sh
git clone https://github.com/Polyedre/hexol && cd hexol
./bin/hexol render -i examples/kubernetes.scm
guix shell -m manifest.scm -- ./bin/hexol render -i examples/kubernetes.scm
```

(The repo's `.envrc` does this automatically under [direnv](https://direnv.net/).)

Without Guix, install Guile 3.x plus guile-json, guile-libyaml, and jq however
your distro provides them, then:

```sh
./bin/hexol render -i examples/kubernetes.scm # auto-compiles on first use
```

The CLI itself shells out to nothing. Individual features do, and only when you
Expand Down Expand Up @@ -98,7 +112,10 @@ While the kernel is target-agnostic, the library provide a few syntaxic sugar he
- **Secrets (SOPS)** — secrets live inline in the inventory, encrypted at rest
with [sops](https://github.com/getsops/sops): no separate `*.sops.yaml` files
to keep in sync. `(secret-ref 'key)` is a cheap marker, so only `render`
shells out to sops; manage the store with the `hexol secret` subcommands. See
shells out to sops; manage the store with the `hexol secret` subcommands.
[`examples/secrets.scm`](examples/secrets.scm) is self-contained — it ships a
throwaway age key, so `hexol render -o yaml -i examples/secrets.scm` decrypts
and substitutes real plaintext on a fresh clone. See also
[`examples/homelab.scm`](examples/homelab.scm) and
[`docs/authoring.md`](docs/authoring.md#secrets-inline-sops-backed).

Expand Down Expand Up @@ -137,8 +154,6 @@ live homelab. Kick the tires before you bet a cluster on it.
- [`docs/extending.md`](docs/extending.md) — building target libraries,
the kernel/library/example boundary, worked Terraform and Helm
conversions, and introspection.
- [`docs/cmdb.md`](docs/cmdb.md) — the event-sourced CMDB built on the same
kernel (fact log + versioned libraries + HTTP server).

## License

Expand Down
45 changes: 0 additions & 45 deletions bin/cmdb-server

This file was deleted.

Loading
Loading