Compare commits

...

43 Commits

Author SHA1 Message Date
9a05d2a072 Drop macOS-specific remote-program param from nix copy command 2025-11-04 01:53:58 +08:00
clan-bot
62b64c3b3e Merge pull request 'Update nixpkgs-dev in devFlake' (#5728) from update-devFlake-nixpkgs-dev into main 2025-11-03 15:07:53 +00:00
clan-bot
19a1ad6081 Update nixpkgs-dev in devFlake 2025-11-03 15:01:50 +00:00
Kenji Berthold
a2df5db3d6 Merge pull request 'docs/testing: Document requirements for our container testing system' (#5693) from ke-docs-testing-container into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5693
2025-11-03 13:13:53 +00:00
Kenji Berthold
ac46f890ea Merge branch 'main' into ke-docs-testing-container 2025-11-03 13:06:14 +00:00
clan-bot
19abf8d288 Merge pull request 'Update nixpkgs-dev in devFlake' (#5726) from update-devFlake-nixpkgs-dev into main 2025-11-03 10:06:31 +00:00
clan-bot
e5105e31c4 Update nixpkgs-dev in devFlake 2025-11-03 10:01:47 +00:00
clan-bot
0f847b4799 Merge pull request 'Update nixpkgs-dev in devFlake' (#5724) from update-devFlake-nixpkgs-dev into main 2025-11-02 20:06:24 +00:00
clan-bot
40a8a823b8 Update nixpkgs-dev in devFlake 2025-11-02 20:01:50 +00:00
Mic92
e3adb3fc71 Merge pull request 'Fix vars upload for public vars with neededFor activation/partitioning' (#5723) from vars into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5723
2025-11-02 16:00:13 +00:00
Jörg Thalheim
a569a1d147 Fix vars upload for public vars with neededFor activation/partitioning
When vars are marked with neededFor="activation" or "partitioning", they
need to be available early in the boot process. However, the populate_dir
methods in both sops and password_store secret backends were only calling
self.get() which only retrieves secret vars from the .../secret path.

This caused public vars (stored at .../value) to fail with "Secret does
not exist" errors when trying to upload them.

The fix uses file.value property instead, which properly delegates to the
correct store (SecretStore or FactStore) based on whether the file is
marked as secret or public.

Fixes affected all neededFor phases in both backends:
- sops: activation and partitioning phases
- password_store: activation and partitioning phases
2025-11-02 16:49:49 +01:00
Mic92
64718b77ca Merge pull request 'readme fix' (#5722) from i18n/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5722
2025-11-02 15:49:16 +00:00
i18n
7b34c39736 Merge pull request '更新 docs/site/getting-started/creating-your-first-clan.md' (#1) from i18n-patch-1 into main
Reviewed-on: https://git.clan.lol/i18n/clan-core/pulls/1
2025-11-02 13:24:05 +00:00
i18n
4d6ab60793 更新 docs/site/getting-started/creating-your-first-clan.md 2025-11-02 13:23:04 +00:00
clan-bot
35bffee544 Merge pull request 'Update nixpkgs-dev in devFlake' (#5721) from update-devFlake-nixpkgs-dev into main 2025-11-02 10:05:51 +00:00
clan-bot
16917fd79b Update nixpkgs-dev in devFlake 2025-11-02 10:01:50 +00:00
clan-bot
895c116c01 Merge pull request 'Update nix-darwin' (#5720) from update-nix-darwin into main 2025-11-02 05:06:00 +00:00
clan-bot
e67151f7b9 Merge pull request 'Update flake-parts' (#5719) from update-flake-parts into main 2025-11-02 05:05:06 +00:00
clan-bot
8d26ec1760 Update nix-darwin 2025-11-02 05:01:04 +00:00
clan-bot
7a9062b629 Update flake-parts 2025-11-02 05:01:01 +00:00
clan-bot
de07454a0a Merge pull request 'Update nix-darwin' (#5718) from update-nix-darwin into main 2025-11-01 20:06:16 +00:00
clan-bot
6fe60f61cf Update nix-darwin 2025-11-01 20:00:58 +00:00
clan-bot
3fa74847e4 Merge pull request 'Update nixpkgs-dev in devFlake' (#5716) from update-devFlake-nixpkgs-dev into main 2025-11-01 15:06:01 +00:00
clan-bot
fc37140b52 Update nixpkgs-dev in devFlake 2025-11-01 15:01:52 +00:00
hsjobeki
83406c61f3 Merge pull request 'services: update hello-world readme and tests' (#5714) from update-docs into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5714
2025-11-01 11:37:39 +00:00
hsjobeki
6d736e7e80 Merge pull request 'docs: update experimental notes as planned in release-notes' (#5715) from ex-docs into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5715
2025-11-01 11:35:29 +00:00
Johannes Kirschbauer
7b6cec4100 services: update hello-world readme and tests 2025-11-01 12:33:15 +01:00
Johannes Kirschbauer
e21a6516b5 docs: update experimental notes as planned in release-notes 2025-11-01 12:30:01 +01:00
Mic92
6ffe8ea5f6 Merge pull request 'treewide: replace pkgs.hostPlatform with pkgs.stdenv.hostPlatform' (#5713) from fix-eval into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5713
2025-10-31 17:57:38 +00:00
Jörg Thalheim
0a2fefd141 treewide: replace pkgs.hostPlatform with pkgs.stdenv.hostPlatform
nixpkgs now throws an error for this, the other variant in stdenv also
exists in the previous release
2025-10-31 18:52:31 +01:00
Luis Hebendanz
0c885d05b6 Merge pull request 'clan_lib/flake: Improve select error message' (#5711) from Qubasa/clan-core:improve_clan_select_error_message into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5711
2025-10-31 15:11:29 +00:00
Qubasa
58d85b117a clan_lib/flake: Improve select error message 2025-10-31 16:05:54 +01:00
clan-bot
ad58d7b6e9 Merge pull request 'Update nixpkgs-dev in devFlake' (#5710) from update-devFlake-nixpkgs-dev into main 2025-10-31 15:05:13 +00:00
clan-bot
7a63cb9642 Update nixpkgs-dev in devFlake 2025-10-31 15:01:50 +00:00
clan-bot
196b98da36 Merge pull request 'Update disko' (#5707) from update-disko into main 2025-10-31 10:10:34 +00:00
clan-bot
42acbe95b8 Update disko 2025-10-31 10:00:58 +00:00
clan-bot
b6b065e365 Merge pull request 'Update nixpkgs-dev in devFlake' (#5706) from update-devFlake-nixpkgs-dev into main 2025-10-31 00:08:41 +00:00
clan-bot
4b1955b189 Update nixpkgs-dev in devFlake 2025-10-31 00:02:00 +00:00
clan-bot
ef7ef8b843 Merge pull request 'Update nixpkgs-dev in devFlake' (#5704) from update-devFlake-nixpkgs-dev into main 2025-10-30 20:05:49 +00:00
clan-bot
38c1367322 Update nixpkgs-dev in devFlake 2025-10-30 20:01:49 +00:00
clan-bot
8e72c086fd Merge pull request 'Update nixpkgs-dev in devFlake' (#5702) from update-devFlake-nixpkgs-dev into main 2025-10-30 15:06:22 +00:00
clan-bot
c454b1339d Update nixpkgs-dev in devFlake 2025-10-30 15:01:51 +00:00
a-kenji
bc290fe59f docs/testing: Document requirements for our container testing system
Document the requirements for our container testing system:
- uid-range
- auto-allocate-uids

Further document that the container tests are used by default and how to
switch to the more traditional and more supported / featureful VM
testing framework.
2025-10-29 13:47:26 +01:00
25 changed files with 247 additions and 104 deletions

View File

@@ -58,51 +58,53 @@
pkgs.buildPackages.xorg.lndir
pkgs.glibcLocales
pkgs.kbd.out
self.nixosConfigurations."test-flash-machine-${pkgs.hostPlatform.system}".pkgs.perlPackages.ConfigIniFiles
self.nixosConfigurations."test-flash-machine-${pkgs.hostPlatform.system}".pkgs.perlPackages.FileSlurp
self.nixosConfigurations."test-flash-machine-${pkgs.stdenv.hostPlatform.system}".pkgs.perlPackages.ConfigIniFiles
self.nixosConfigurations."test-flash-machine-${pkgs.stdenv.hostPlatform.system}".pkgs.perlPackages.FileSlurp
pkgs.bubblewrap
self.nixosConfigurations."test-flash-machine-${pkgs.hostPlatform.system}".config.system.build.toplevel
self.nixosConfigurations."test-flash-machine-${pkgs.hostPlatform.system}".config.system.build.diskoScript
self.nixosConfigurations."test-flash-machine-${pkgs.hostPlatform.system}".config.system.build.diskoScript.drvPath
self.nixosConfigurations."test-flash-machine-${pkgs.stdenv.hostPlatform.system}".config.system.build.toplevel
self.nixosConfigurations."test-flash-machine-${pkgs.stdenv.hostPlatform.system}".config.system.build.diskoScript
self.nixosConfigurations."test-flash-machine-${pkgs.stdenv.hostPlatform.system}".config.system.build.diskoScript.drvPath
]
++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
in
{
# Skip flash test on aarch64-linux for now as it's too slow
checks = lib.optionalAttrs (pkgs.stdenv.isLinux && pkgs.hostPlatform.system != "aarch64-linux") {
nixos-test-flash = self.clanLib.test.baseTest {
name = "flash";
nodes.target = {
virtualisation.emptyDiskImages = [ 4096 ];
virtualisation.memorySize = 4096;
checks =
lib.optionalAttrs (pkgs.stdenv.isLinux && pkgs.stdenv.hostPlatform.system != "aarch64-linux")
{
nixos-test-flash = self.clanLib.test.baseTest {
name = "flash";
nodes.target = {
virtualisation.emptyDiskImages = [ 4096 ];
virtualisation.memorySize = 4096;
virtualisation.useNixStoreImage = true;
virtualisation.writableStore = true;
virtualisation.useNixStoreImage = true;
virtualisation.writableStore = true;
environment.systemPackages = [ self.packages.${pkgs.system}.clan-cli ];
environment.etc."install-closure".source = "${closureInfo}/store-paths";
environment.systemPackages = [ self.packages.${pkgs.system}.clan-cli ];
environment.etc."install-closure".source = "${closureInfo}/store-paths";
nix.settings = {
substituters = lib.mkForce [ ];
hashed-mirrors = null;
connect-timeout = lib.mkForce 3;
flake-registry = "";
experimental-features = [
"nix-command"
"flakes"
];
};
nix.settings = {
substituters = lib.mkForce [ ];
hashed-mirrors = null;
connect-timeout = lib.mkForce 3;
flake-registry = "";
experimental-features = [
"nix-command"
"flakes"
];
};
};
testScript = ''
start_all()
machine.succeed("echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRWUusawhlIorx7VFeQJHmMkhl9X3QpnvOdhnV/bQNG root@target' > ./test_id_ed25519.pub")
# Some distros like to automount disks with spaces
machine.succeed('mkdir -p "/mnt/with spaces" && mkfs.ext4 /dev/vdc && mount /dev/vdc "/mnt/with spaces"')
machine.succeed("clan flash write --ssh-pubkey ./test_id_ed25519.pub --keymap de --language de_DE.UTF-8 --debug --flake ${self.checks.x86_64-linux.clan-core-for-checks} --yes --disk main /dev/vdc test-flash-machine-${pkgs.stdenv.hostPlatform.system}")
'';
} { inherit pkgs self; };
};
testScript = ''
start_all()
machine.succeed("echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIRWUusawhlIorx7VFeQJHmMkhl9X3QpnvOdhnV/bQNG root@target' > ./test_id_ed25519.pub")
# Some distros like to automount disks with spaces
machine.succeed('mkdir -p "/mnt/with spaces" && mkfs.ext4 /dev/vdc && mount /dev/vdc "/mnt/with spaces"')
machine.succeed("clan flash write --ssh-pubkey ./test_id_ed25519.pub --keymap de --language de_DE.UTF-8 --debug --flake ${self.checks.x86_64-linux.clan-core-for-checks} --yes --disk main /dev/vdc test-flash-machine-${pkgs.hostPlatform.system}")
'';
} { inherit pkgs self; };
};
};
}

View File

@@ -160,9 +160,9 @@
closureInfo = pkgs.closureInfo {
rootPaths = [
privateInputs.clan-core-for-checks
self.nixosConfigurations."test-install-machine-${pkgs.hostPlatform.system}".config.system.build.toplevel
self.nixosConfigurations."test-install-machine-${pkgs.hostPlatform.system}".config.system.build.initialRamdisk
self.nixosConfigurations."test-install-machine-${pkgs.hostPlatform.system}".config.system.build.diskoScript
self.nixosConfigurations."test-install-machine-${pkgs.stdenv.hostPlatform.system}".config.system.build.toplevel
self.nixosConfigurations."test-install-machine-${pkgs.stdenv.hostPlatform.system}".config.system.build.initialRamdisk
self.nixosConfigurations."test-install-machine-${pkgs.stdenv.hostPlatform.system}".config.system.build.diskoScript
pkgs.stdenv.drvPath
pkgs.bash.drvPath
pkgs.buildPackages.xorg.lndir
@@ -215,7 +215,7 @@
# Prepare test flake and Nix store
flake_dir = prepare_test_flake(
temp_dir,
"${self.checks.${pkgs.hostPlatform.system}.clan-core-for-checks}",
"${self.checks.${pkgs.stdenv.hostPlatform.system}.clan-core-for-checks}",
"${closureInfo}"
)
@@ -296,7 +296,7 @@
# Prepare test flake and Nix store
flake_dir = prepare_test_flake(
temp_dir,
"${self.checks.${pkgs.hostPlatform.system}.clan-core-for-checks}",
"${self.checks.${pkgs.stdenv.hostPlatform.system}.clan-core-for-checks}",
"${closureInfo}"
)

View File

@@ -2,7 +2,7 @@
let
cli = self.packages.${pkgs.hostPlatform.system}.clan-cli-full;
cli = self.packages.${pkgs.stdenv.hostPlatform.system}.clan-cli-full;
ollama-model = pkgs.callPackage ./qwen3-4b-instruct.nix { };
in
@@ -53,7 +53,7 @@ in
pytest
pytest-xdist
(cli.pythonRuntime.pkgs.toPythonModule cli)
self.legacyPackages.${pkgs.hostPlatform.system}.nixosTestLib
self.legacyPackages.${pkgs.stdenv.hostPlatform.system}.nixosTestLib
]
))
];

View File

@@ -2,7 +2,7 @@
let
cli = self.packages.${pkgs.hostPlatform.system}.clan-cli-full;
cli = self.packages.${pkgs.stdenv.hostPlatform.system}.clan-cli-full;
in
{
name = "systemd-abstraction";

View File

@@ -115,9 +115,9 @@
let
closureInfo = pkgs.closureInfo {
rootPaths = [
self.packages.${pkgs.hostPlatform.system}.clan-cli
self.checks.${pkgs.hostPlatform.system}.clan-core-for-checks
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-update-machine.config.system.build.toplevel
self.packages.${pkgs.stdenv.hostPlatform.system}.clan-cli
self.checks.${pkgs.stdenv.hostPlatform.system}.clan-core-for-checks
self.clanInternals.machines.${pkgs.stdenv.hostPlatform.system}.test-update-machine.config.system.build.toplevel
pkgs.stdenv.drvPath
pkgs.bash.drvPath
pkgs.buildPackages.xorg.lndir
@@ -132,7 +132,7 @@
imports = [ self.nixosModules.test-update-machine ];
};
extraPythonPackages = _p: [
self.legacyPackages.${pkgs.hostPlatform.system}.nixosTestLib
self.legacyPackages.${pkgs.stdenv.hostPlatform.system}.nixosTestLib
];
testScript = ''
@@ -154,7 +154,7 @@
# Prepare test flake and Nix store
flake_dir = prepare_test_flake(
temp_dir,
"${self.checks.${pkgs.hostPlatform.system}.clan-core-for-checks}",
"${self.checks.${pkgs.stdenv.hostPlatform.system}.clan-core-for-checks}",
"${closureInfo}"
)
(flake_dir / ".clan-flake").write_text("") # Ensure .clan-flake exists
@@ -226,7 +226,7 @@
"--to",
"ssh://root@192.168.1.1",
"--no-check-sigs",
f"${self.packages.${pkgs.hostPlatform.system}.clan-cli}",
f"${self.packages.${pkgs.stdenv.hostPlatform.system}.clan-cli}",
"--extra-experimental-features", "nix-command flakes",
],
check=True,
@@ -242,7 +242,7 @@
"-o", "UserKnownHostsFile=/dev/null",
"-o", "StrictHostKeyChecking=no",
f"root@192.168.1.1",
"${self.packages.${pkgs.hostPlatform.system}.clan-cli}/bin/clan",
"${self.packages.${pkgs.stdenv.hostPlatform.system}.clan-cli}/bin/clan",
"machines",
"update",
"--debug",
@@ -270,7 +270,7 @@
# Run clan update command
subprocess.run([
"${self.packages.${pkgs.hostPlatform.system}.clan-cli-full}/bin/clan",
"${self.packages.${pkgs.stdenv.hostPlatform.system}.clan-cli-full}/bin/clan",
"machines",
"update",
"--debug",
@@ -297,7 +297,7 @@
# Run clan update command with --build-host
subprocess.run([
"${self.packages.${pkgs.hostPlatform.system}.clan-cli-full}/bin/clan",
"${self.packages.${pkgs.stdenv.hostPlatform.system}.clan-cli-full}/bin/clan",
"machines",
"update",
"--debug",

View File

@@ -1,3 +1,6 @@
!!! Danger "Experimental"
This service is experimental and will change in the future.
This service sets up a certificate authority (CA) that can issue certificates to
other machines in your clan. For this the `ca` role is used.
It additionally provides a `default` role, that can be applied to all machines

View File

@@ -1,3 +1,6 @@
!!! Danger "Experimental"
This service is experimental and will change in the future.
This module enables hosting clan-internal services easily, which can be resolved
inside your VPN. This allows defining a custom top-level domain (e.g. `.clan`)
and exposing endpoints from a machine to others, which will be

View File

@@ -1 +1,83 @@
This a test README just to appease the eval warnings if we don't have one
!!! Danger "Experimental"
This service is for demonstration purpose only and may change in the future.
The Hello-World Clan Service is a minimal example showing how to build and register your own service.
It serves as a reference implementation and is used in clan-core CI tests to ensure compatibility.
## What it demonstrates
- How to define a basic Clan-compatible service.
- How to structure your service for discovery and configuration.
- How Clan services interact with nixos.
## Testing
This service demonstrates two levels of testing to ensure quality and stability across releases:
1. **Unit & Integration Testing** — via [`nix-unit`](https://github.com/nix-community/nix-unit)
2. **End-to-End Testing** — via **NixOS VM tests**, which we extended to support **container virtualization** for better performance.
We highly advocate following the [Practical Testing Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html):
* Write **unit tests** for core logic and invariants.
* Add **one or two end-to-end (E2E)** tests to confirm your service starts and behaves correctly in a real NixOS environment.
NixOS is **untyped** and frequently changes; tests are the safest way to ensure long-term stability of services.
```
/ \
/ \
/ E2E \
/-------\
/ \
/Integration\
/-------------\
/ \
/ Unit Tests \
-------------------
```
### nix-unit
We highly advocate the usage of
[nix-unit](https://github.com/nix-community/nix-unit)
Example in: tests/eval-tests.nix
If you use flake-parts you can use the [native integration](https://flake.parts/options/nix-unit.html)
If nix-unit succeeds you'r nixos evaluation should be mostly correct.
!!! Tip
- Ensure most used 'settings' and variants are tested.
- Think about some important edge-cases your system should handle.
### NixOS VM / Container Test
!!! Warning "Early Vars & clanTest"
The testing system around vars is experimental
`clanTest` is still experimental and enables container virtualization by default.
This is still early and might have some limitations.
Some minimal boilerplate is needed to use `clanTest`
```nix
nixosLib = import (inputs.nixpkgs + "/nixos/lib") { }
nixosLib.runTest (
{ ... }:
{
imports = [
self.modules.nixosTest.clanTest
# Example in tests/vm/default.nix
testModule
];
hostPkgs = pkgs;
# Uncomment if you don't want or cannot use containers
# test.useContainers = false;
}
)
```

View File

@@ -8,7 +8,7 @@
{
_class = "clan.service";
manifest.name = "clan-core/hello-word";
manifest.description = "This is a test";
manifest.description = "Minimal example clan service that greets the world";
manifest.readme = builtins.readFile ./README.md;
# This service provides two roles: "morning" and "evening". Roles can be

View File

@@ -26,7 +26,7 @@ in
# The hello-world service being tested
../../clanServices/hello-world
# Required modules
../../nixosModules/clanCore
../../nixosModules
];
testName = "hello-world";
tests = ./tests/eval-tests.nix;

View File

@@ -4,7 +4,7 @@
...
}:
let
testFlake = clanLib.clan {
testClan = clanLib.clan {
self = { };
# Point to the folder of the module
# TODO: make this optional
@@ -33,10 +33,20 @@ let
};
in
{
test_simple = {
config = testFlake.config;
/**
We highly advocate the usage of:
https://github.com/nix-community/nix-unit
expr = { };
expected = { };
If you use flake-parts you can use the native integration: https://flake.parts/options/nix-unit.html
*/
test_simple = {
# Allows inspection via the nix-repl
# Ignored by nix-unit; it only looks at 'expr' and 'expected'
inherit testClan;
# Assert that jon has the
# configured greeting in 'environment.etc.hello.text'
expr = testClan.config.nixosConfigurations.jon.config.environment.etc."hello".text;
expected = "Good evening World!";
};
}

View File

@@ -1,8 +1,5 @@
🚧🚧🚧 Experimental 🚧🚧🚧
Use at your own risk.
We are still refining its interfaces, instability and breakages are expected.
!!! Danger "Experimental"
This service is experimental and will change in the future.
---

View File

@@ -1,3 +1,6 @@
!!! Danger "Experimental"
This service is experimental and will change in the future.
## Usage
```

View File

@@ -1,8 +1,5 @@
🚧🚧🚧 Experimental 🚧🚧🚧
Use at your own risk.
We are still refining its interfaces, instability and breakages are expected.
!!! Danger "Experimental"
This service is experimental and will change in the future.
---

View File

@@ -1,12 +1,9 @@
🚧🚧🚧 Experimental 🚧🚧🚧
Use at your own risk.
We are still refining its interfaces, instability and breakages are expected.
!!! Danger "Experimental"
This service is experimental and will change in the future.
---
This module sets up [yggdrasil](https://yggdrasil-network.github.io/) across your clan.
This module sets up [yggdrasil](https://yggdrasil-network.github.io/) across your clan.
Yggdrasil is designed to be a future-proof and decentralised alternative to the
structured routing protocols commonly used today on the internet. Inside your

6
devFlake/flake.lock generated
View File

@@ -105,11 +105,11 @@
},
"nixpkgs-dev": {
"locked": {
"lastModified": 1761748483,
"narHash": "sha256-v7fttCB5lJ22Ok7+N7ZbLhDeM89QIz9YWtQP4XN7xgA=",
"lastModified": 1762168314,
"narHash": "sha256-+DX6mIF47gRGoK0mqkTg1Jmcjcup0CAXJFHVkdUx8YA=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "061c55856b29b8b9360e14231a0986c7f85f1130",
"rev": "94fc102d2c15d9c1a861e59de550807c65358e1b",
"type": "github"
},
"original": {

View File

@@ -51,7 +51,7 @@ Make sure you have the following:
**Note:** This creates a new directory in your current location
```shellSession
nix run https://git.clan.lol/clan/clan-core/archive/main.tar.gz#clan-cli --refresh -- flakes create
nix run "https://git.clan.lol/clan/clan-core/archive/main.tar.gz#clan-cli" --refresh -- flakes create
```
3. Enter a **name** in the prompt:

View File

@@ -150,10 +150,61 @@ Those are very similar to NixOS VM tests, as in they run virtualized nixos machi
As of now the container test driver is a downstream development in clan-core.
Basically everything stated under the NixOS VM tests sections applies here, except some limitations.
Limitations:
### Using Container Tests vs VM Tests
- Cannot run in interactive mode, however while the container test runs, it logs a nsenter command that can be used to log into each of the container.
- setuid binaries don't work
Container tests are **enabled by default** for all tests using the clan testing framework.
They offer significant performance advantages over VM tests:
- **Faster startup**
- **Lower resource usage**: No full kernel boot or hardware emulation overhead
To control whether a test uses containers or VMs, use the `clan.test.useContainers` option:
```nix
{
clan = {
directory = ./.;
test.useContainers = true; # Use containers (default)
# test.useContainers = false; # Use VMs instead
};
}
```
**When to use VM tests instead of container tests:**
- Testing kernel features, modules, or boot processes
- Testing hardware-specific features
- When you need full system isolation
### System Requirements for Container Tests
Container tests require the **`uid-range`** system feature** in the Nix sandbox.
This feature allows Nix to allocate a range of UIDs for containers to use, enabling `systemd-nspawn` containers to run properly inside the Nix build sandbox.
**Configuration:**
The `uid-range` feature requires the `auto-allocate-uids` setting to be enabled in your Nix configuration.
To verify or enable it, add to your `/etc/nix/nix.conf` or NixOS configuration:
```nix
settings.experimental-features = [
"auto-allocate-uids"
];
nix.settings.auto-allocate-uids = true;
nix.settings.system-features = [ "uid-range" ];
```
**Technical details:**
- Container tests set `requiredSystemFeatures = [ "uid-range" ];` in their derivation (see `lib/test/container-test-driver/driver-module.nix:98`)
- Without this feature, containers cannot properly manage user namespaces and will fail to start
### Limitations
- Cannot run in interactive mode, however while the container test runs, it logs a nsenter command that can be used to log into each of the containers.
- Early implementation and limited by features.
### Where to find examples for NixOS container tests

24
flake.lock generated
View File

@@ -31,11 +31,11 @@
]
},
"locked": {
"lastModified": 1760701190,
"narHash": "sha256-y7UhnWlER8r776JsySqsbTUh2Txf7K30smfHlqdaIQw=",
"lastModified": 1761899396,
"narHash": "sha256-XOpKBp6HLzzMCbzW50TEuXN35zN5WGQREC7n34DcNMM=",
"owner": "nix-community",
"repo": "disko",
"rev": "3a9450b26e69dcb6f8de6e2b07b3fc1c288d85f5",
"rev": "6f4cf5abbe318e4cd1e879506f6eeafd83f7b998",
"type": "github"
},
"original": {
@@ -51,11 +51,11 @@
]
},
"locked": {
"lastModified": 1760948891,
"narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=",
"lastModified": 1762040540,
"narHash": "sha256-z5PlZ47j50VNF3R+IMS9LmzI5fYRGY/Z5O5tol1c9I4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04",
"rev": "0010412d62a25d959151790968765a70c436598b",
"type": "github"
},
"original": {
@@ -71,11 +71,11 @@
]
},
"locked": {
"lastModified": 1761339987,
"narHash": "sha256-IUaawVwItZKi64IA6kF6wQCLCzpXbk2R46dHn8sHkig=",
"lastModified": 1762039661,
"narHash": "sha256-oM5BwAGE78IBLZn+AqxwH/saqwq3e926rNq5HmOulkc=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "7cd9aac79ee2924a85c211d21fafd394b06a38de",
"rev": "c3c8c9f2a5ed43175ac4dc030308756620e6e4e4",
"type": "github"
},
"original": {
@@ -115,10 +115,10 @@
"nixpkgs": {
"locked": {
"lastModified": 315532800,
"narHash": "sha256-yDxtm0PESdgNetiJN5+MFxgubBcLDTiuSjjrJiyvsvM=",
"rev": "d7f52a7a640bc54c7bb414cca603835bf8dd4b10",
"narHash": "sha256-LDT9wuUZtjPfmviCcVWif5+7j4kBI2mWaZwjNNeg4eg=",
"rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386",
"type": "tarball",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.11pre871443.d7f52a7a640b/nixexprs.tar.xz"
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.11pre887438.a7fc11be66bd/nixexprs.tar.xz"
},
"original": {
"type": "tarball",

View File

@@ -18,7 +18,7 @@ let
inputs.data-mesher.nixosModules.data-mesher
];
config = {
clan.core.clanPkgs = lib.mkDefault self.packages.${pkgs.hostPlatform.system};
clan.core.clanPkgs = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system};
};
};
in

View File

@@ -30,5 +30,5 @@ let
in
{
# Note this might jump back and worth as kernel get added or removed.
boot.kernelPackages = lib.mkIf (lib.meta.availableOn pkgs.hostPlatform pkgs.zfs) latestKernelPackage;
boot.kernelPackages = lib.mkIf (lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.zfs) latestKernelPackage;
}

View File

@@ -245,7 +245,7 @@ class SecretStore(StoreBase):
output_dir / "activation" / generator.name / file.name
)
out_file.parent.mkdir(parents=True, exist_ok=True)
out_file.write_bytes(self.get(generator, file.name))
out_file.write_bytes(file.value)
if "partitioning" in phases:
for generator in vars_generators:
for file in generator.files:
@@ -254,7 +254,7 @@ class SecretStore(StoreBase):
output_dir / "partitioning" / generator.name / file.name
)
out_file.parent.mkdir(parents=True, exist_ok=True)
out_file.write_bytes(self.get(generator, file.name))
out_file.write_bytes(file.value)
hash_data = self.generate_hash(machine)
if hash_data:

View File

@@ -246,7 +246,7 @@ class SecretStore(StoreBase):
)
# chmod after in case it doesn't have u+w
target_path.touch(mode=0o600)
target_path.write_bytes(self.get(generator, file.name))
target_path.write_bytes(file.value)
target_path.chmod(file.mode)
if "partitioning" in phases:
@@ -260,7 +260,7 @@ class SecretStore(StoreBase):
)
# chmod after in case it doesn't have u+w
target_path.touch(mode=0o600)
target_path.write_bytes(self.get(generator, file.name))
target_path.write_bytes(file.value)
target_path.chmod(file.mode)
@override

View File

@@ -211,7 +211,7 @@ class ClanSelectError(ClanError):
def __str__(self) -> str:
if self.description:
return f"{self.msg} Reason: {self.description}"
return f"{self.msg} Reason: {self.description}. Use flag '--debug' to see full nix trace."
return self.msg
def __repr__(self) -> str:

View File

@@ -59,9 +59,7 @@ def upload_sources(machine: Machine, ssh: Host, upload_inputs: bool) -> str:
if not has_path_inputs and not upload_inputs:
# Just copy the flake to the remote machine, we can substitute other inputs there.
path = flake_data["path"]
if machine._class_ == "darwin":
remote_program_params = "?remote-program=bash -lc 'exec nix-daemon --stdio'"
remote_url = f"ssh-ng://{remote_url_base}{remote_program_params}"
remote_url = f"ssh-ng://{remote_url_base}"
cmd = nix_command(
[
"copy",