Skip to content

Commit 5788fc9

Browse files
committed
rename all Lix references to Nix, remove Lix cache entries and upterm sessions from CI, add ci-debug agent using opencode+DeepSeek V4 Flash for automated K8s triage on CI failure, fix kubenixCI1 aarch64-linux, consolidate CI substituters
ci-debug uses opencodes agentic loop to let DeepSeek V4 Flash run kubectl commands interactively in the CI environment, diagnosing K8s failures with full context. Consolidated CI substituters into kubenix/ci/default.nix so all CI variants share the same three substituters: nix-csi.cachix.org, cache.nixos.org, and nix-serve (10.113.37.1:5000). Nix handles dead/unreachable substituters gracefully, so having the NixOS-test-only nix-serve URL in Kind CI is safe. Removed kubenixCI2Kind. Fixed CI2 substituters overriding shared defaults by moving the nix-serve URL into the shared CI config alongside the public caches. Configured via opencode.json with {env:DS_API} variable substitution so no API keys are stored in the repo.
1 parent 26632d2 commit 5788fc9

22 files changed

Lines changed: 229 additions & 146 deletions

File tree

.github/actions/setup-nix/action.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ runs:
2222
# - Update substituters: https://nix-csi.cachix.org → https://nixkube.cachix.org
2323
# - Recreate/migrate Cachix cache from nix-csi to nixkube
2424
nix_conf: |
25-
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o= nixbuild.net/CHEAKK-1:IvfuR1Ldmkef8pMcSuCl9N2jppEb8KpBzdoB8uKQdxE= nix-csi.cachix.org-1:i4w33gR4efO67jpz8U7g/MdvRQ6mQ3LEF9fB8tES60g=
25+
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nixbuild.net/CHEAKK-1:IvfuR1Ldmkef8pMcSuCl9N2jppEb8KpBzdoB8uKQdxE= nix-csi.cachix.org-1:i4w33gR4efO67jpz8U7g/MdvRQ6mQ3LEF9fB8tES60g=
2626
extra-platforms = aarch64-linux qemu-user
2727
# builders = ssh-ng://eu.nixbuild.net aarch64-linux ; ssh-ng://eu.nixbuild.net x86_64-linux
28-
substituters = https://cache.nixos.org?priority=1 https://nix-csi.cachix.org?priority=2 https://cache.lix.systems?priority=3 ssh-ng://eu.nixbuild.net?priority=4
28+
substituters = https://cache.nixos.org?priority=1 https://nix-csi.cachix.org?priority=2 ssh-ng://eu.nixbuild.net?priority=4
2929
keep-env-derivations = true
3030
keep-outputs = true
3131
- name: Restore and save Nix store

.github/workflows/ci.yaml

Lines changed: 27 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ jobs:
5050
unlink nix-envs || true
5151
nix build --show-trace --file . push --out-link nix-envs
5252
./nix-envs/bin/push
53-
- name: Build and push amd64 lix image
53+
- name: Build and push amd64 nix image
5454
run: |
55-
unlink nix-lix || true
56-
nix build --show-trace --file . lixImage.pushArch.x86_64-linux --out-link nix-lix
57-
./nix-lix/bin/push-lix-x86_64-linux
55+
unlink nix-nix || true
56+
nix build --show-trace --file . nixImage.pushArch.x86_64-linux --out-link nix-nix
57+
./nix-nix/bin/push-nix-x86_64-linux
5858
build-arm64:
5959
runs-on: ubuntu-24.04-arm
6060
steps:
@@ -71,11 +71,11 @@ jobs:
7171
unlink nix-envs || true
7272
nix build --show-trace --file . push --out-link nix-envs
7373
./nix-envs/bin/push
74-
- name: Build and push arm64 lix image
74+
- name: Build and push arm64 nix image
7575
run: |
76-
unlink nix-lix || true
77-
nix build --show-trace --file . lixImage.pushArch.aarch64-linux --out-link nix-lix
78-
./nix-lix/bin/push-lix-aarch64-linux
76+
unlink nix-nix || true
77+
nix build --show-trace --file . nixImage.pushArch.aarch64-linux --out-link nix-nix
78+
./nix-nix/bin/push-nix-aarch64-linux
7979
build-manifests:
8080
needs: [build-amd64, build-arm64]
8181
runs-on: ubuntu-latest
@@ -88,11 +88,11 @@ jobs:
8888
nixbuild_key: ${{ secrets.NIXBUILD_KEY }}
8989
github_token: ${{ secrets.GITHUB_TOKEN }}
9090
cache_key: build-manifests
91-
- name: Create lix multi-arch manifest
91+
- name: Create nix multi-arch manifest
9292
run: |
9393
unlink nix-manifest || true
94-
nix build --show-trace --file . lixImage.pushManifest --out-link nix-manifest
95-
./nix-manifest/bin/push-lix-manifest
94+
nix build --show-trace --file . nixImage.pushManifest --out-link nix-manifest
95+
./nix-manifest/bin/push-nix-manifest
9696
- name: Build and push scratch image
9797
run: |
9898
unlink nix-scratches || true
@@ -122,13 +122,13 @@ jobs:
122122
./result/bin/kubenixDeploy --yes
123123
- name: Wait for nix-csi node daemonset
124124
run: |
125-
kubectl rollout status daemonset -l app.kubernetes.io/component=node -n nixkube --timeout=60s
125+
kubectl rollout status daemonset -l app.kubernetes.io/component=node -n nixkube --timeout=180s
126126
- name: Wait for nix-csi cache pod
127127
run: |
128-
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=cache -n nixkube --timeout=60s
128+
kubectl wait --for=condition=ready pod -l app.kubernetes.io/component=pynixd -n nixkube --timeout=180s
129129
- name: Wait for test workload
130130
run: |
131-
kubectl wait --for=condition=complete job/flake-hello job/expr-hello job/path-hello job/nri-hello-ro job/nri-hello-rw -n nixkube --timeout=120s
131+
kubectl wait --for=condition=complete job/flake-hello job/expr-hello job/path-hello job/nri-hello-ro job/nri-hello-rw -n nixkube --timeout=300s
132132
- name: Validate success events
133133
run: |
134134
echo "=== Checking NixVolumeMount events ==="
@@ -151,7 +151,7 @@ jobs:
151151
- name: Delete jobs and verify CSI cleanup
152152
run: |
153153
kubectl delete job flake-hello expr-hello path-hello invalid-storepath-hello invalid-flake-hello invalid-expr-hello nri-hello-ro nri-hello-rw -n nixkube
154-
kubectl wait --for=delete pod -l "job-name in (flake-hello,expr-hello,path-hello,invalid-storepath-hello,invalid-flake-hello,invalid-expr-hello,nri-hello-ro,nri-hello-rw)" -n nixkube --timeout=60s
154+
kubectl wait --for=delete pod -l "job-name in (flake-hello,expr-hello,path-hello,invalid-storepath-hello,invalid-flake-hello,invalid-expr-hello,nri-hello-ro,nri-hello-rw)" -n nixkube --timeout=120s
155155
- name: Validate error events
156156
run: |
157157
echo "=== Checking error events ==="
@@ -171,45 +171,12 @@ jobs:
171171
- name: Print node logs
172172
run: |
173173
echo "=== Node pod logs ==="
174-
kubectl logs -l app.kubernetes.io/component=node -n nixkube --tail -1
175-
- name: Cluster state all
176-
if: failure()
177-
run: |
178-
echo "=== Cluster state all ==="
179-
kubectl get all -A || true
180-
- name: Cluster state configmaps
181-
if: failure()
182-
run: |
183-
echo "=== Cluster configmaps ==="
184-
kubectl get configmaps -A || true
185-
- name: Cluster state secrets
186-
if: failure()
187-
run: |
188-
kubectl get secrets -A || true
189-
- name: Cache
190-
if: failure()
191-
run: |
192-
kubectl logs -l app.kubernetes.io/component=cache -n nixkube --tail -1 || true
193-
kubectl describe pod -l app.kubernetes.io/component=cache -n nixkube || true
194-
- name: Node
195-
if: failure()
196-
run: |
197-
kubectl logs -l app.kubernetes.io/component=node -n nixkube --tail -1 || true
198-
kubectl describe pod -l app.kubernetes.io/component=node -n nixkube || true
199-
- name: Init
200-
if: failure()
201-
run: |
202-
kubectl logs -l app.kubernetes.io/component=init -n nixkube --tail -1 || true
203-
- name: Events
204-
if: failure()
205-
run: |
206-
kubectl get events -n nixkube --sort-by='.lastTimestamp'
207-
- name: Troubleshoot with upterm
174+
kubectl logs -l app.kubernetes.io/component=node -n nixkube --tail=50 --timestamps
175+
- name: Debug on failure
208176
if: failure()
209-
uses: owenthereal/action-upterm@main
210-
with:
211-
limit-access-to-actor: true
212-
wait-timeout-minutes: 5
177+
env:
178+
DS_API: ${{ secrets.DS_API }}
179+
run: nix run --file . ci-debug || true
213180
test-kind-nocache:
214181
needs: build-manifests
215182
runs-on: ubuntu-latest
@@ -233,41 +200,23 @@ jobs:
233200
./result/bin/kubenixDeploy --yes
234201
- name: Wait for nix-csi node daemonset
235202
run: |
236-
kubectl rollout status daemonset -l app.kubernetes.io/component=node -n nixkube --timeout=60s
203+
kubectl rollout status daemonset -l app.kubernetes.io/component=node -n nixkube --timeout=180s
237204
- name: Wait for test workload
238205
run: |
239-
kubectl wait --for=condition=complete job/flake-hello job/expr-hello job/path-hello job/nri-hello-ro job/nri-hello-rw -n nixkube --timeout=120s
206+
kubectl wait --for=condition=complete job/flake-hello job/expr-hello job/path-hello job/nri-hello-ro job/nri-hello-rw -n nixkube --timeout=300s
240207
- name: Delete jobs and verify CSI cleanup
241208
run: |
242209
kubectl delete job flake-hello expr-hello path-hello nri-hello-ro nri-hello-rw -n nixkube
243-
kubectl wait --for=delete pod -l "job-name in (flake-hello,expr-hello,path-hello,nri-hello-ro,nri-hello-rw)" -n nixkube --timeout=60s
210+
kubectl wait --for=delete pod -l "job-name in (flake-hello,expr-hello,path-hello,nri-hello-ro,nri-hello-rw)" -n nixkube --timeout=120s
244211
- name: Print node logs
245212
run: |
246213
echo "=== Node pod logs ==="
247-
kubectl logs -l app.kubernetes.io/component=node -n nixkube --tail -1
214+
kubectl logs -l app.kubernetes.io/component=node -n nixkube --tail=50 --timestamps
248215
- name: Debug on failure
249216
if: failure()
250-
run: |
251-
echo "=== Cluster state ==="
252-
kubectl get all -A
253-
254-
echo "=== Cache pod logs ==="
255-
kubectl logs -l app.kubernetes.io/name=cache -n nixkube --tail -1 || true
256-
257-
echo "=== Node pod logs ==="
258-
kubectl logs -l app.kubernetes.io/component=node -n nixkube --tail -1 || true
259-
260-
echo "=== Init pod logs ==="
261-
kubectl logs -l app.kubernetes.io/component=init -n nixkube --tail -1 || true
262-
263-
echo "=== Events ==="
264-
kubectl get events -n nixkube --sort-by='.lastTimestamp'
265-
- name: Troubleshoot with upterm
266-
if: failure()
267-
uses: owenthereal/action-upterm@main
268-
with:
269-
limit-access-to-actor: true
270-
wait-timeout-minutes: 5
217+
env:
218+
DS_API: ${{ secrets.DS_API }}
219+
run: nix run --file . ci-debug || true
271220
release:
272221
needs: [check, build-manifests, test-kind-cache, test-kind-nocache]
273222
runs-on: ubuntu-latest

.github/workflows/test-nixos.yaml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ jobs:
2222
nix_conf: |
2323
experimental-features = nix-command flakes
2424
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
25-
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o= nixbuild.net/CHEAKK-1:IvfuR1Ldmkef8pMcSuCl9N2jppEb8KpBzdoB8uKQdxE= nix-csi.cachix.org-1:i4w33gR4efO67jpz8U7g/MdvRQ6mQ3LEF9fB8tES60g=
25+
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nixbuild.net/CHEAKK-1:IvfuR1Ldmkef8pMcSuCl9N2jppEb8KpBzdoB8uKQdxE= nix-csi.cachix.org-1:i4w33gR4efO67jpz8U7g/MdvRQ6mQ3LEF9fB8tES60g=
2626
# builders = ssh-ng://eu.nixbuild.net aarch64-linux ; ssh-ng://eu.nixbuild.net x86_64-linux
27-
substituters = https://cache.nixos.org?priority=1 https://nix-csi.cachix.org?priority=2 https://cache.lix.systems?priority=3 ssh-ng://eu.nixbuild.net?priority=4
27+
substituters = https://cache.nixos.org?priority=1 https://nix-csi.cachix.org?priority=2 ssh-ng://eu.nixbuild.net?priority=4
2828
sandbox = relaxed
2929
- name: Configure SSH Keys
3030
shell: bash
@@ -44,8 +44,10 @@ jobs:
4444
echo $! > /tmp/test.pid
4545
echo "Test running in background (PID: $(cat /tmp/test.pid))"
4646
sleep 5
47-
- name: Setup upterm session (test runs in parallel)
48-
uses: owenthereal/action-upterm@v1
49-
with:
50-
wait-timeout-minutes: 5
51-
limit-access-to-actor: true
47+
- name: Print test logs
48+
run: |
49+
cat /tmp/test.log || true
50+
- name: Print test results
51+
run: |
52+
echo "=== Test log output ==="
53+
cat /tmp/test.log 2>/dev/null || echo "(no test log)"

CLAUDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ The integration test (runs in CI via `.github/workflows/integration-test.yaml`):
116116
- Confirms cache and node pods are operational
117117

118118
**Build job** (runs once, pushes to cachix and container registry):
119-
1. Builds and pushes Lix image
119+
1. Builds and pushes Nix image
120120
2. Builds and pushes cache/node environments
121121
3. Builds and pushes scratch image
122122

@@ -202,7 +202,7 @@ The `config-reconciler` service runs continuously to sync SSH keys and Nix confi
202202
- `kubenix/builder.nix`: Optional builder pods for distributed builds
203203
- `pkgs/nixkube/src/csi/server.py`: CSI driver gRPC server
204204
- `pkgs/nixkube/src/nri/server.py`: NRI plugin ttrpc handler
205-
- `liximage.nix`: Builds the Lix container used by initContainers
205+
- `niximage.nix`: Builds the Nix container used by initContainers
206206

207207
## Code Review Standards
208208

default.nix

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ in
2121
rec {
2222
pkgs = import inputs.nixpkgs {
2323
inherit system;
24+
config = {
25+
allowUnfree = true;
26+
};
2427
overlays = [ (import ./pkgs) ];
2528
};
2629
inherit inputs;
@@ -32,30 +35,41 @@ rec {
3235
kubenixCI1 = kubenixInstance {
3336
module.imports = [
3437
./kubenix/ci
38+
{
39+
nixkube.systems = {
40+
x86_64-linux = true;
41+
aarch64-linux = false;
42+
};
43+
}
3544
];
3645
};
3746
# kubenixCI2 is used by tests/nixos/integration.nix for the containerd nixos test.
3847
# Disables aarch64-linux to avoid needing cross-compilation support.
3948
kubenixCI2 = kubenixInstance {
4049
module.imports = [
4150
./kubenix/ci
42-
{
43-
nixkube.pynixd.enable = false;
44-
# push = true retains Nix string context on DaemonSet store paths so
45-
# they become part of the manifest's closure. The NixOS test VM then
46-
# has every path in /nix/store, where nix-serve makes them available
47-
# as a substituter for nixkube's separate /var/lib/nix-csi store.
48-
nixkube.push = true;
49-
nixkube.systems = {
50-
x86_64-linux = true;
51-
aarch64-linux = false;
52-
};
53-
# 10.113.37.1 is the PTP CNI gateway — the host-side veth IP reachable
54-
# from all pods. nix-serve runs there during the NixOS test.
55-
nixkube.node.nixConfig.settings.substituters = [
56-
"http://10.113.37.1:5000?trusted=1"
57-
];
58-
}
51+
(
52+
{ config, pkgs, ... }:
53+
{
54+
kluctl.preDeployScript = # bash
55+
''
56+
export PATH=${lib.makeBinPath [ pkgs.cachix ]}:$PATH
57+
cachix push nix-csi ${config.internal.manifestJSONFile}
58+
'';
59+
nixkube.pynixd.enable = false;
60+
# push = true retains Nix string context on DaemonSet store paths so
61+
# they become part of the manifest's closure. The NixOS test VM then
62+
# has every path in /nix/store, where nix-serve makes them available
63+
# as a substituter for nixkube's separate /var/lib/nix-csi store.
64+
nixkube.push = true;
65+
nixkube.systems = {
66+
x86_64-linux = true;
67+
aarch64-linux = false;
68+
};
69+
# 10.113.37.1 is the PTP CNI gateway — the host-side veth IP reachable
70+
# from all pods. nix-serve runs there during the NixOS test.
71+
}
72+
)
5973
];
6074
};
6175
kubenixLocal = kubenixInstance {
@@ -225,6 +239,7 @@ rec {
225239
programs.yamlfmt.enable = true;
226240
};
227241

228-
lixImage = pkgs.callPackage ./liximage.nix { };
242+
nixImage = pkgs.callPackage ./niximage.nix { };
229243
scratchImage = pkgs.callPackage ./scratchimage.nix { };
244+
ci-debug = pkgs.callPackage ./pkgs/ci-debug { };
230245
}

demo/flake.nix

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
outputs = inputs: {
77
packages.x86_64-linux.manifest =
88
(inputs.easykubenix.lib.easykubenix {
9-
pkgs = import inputs.nixpkgs { system = "x86_64-linux"; };
9+
pkgs = import inputs.nixpkgs {
10+
system = "x86_64-linux";
11+
config = {
12+
allowUnfree = true;
13+
};
14+
};
1015
modules = [
1116
(
1217
{ pkgs, lib, ... }:

demo/pod.nix

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,18 @@ let
88
"x86_64-linux" = "aarch64-linux";
99
"aarch64-linux" = "x86_64-linux";
1010
};
11-
pkgs = import inputs.nixpkgs { inherit system; };
12-
pkgsCross = import pkgs.path { system = sysMap.${system}; };
11+
pkgs = import inputs.nixpkgs {
12+
inherit system;
13+
config = {
14+
allowUnfree = true;
15+
};
16+
};
17+
pkgsCross = import pkgs.path {
18+
system = sysMap.${system};
19+
config = {
20+
allowUnfree = true;
21+
};
22+
};
1323

1424
package =
1525
pkgs:
@@ -20,7 +30,7 @@ let
2030
pkgs.fishMinimal
2131
pkgs.coreutils
2232
pkgs.moreutils
23-
pkgs.lix
33+
pkgs.nix
2434
];
2535
};
2636

environments/cache/default.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: MIT
22

3-
# Cache uses lruLix which is Lix patched to keep storePaths registrationTime up2date when they're referenced
3+
# Cache uses a patched Nix to keep storePaths registrationTime up2date when they're referenced
44
# through the Daemon protocol
55
{
66
pkgs,

environments/modules/gc.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
command = pkgs.writeShellApplication {
2424
name = "gc";
2525
runtimeInputs = [
26-
pkgs.lruLix
26+
pkgs.nix
2727
pkgs.jq
2828
];
2929
text =

environments/modules/nix-daemon.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
{
99
config = {
1010
services.nix-daemon = {
11-
command = "${lib.getExe pkgs.lruLix} daemon --store local";
11+
command = "${lib.getExe pkgs.nix} daemon --store local";
1212
depends-on = [ "setup" ];
1313
log-type = "file";
1414
logfile = "/var/log/nix-daemon.log";

0 commit comments

Comments
 (0)