Merge pull request 'dummy-test: add vars' (#3940) from davhau/test into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3940
This commit is contained in:
61
checks/dummy-inventory-test-from-flake/default.nix
Normal file
61
checks/dummy-inventory-test-from-flake/default.nix
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
pkgs,
|
||||
nixosLib,
|
||||
clan-core,
|
||||
...
|
||||
}:
|
||||
|
||||
nixosLib.runTest (
|
||||
{ hostPkgs, config, ... }:
|
||||
{
|
||||
imports = [
|
||||
clan-core.modules.nixosVmTest.clanTest
|
||||
];
|
||||
|
||||
hostPkgs = pkgs;
|
||||
|
||||
# This tests the compatibility of the inventory
|
||||
# With the test framework
|
||||
# - legacy-modules
|
||||
# - clan.service modules
|
||||
name = "dummy-inventory-test-from-flake";
|
||||
|
||||
clan.test.fromFlake = ./.;
|
||||
|
||||
testScript =
|
||||
{ nodes, ... }:
|
||||
''
|
||||
${clan-core.legacyPackages.${hostPkgs.system}.setupNixInNixPython}
|
||||
|
||||
def run_clan(cmd: list[str], **kwargs) -> str:
|
||||
import subprocess
|
||||
clan = "${clan-core.packages.${hostPkgs.system}.clan-cli}/bin/clan"
|
||||
clan_args = ["--flake", "${config.clan.test.flakeForSandbox}"]
|
||||
return subprocess.run(
|
||||
["${hostPkgs.util-linux}/bin/unshare", "--user", "--map-user", "1000", "--map-group", "1000", clan, *cmd, *clan_args],
|
||||
**kwargs,
|
||||
check=True,
|
||||
).stdout
|
||||
|
||||
start_all()
|
||||
admin1.wait_for_unit("multi-user.target")
|
||||
peer1.wait_for_unit("multi-user.target")
|
||||
# Provided by the legacy module
|
||||
print(admin1.succeed("systemctl status dummy-service"))
|
||||
print(peer1.succeed("systemctl status dummy-service"))
|
||||
|
||||
# peer1 should have the 'hello' file
|
||||
peer1.succeed("cat ${nodes.peer1.clan.core.vars.generators.new-service.files.not-a-secret.path}")
|
||||
|
||||
ls_out = peer1.succeed("ls -la ${nodes.peer1.clan.core.vars.generators.new-service.files.a-secret.path}")
|
||||
# Check that the file is owned by 'nobody'
|
||||
assert "nobody" in ls_out, f"File is not owned by 'nobody': {ls_out}"
|
||||
# Check that the file is in the 'users' group
|
||||
assert "users" in ls_out, f"File is not in the 'users' group: {ls_out}"
|
||||
# Check that the file is in the '0644' mode
|
||||
assert "-rw-r--r--" in ls_out, f"File is not in the '0644' mode: {ls_out}"
|
||||
|
||||
run_clan(["machines", "list"])
|
||||
'';
|
||||
}
|
||||
)
|
||||
70
checks/dummy-inventory-test-from-flake/flake.nix
Normal file
70
checks/dummy-inventory-test-from-flake/flake.nix
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
inputs.clan-core.url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
|
||||
inputs.nixpkgs.follows = "clan-core/nixpkgs";
|
||||
|
||||
outputs =
|
||||
{ self, clan-core, ... }:
|
||||
let
|
||||
# Usage see: https://docs.clan.lol
|
||||
clan = clan-core.clanLib.buildClan {
|
||||
inherit self;
|
||||
|
||||
inventory =
|
||||
{ ... }:
|
||||
{
|
||||
meta.name = "foo";
|
||||
machines.peer1 = { };
|
||||
machines.admin1 = { };
|
||||
services = {
|
||||
legacy-module.default = {
|
||||
roles.peer.machines = [ "peer1" ];
|
||||
roles.admin.machines = [ "admin1" ];
|
||||
};
|
||||
};
|
||||
|
||||
instances."test" = {
|
||||
module.name = "new-service";
|
||||
roles.peer.machines.peer1 = { };
|
||||
};
|
||||
|
||||
modules = {
|
||||
legacy-module = ./legacy-module;
|
||||
};
|
||||
};
|
||||
|
||||
modules.new-service = {
|
||||
_class = "clan.service";
|
||||
manifest.name = "new-service";
|
||||
roles.peer = { };
|
||||
perMachine = {
|
||||
nixosModule = {
|
||||
# This should be generated by:
|
||||
# nix run .#generate-test-vars -- checks/dummy-inventory-test dummy-inventory-test
|
||||
clan.core.vars.generators.new-service = {
|
||||
files.not-a-secret = {
|
||||
secret = false;
|
||||
deploy = true;
|
||||
};
|
||||
files.a-secret = {
|
||||
secret = true;
|
||||
deploy = true;
|
||||
owner = "nobody";
|
||||
group = "users";
|
||||
mode = "0644";
|
||||
};
|
||||
script = ''
|
||||
# This is a dummy script that does nothing
|
||||
echo -n "not-a-secret" > $out/not-a-secret
|
||||
echo -n "a-secret" > $out/a-secret
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
# all machines managed by Clan
|
||||
inherit (clan) nixosConfigurations nixosModules clanInternals;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
description = "Set up dummy-module"
|
||||
categories = ["System"]
|
||||
features = [ "inventory" ]
|
||||
|
||||
[constraints]
|
||||
roles.admin.min = 1
|
||||
roles.admin.max = 1
|
||||
---
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
imports = [
|
||||
../shared.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
imports = [
|
||||
../shared.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{ config, ... }:
|
||||
{
|
||||
systemd.services.dummy-service = {
|
||||
enable = true;
|
||||
description = "Dummy service";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
script = ''
|
||||
generated_password_path="${config.clan.core.vars.generators.dummy-generator.files.generated-password.path}"
|
||||
if [ ! -f "$generated_password_path" ]; then
|
||||
echo "Generated password file not found: $generated_password_path"
|
||||
exit 1
|
||||
fi
|
||||
host_id_path="${config.clan.core.vars.generators.dummy-generator.files.host-id.path}"
|
||||
if [ ! -e "$host_id_path" ]; then
|
||||
echo "Host ID file not found: $host_id_path"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
# TODO: add and prompt and make it work in the test framework
|
||||
clan.core.vars.generators.dummy-generator = {
|
||||
files.host-id.secret = false;
|
||||
files.generated-password.secret = true;
|
||||
script = ''
|
||||
echo $RANDOM > "$out"/host-id
|
||||
echo $RANDOM > "$out"/generated-password
|
||||
'';
|
||||
};
|
||||
}
|
||||
6
checks/dummy-inventory-test-from-flake/sops/machines/admin1/key.json
Executable file
6
checks/dummy-inventory-test-from-flake/sops/machines/admin1/key.json
Executable file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"publickey": "age12yt078p9ewxy2sh0a36nxdpgglv8wqqftmj4dkj9rgy5fuyn4p0q5nje9m",
|
||||
"type": "age"
|
||||
}
|
||||
]
|
||||
6
checks/dummy-inventory-test-from-flake/sops/machines/peer1/key.json
Executable file
6
checks/dummy-inventory-test-from-flake/sops/machines/peer1/key.json
Executable file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"publickey": "age12w2ld4vxfyf3hdq2d8la4cu0tye4pq97egvv3me4wary7xkdnq2snh0zx2",
|
||||
"type": "age"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:GPpsUhSzWPtTP8EUNKsobFXjYqDldhkkIH6hBk11RsDLAGWdhVrwcISGbhsWpYhvAdPKA84DB6Zqyh9lL2bLM9//ybC1kzY20BQ=,iv:NrxMLdedT2FCkUAD00SwsAHchIsxWvqe7BQekWuJcxw=,tag:pMDXcMyHnLF2t3Qhb1KolA==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzb2tWb1ExKzdmUTRzaGVj\nK3cyYTBHZTJwVjM1SzUvbHFiMnVhY05iKzFZCnJTSE1VSVdpcUFLSEJuaE1CZzJD\nWjZxYzN2cUltdThNMVRKU3FIb20vUXMKLS0tIFlHQXRIdnMybDZFUVEzWlQrc1dw\nbUxhZURXblhHd0pka0JIK1FTZEVqdUEKI/rfxQRBc+xGRelhswkJQ9GcZs6lzfgy\nuCxS5JI9npdPLQ/131F3b21+sP5YWqks41uZG+vslM1zQ+BlENNhDw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-05-04T12:44:13Z",
|
||||
"mac": "ENC[AES256_GCM,data:fWxLHXBWolHVxv6Q7utcy6OVLV13ziswrIYyNKiwy1vsU8i7xvvuGO1HlnE+q43D2WuHR53liKq1UHuf1JMrWzTwZ0PYe+CVugtoEtbR2qu3rK/jAkOyMyhmmHzmf6Rp4ZMCzKgZeC/X2bDKY/z0firHAvjWydEyogutHpvtznM=,iv:OQI3FfkLneqbdztAXVQB3UkHwDPK+0hWu5hZ9m8Oczg=,tag:em6GfS2QHsXs391QKPxfmA==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../users/admin
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:W3cOkUYL5/YulW2pEISyTlMaA/t7/WBE7BoCdFlqrqgaCL7tG4IV2HgjiPWzIVMs0zvDSaghdEvAIoB4wOf470d1nSWs0/E8SDk=,iv:wXXaZIw3sPY8L/wxsu7+C5v+d3RQRuwxZRP4YLkS8K4=,tag:HeK4okj7O7XDA9JDz2KULw==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxRC83b3dtSVpXcGovNnVs\nTzFka2J2MEFhYkF1ajVrdjMrNUtPWGRObjM4Cm5zSUR5OGw0T0FaL3BaWmR6L29W\nU2syMFIyMUhFRUZpWFpCT28vWko2ZU0KLS0tIFpHK3BjU1V1L0FrMGtwTGFuU3Mz\nRkV5VjI2Vndod202bUR3RWQwNXpmVzQKNk8/y7M62wTIIKqY4r3ZRk5aUCRUfine\n1LUSHMKa2bRe+hR7nS7AF4BGXp03h2UPY0FP5+U5q8XuIj1jfMX8kg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-05-04T12:44:16Z",
|
||||
"mac": "ENC[AES256_GCM,data:yTkQeFvKrN1+5FP+yInsaRWSAG+ZGG0uWF3+gVRvzJTFxab8kT2XkAMc+4D7SKgcjsmwBBb77GNoAKaKByhZ92UaCfZ2X66i7ZmYUwLM1NVVmm+xiwwjsh7PJXlZO/70anTzd1evtlZse0jEmRnV5Y0F0M6YqXmuwU+qGUJU2F8=,iv:sy6ozhXonWVruaQfa7pdEoV5GkNZR/UbbINKAPbgWeg=,tag:VMruQ1KExmlMR7TsGNgMlg==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../users/admin
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"type": "age"
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/admin1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:T8edCvw=,iv:7/G5xt5fv38I9uFzk7WMIr9xQdz/6lFxqOC+18HBg8Q=,tag:F39Cxbgmzml+lZLsZ59Kmg==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age12yt078p9ewxy2sh0a36nxdpgglv8wqqftmj4dkj9rgy5fuyn4p0q5nje9m",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPNUhiYkZWK3dPMHNiRTVM\nRHNvaHFsOFp1c0UxQitwVG0zY01MNDZRV1E4CjEybENoTVIzN29vQ3FtUTRSYmFU\nNXIzQllVSllXRGN2M1B6WXJLdHZSajgKLS0tIDllZ0ZmZUcxMHhDQUpUOEdWbmkv\neUQweHArYTdFSmNteVpuQ3BKdnh0Y0UKs8Hm3D+rXRRfpUVSZM3zYjs6b9z8g10D\nGTkvreUMim4CS22pjdQ3eNA9TGeDXfWXE7XzwXLCb+wVcf7KwbDmvg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKSDhpT3cvck9PenZYVEZH\ndFQreVRBdG93L1dBUGlvYjFWcDlHWUJsZUVBCm9DMTJ4UytiYzlEVHNWdUcwS1ds\nT0dhbzAzNDdmbDBCU0dvL2xNeHpXcGsKLS0tIFArbmpsbzU3WnpJdUt1MGN0L1d0\nV1JkTDJYWUxsbmhTQVNOeVRaSUhTODQKk9Vph2eldS5nwuvVX0SCsxEm4B+sO76Z\ndIjJ3OQxzoZmXMaOOuKHC5U0Y75Qn7eXC43w5KHsl2CMIUYsBGJOZw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-05-04T12:44:14Z",
|
||||
"mac": "ENC[AES256_GCM,data:6fKrS1eLLUWlHkQpxLFXBRk6f2wa5ADLMViVvYXXGU24ayl9UuNSKrCRHp9cbzhqhti3HdwyNt6TM+2X6qhiiAQanKEB2PF7JRYX74NfNKil9BEDjt5AqqtpSgVv5l7Ku/uSHaPkd2sDmzHsy5Q4bSGxJQokStk1kidrwle+mbc=,iv:I/Aad82L/TCxStM8d8IZICUrwdjRbGx2fuGWqexr21o=,tag:BfgRbGUxhPZzK2fLik1kxA==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1 @@
|
||||
18650
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:vp0yW0Gt,iv:FO2cy+UpEl5aRay/LUGu//c82QiVxuKuGSaVh0rGJvc=,tag:vf2RAOPpcRW0HwxHoGy17A==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age12w2ld4vxfyf3hdq2d8la4cu0tye4pq97egvv3me4wary7xkdnq2snh0zx2",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjaFVNMEd2YUxpSm5XVVRi\nY2ZUc3NTOStJUFNMWWVPQTgxZ2tCK1QrMW1ZCjYwMlA4dkIzSlc0TGtvZjcyK3Bi\nM3pob2JOOFUyeVJ6M2JpaTRCZlc1R0kKLS0tIDJMb1dFcVRWckhwYWNCQng0RlFO\nTkw3OGt4dkFIZVY5aVEzZE5mMzJSM0EKUv8bUqg48L2FfYVUVlpXvyZvPye699of\nG6PcjLh1ZMbNCfnsCzr+P8Vdk/F4J/ifxL66lRGfu2xOLxwciwQ+5Q==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnZ2dDbVhoQngxM3lTSmZF\nUTAwS1lCTGhEMU1GVXpFUzlIUFdqZy9LajF3Ck9mdVpBRjlyVUNhZXZIUFZjUzF1\nNlhFN28vNmwzcUVkNmlzUnpkWjJuZE0KLS0tIHpXVHVlNk9vU1ZPTGRrYStWbmRO\nbDM4U2o1SlEwYWtqOXBqd3BFUTAvMHcKkI8UVd0v+x+ELZ5CoGq9DzlA6DnVNU2r\nrV9wLfbFd7RHxS0/TYZh5tmU42nO3iMYA9FqERQXCtZgXS9KvfqHwQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-05-04T12:44:18Z",
|
||||
"mac": "ENC[AES256_GCM,data:1ZZ+ZI1JsHmxTov1bRijfol3kTkyheg2o3ivLsMHRhCmScsUry97hQJchF78+y2Izt7avaQEHYn6pVbYt/0rLrSYD7Ru7ITVxXoYHOiN5Qb98masUzpibZjrdyg5nO+LW5/Hmmwsc3yn/+o3IH1AUYpsxlJRdnHHCmoSOFaiFFM=,iv:OQlgmpOTw4ljujNzqwQ5/0Mz8pQpCSUtqRvj3FJAxDs=,tag:foZvdeW7gK9ZVKkWqnlxGA==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1 @@
|
||||
6745
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/machines/peer1
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data:prFl0EJy8bM=,iv:zITWxf+6Ebk0iB5vhhd7SBQa1HFrIJXm8xpSM+D9I0M=,tag:NZCRMCs1SzNKLBu/KUDKMQ==,type:str]",
|
||||
"sops": {
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age12w2ld4vxfyf3hdq2d8la4cu0tye4pq97egvv3me4wary7xkdnq2snh0zx2",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0S0RZRWxaZVZvTUhjdWVL\naU9WZmtEcm1qa2JsRmdvdmZmNENMaWFEVUFRCmdoVnRXSGlpRlFjNmVVbDJ5VnFT\nMnVJUlVnM3lxNmZCRTdoRVJ4NW1oYWcKLS0tIFFNbXBFUk1RWnlUTW1SeG1vYzlM\nVVpEclFVOE9PWWQxVkZ0eEgwWndoRWcKDAOHe+FIxqGsc6LhxMy164qjwG6t2Ei2\nP0FSs+bcKMDpudxeuxCjnDm/VoLxOWeuqkB+9K2vSm2W/c/fHTSbrA==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
},
|
||||
{
|
||||
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2VU5jOEpwYUtDVEVFcVpU\nQkExTVZ3ejZHcGo5TG8zdUQwNktoV09WdUZvCmQ0dE1TOWRFbTlxdVd4WWRxd3VF\nQUNTTkNNT3NKYjQ5dEJDY0xVZ3pZVUUKLS0tIDFjajRZNFJZUTdNeS8yN05FMFZU\ncEtjRjhRbGE0MnRLdk10NkFLMkxqencKGzJ66dHluIghH04RV/FccfEQP07yqnfb\n25Hi0XIVJfXBwje4UEyszrWTxPPwVXdQDQmoNKf76Qy2jYqJ56uksw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2025-05-04T12:44:20Z",
|
||||
"mac": "ENC[AES256_GCM,data:FIkilsni5kOdNlVwDuLsQ/zExypHRWdqIBQDNWMLTwe8OrsNPkX+KYutUvt9GaSoGv4iDULaMRoizO/OZUNfc2d8XYSdj0cxOG1Joov4GPUcC/UGyNuQneAejZBKolvlnidKZArofnuK9g+lOTANEUtEXUTnx8L+VahqPZayQas=,iv:NAo6sT3L8OOB3wv1pjr3RY2FwXgVmZ4N0F4BEX4YPUY=,tag:zHwmXygyvkdpASZCodQT9Q==,type:str]",
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.10.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
../../../../../../sops/users/admin
|
||||
@@ -0,0 +1 @@
|
||||
not-a-secret
|
||||
@@ -51,6 +51,7 @@ in
|
||||
postgresql = self.clanLib.test.containerTest ./postgresql nixosTestArgs;
|
||||
|
||||
dummy-inventory-test = import ./dummy-inventory-test nixosTestArgs;
|
||||
dummy-inventory-test-from-flake = import ./dummy-inventory-test-from-flake nixosTestArgs;
|
||||
data-mesher = import ./data-mesher nixosTestArgs;
|
||||
}
|
||||
// lib.optionalAttrs (pkgs.stdenv.hostPlatform.system == "aarch64-linux") {
|
||||
|
||||
@@ -7,11 +7,10 @@
|
||||
let
|
||||
inherit (lib)
|
||||
flatten
|
||||
flip
|
||||
mapAttrs'
|
||||
mapAttrsToList
|
||||
mkForce
|
||||
mkIf
|
||||
mkOption
|
||||
removePrefix
|
||||
types
|
||||
unique
|
||||
;
|
||||
@@ -24,9 +23,48 @@ in
|
||||
flake.modules.nixosVmTest.clanTest =
|
||||
{ config, hostPkgs, ... }:
|
||||
let
|
||||
clanFlakeResult = config.clan;
|
||||
testName = config.name;
|
||||
|
||||
clan-core = self;
|
||||
|
||||
inherit (lib)
|
||||
filterAttrs
|
||||
flip
|
||||
hasPrefix
|
||||
intersectAttrs
|
||||
mapAttrs'
|
||||
pathExists
|
||||
removePrefix
|
||||
throwIf
|
||||
;
|
||||
|
||||
# only relevant if config.clan.test.fromFlake is used
|
||||
importFlake =
|
||||
flakeDir:
|
||||
let
|
||||
flakeExpr = import (flakeDir + "/flake.nix");
|
||||
inputs = intersectAttrs flakeExpr.inputs clan-core.inputs;
|
||||
flake = flakeExpr.outputs (
|
||||
inputs
|
||||
// {
|
||||
self = flake // {
|
||||
outPath = flakeDir;
|
||||
};
|
||||
clan-core = clan-core;
|
||||
}
|
||||
);
|
||||
in
|
||||
throwIf (pathExists (
|
||||
flakeDir + "/flake.lock"
|
||||
)) "Test ${testName} should not have a flake.lock file" flake;
|
||||
|
||||
clanFlakeResult =
|
||||
if config.clan.test.fromFlake != null then importFlake config.clan.test.fromFlake else config.clan;
|
||||
|
||||
machineModules = flip filterAttrs clanFlakeResult.nixosModules (
|
||||
name: _module: hasPrefix "clan-machine-" name
|
||||
);
|
||||
|
||||
update-vars-script = "${
|
||||
self.packages.${hostPkgs.system}.generate-test-vars
|
||||
}/bin/generate-test-vars";
|
||||
@@ -48,7 +86,7 @@ in
|
||||
);
|
||||
|
||||
vars-check =
|
||||
hostPkgs.runCommand "update-vars-check"
|
||||
hostPkgs.runCommand "update-vars-check-${testName}"
|
||||
{
|
||||
nativeBuildInputs = generatorRuntimeInputs ++ [
|
||||
hostPkgs.nix
|
||||
@@ -89,6 +127,16 @@ in
|
||||
fi
|
||||
touch $out
|
||||
'';
|
||||
|
||||
# the test's flake.nix with locked clan-core input
|
||||
flakeForSandbox = hostPkgs.runCommand "offline-flake-for-test-${config.name}" { } ''
|
||||
cp -r ${config.clan.directory} $out
|
||||
chmod +w -R $out
|
||||
substituteInPlace $out/flake.nix \
|
||||
--replace-fail \
|
||||
"https://git.clan.lol/clan/clan-core/archive/main.tar.gz" \
|
||||
"${clan-core.packages.${hostPkgs.system}.clan-core-flake}"
|
||||
'';
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
@@ -115,6 +163,9 @@ in
|
||||
nixpkgs
|
||||
nix-darwin
|
||||
;
|
||||
# By default clan.directory defaults to self, but we don't
|
||||
# have a sensible default for self here
|
||||
self = throw "set clan.directory in the test";
|
||||
};
|
||||
modules = [
|
||||
clanLib.buildClanModule.flakePartsModule
|
||||
@@ -134,6 +185,28 @@ in
|
||||
type = types.bool;
|
||||
description = "Whether to use containers for the test.";
|
||||
};
|
||||
test.fromFlake = mkOption {
|
||||
default = null;
|
||||
type = types.nullOr types.path;
|
||||
description = ''
|
||||
path to a directory containing a `flake.nix` defining the clan
|
||||
|
||||
Only use this if the clan CLI needs to be used inside the test.
|
||||
Otherwise, use the other clan.XXX options instead to specify the clan.
|
||||
|
||||
Loads the clan from a flake instead of using clan.XXX options.
|
||||
This has the benefit that a real flake.nix will be available in the test.
|
||||
This is useful to test CLI interactions which require a flake.nix.
|
||||
|
||||
Using this introduces dependencies that should otherwise be avoided.
|
||||
'';
|
||||
};
|
||||
test.flakeForSandbox = mkOption {
|
||||
default = flakeForSandbox;
|
||||
type = types.path;
|
||||
description = "The flake.nix to use for the test.";
|
||||
readOnly = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
@@ -141,10 +214,12 @@ in
|
||||
};
|
||||
};
|
||||
config = {
|
||||
clan.directory = mkIf (config.clan.test.fromFlake != null) (mkForce config.clan.test.fromFlake);
|
||||
|
||||
# Inherit all nodes from the clan
|
||||
# i.e. nodes.jon <- clan.machines.jon
|
||||
# clanInternals.nixosModules contains nixosModules per node
|
||||
nodes = flip mapAttrs' clanFlakeResult.nixosModules (
|
||||
nodes = flip mapAttrs' machineModules (
|
||||
name: machineModule: {
|
||||
name = removePrefix "clan-machine-" name;
|
||||
value = machineModule;
|
||||
@@ -169,11 +244,6 @@ in
|
||||
clanLib.test.sopsModule
|
||||
];
|
||||
|
||||
# Disable documentation
|
||||
# This is nice to speed up the evaluation
|
||||
# And also suppresses any warnings or errors about the documentation
|
||||
documentation.enable = lib.mkDefault false;
|
||||
|
||||
# Disable garbage collection during the test
|
||||
# https://nix.dev/manual/nix/2.28/command-ref/conf-file.html?highlight=min-free#available-settings
|
||||
nix.settings.min-free = 0;
|
||||
|
||||
@@ -8,4 +8,5 @@
|
||||
nix.registry = lib.mkForce { };
|
||||
documentation.doc.enable = false;
|
||||
documentation.man.enable = false;
|
||||
documentation.enable = lib.mkDefault false;
|
||||
}
|
||||
|
||||
@@ -1,19 +1,37 @@
|
||||
{
|
||||
perSystem = {
|
||||
legacyPackages.setupNixInNix = ''
|
||||
export HOME=$TMPDIR
|
||||
export NIX_STATE_DIR=$TMPDIR/nix
|
||||
export NIX_CONF_DIR=$TMPDIR/etc
|
||||
export IN_NIX_SANDBOX=1
|
||||
export CLAN_TEST_STORE=$TMPDIR/store
|
||||
# required to prevent concurrent 'nix flake lock' operations
|
||||
export LOCK_NIX=$TMPDIR/nix_lock
|
||||
mkdir -p "$CLAN_TEST_STORE/nix/store"
|
||||
mkdir -p "$CLAN_TEST_STORE/nix/var/nix/gcroots"
|
||||
if [[ -n "''${closureInfo-}" ]]; then
|
||||
xargs cp --recursive --target "$CLAN_TEST_STORE/nix/store" < "$closureInfo/store-paths"
|
||||
nix-store --load-db --store "$CLAN_TEST_STORE" < "$closureInfo/registration"
|
||||
fi
|
||||
'';
|
||||
legacyPackages = {
|
||||
setupNixInNix = ''
|
||||
export HOME=$TMPDIR
|
||||
export NIX_STATE_DIR=$TMPDIR/nix
|
||||
export NIX_CONF_DIR=$TMPDIR/etc
|
||||
export IN_NIX_SANDBOX=1
|
||||
export CLAN_TEST_STORE=$TMPDIR/store
|
||||
# required to prevent concurrent 'nix flake lock' operations
|
||||
export LOCK_NIX=$TMPDIR/nix_lock
|
||||
mkdir -p "$CLAN_TEST_STORE/nix/store"
|
||||
mkdir -p "$CLAN_TEST_STORE/nix/var/nix/gcroots"
|
||||
if [[ -n "''${closureInfo-}" ]]; then
|
||||
xargs cp --recursive --target "$CLAN_TEST_STORE/nix/store" < "$closureInfo/store-paths"
|
||||
nix-store --load-db --store "$CLAN_TEST_STORE" < "$closureInfo/registration"
|
||||
fi
|
||||
'';
|
||||
setupNixInNixPython = ''
|
||||
from os import environ
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
environ['HOME'] = environ['TMPDIR']
|
||||
environ['NIX_STATE_DIR'] = environ['TMPDIR'] + '/nix'
|
||||
environ['NIX_CONF_DIR'] = environ['TMPDIR'] + '/etc'
|
||||
environ['IN_NIX_SANDBOX'] = '1'
|
||||
environ['CLAN_TEST_STORE'] = environ['TMPDIR'] + '/store'
|
||||
environ['LOCK_NIX'] = environ['TMPDIR'] + '/nix_lock'
|
||||
Path(environ['CLAN_TEST_STORE'] + '/nix/store').mkdir(parents=True, exist_ok=True)
|
||||
Path(environ['CLAN_TEST_STORE'] + '/nix/var/nix/gcroots').mkdir(parents=True, exist_ok=True)
|
||||
if 'closureInfo' in environ:
|
||||
subprocess.run(['cp', '--recursive', '--target', environ['CLAN_TEST_STORE'] + '/nix/store'] + environ['closureInfo'].split(), check=True)
|
||||
subprocess.run(['nix-store', '--load-db', '--store', environ['CLAN_TEST_STORE']] + ['<', environ['closureInfo'] + '/registration'], shell=True, check=True)
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user