Add explicit dependency validation to vars, so that proper error
messages can be surfaced to the user.
Instead of:
```
Traceback (most recent call last):
File "/home/lhebendanz/Projects/clan-core/pkgs/clan-cli/clan_lib/async_run/__init__.py", line 154, in run
self.result = AsyncResult(_result=self.function(*self.args, **self.kwargs))
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lhebendanz/Projects/clan-core/pkgs/clan-cli/clan_cli/machines/update.py", line 62, in run_update_wit
h_network
run_machine_update(
~~~~~~~~~~~~~~~~~~^
machine=machine,
^^^^^^^^^^^^^^^^
...<2 lines>...
upload_inputs=upload_inputs,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/lhebendanz/Projects/clan-core/pkgs/clan-cli/clan_lib/machines/update.py", line 158, in run_machine_u
pdate
run_generators([machine], generators=None, full_closure=False)
~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lhebendanz/Projects/clan-core/pkgs/clan-cli/clan_lib/vars/generate.py", line 156, in run_generators
all_generators = get_generators(machines, full_closure=True)
File "/home/lhebendanz/Projects/clan-core/pkgs/clan-cli/clan_lib/vars/generate.py", line 50, in get_generators
all_generators_list = Generator.get_machine_generators(
all_machines,
flake,
include_previous_values=include_previous_values,
)
File "/home/lhebendanz/Projects/clan-core/pkgs/clan-cli/clan_cli/vars/generator.py", line 246, in get_machine_ge
nerators
if generators_data[dep]["share"]
~~~~~~~~~~~~~~~^^^^^
KeyError: 'bla'
```
We now get:
```
$> Generator 'my_generator' on machine 'my_machine' depends on generator 'non_existing_generator', but 'non_existing_generator' does not exist
```
Closes: #5698
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
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.
The machines_dir() function was hardcoding "machines" without considering
the directory parameter from buildClan/clan configuration. This caused
update-hardware-config and other commands to write files to the wrong
location when a custom directory was specified (e.g., directory = ./clan).
Solution:
1. Added relativeDirectory to inventoryClass in Nix, computed where both
self and directory have consistent store paths during evaluation
2. Updated machines_dir() to use this pre-computed relative path from Nix
via flake.select("clanInternals.inventoryClass.relativeDirectory")
Fixes: https://git.clan.lol/clan/clan-core/issues/2906
The option curretly keeps it default value, even if set. This fixes the
value being passed through correctly, so that the user-specified value
is actually used.
Fixes: #5669
That means we rely on a certain structure of the user flake
these assumptions cannot be made. Their flake can have any shape and is not controlled by us
Fix dynamic shell completions by correcting parameter names
Dynamic completions for the CLI were not working because completion
functions used `_prefix` as the first parameter name instead of `prefix`.
This is incompatible with how `argcomplete` passes it's arguments.
Add regression test for the prefix parameter as well as some basic shell
completion testing.
The default 30-day expiration was causing certificates to expire
frequently, breaking monitoring. Setting to 100 years provides a
temporary solution until automated certificate rotation is implemented.
Fixes#5605
The client role now automatically collects and merges searchDomains from
ALL servers in the instance when not explicitly configured. This eliminates
redundant configuration and ensures clients trust certificates from all
servers.
Also uses lib.mkIf with .exists check to safely handle the openssh-cert
generator access, checking searchDomains first to enable lazy evaluation.
Within a clan.service the module can access 'role.peer.settings' and 'role.peer.machine.jon.settings'
While the current machine is jon, accessing the role settings is arguably a design mistake.
I didn't catch that problem, unfortunately this might be a breaking change
Prevents "File name too long" errors when users provide age keys directly
to 'clan secrets users add', as Path.is_file() would fail before the key
validation could run.
Fixes: https://git.clan.lol/clan/clan-core/issues/5522
Fix `extraPythonPackages` support in the container test driver.
It triggered the following warning from `nixpkgs`:
```
python3Packages = throw "do not use python3Packages when building Python packages, specify each used package as a separate argument"; # do not remove
```
The following `callPackage` usage triggered the `throw`:
```
hostPackages.python3.pkgs.callPackage
```
The change to a regular `callPackage` i`nvocation fixes this issue.
Added a container test with a popular package to ensure compatibility in the future.
Closes: #5459
This fixes an issue where check_vars() would add machine keys or authorize machines for shared vars.
These write operations should only ever be done on a `clan vars generate`, which `clan vars check` should be a read-only operation
- Action: Add sibling options.darwinModule = mkOption { type = types.deferredModule; default = { }; description = "A single nix-darwin module for the instance."; }.
- Add darwinModule to per-machine return type next to nixosModule.
- Action: Add sibling options.darwinModule = mkOption { type = types.deferredModule; default = { }; description = "A single nix-darwin module for the machine."; }.
- Compose darwinModule per (role, instance, machine) similarly to nixosModule.
- Change: Provide minimal darwinModule that sets users.users.<name> (and any safe, cross-platform bits). If some nixos-only settings (e.g., systemd hooks) exist, keep them nixos-only.
Implementation Steps
1) Service API extensions
- Add options.darwinModule to roles.*.perInstance and perMachine (see anchors above).
- Keep defaults to {} so services can omit it safely.
2) Aggregation logic
- result.allRoles: emit darwinModule wrapper from instanceRes.darwinModule.
- Produce final darwinModule with [ machineResult.darwinModule ] ++ instanceResults.darwinModules.
- Leave exports logic unchanged.
3) Machine wiring
- modules/clan/distributed-services.nix: choose .darwinModule vs .nixosModule based on inventory.machines.<name>.machineClass.
- modules/clan/module.nix: include v.machineImports for both OS classes.
4) Example migration (users)
- Add darwinModule in clanServices/users/default.nix.
- Validate that users service evaluates for a darwin machine and does not reference nixos-specific options.
5) Documentation
- Update ADR docs to mention darwinModule in Result attributes and examples.
- Add a short “Authoring for Darwin” snippet showing perInstance/perMachine returning both modules.
6) Tests and verification
- Unit-level: extend lib/inventory/distributed-service/tests to assert presence of result.final.<machine>.darwinModule when perInstance/perMachine return it.
- Integration-level: evaluate a sample darwin machine (e.g., inventory.json has test-darwin-machine) and assert clan.darwinModules.<machine> includes the aggregated module.
- Sanity: ensure existing nixos-only services still evaluate unchanged.
Backward Compatibility
- Existing services that only return nixosModule continue to work.
- Darwin machines won’t import service modules until services provide darwinModule, avoiding accidental breakage.
- extraModules remain applied only to nixos aggregation initially to prevent nixos-only modules from breaking darwin evaluation. We can add OS-specific extraModules in a follow-up (e.g., roles.*.extraModulesDarwin).
Acceptance Criteria
- Services can return darwinModule in perInstance/perMachine without errors.
- Darwin machines import aggregated darwinModule outputs from all participating services.
- nixos behavior remains unchanged for existing services.
- Documentation updated to reflect the new attribute and example.
Rollout Notes
- Start by updating clanServices/users as a working example.
- Encourage service authors to add darwinModule incrementally; no global migration is required.
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHVC8wZUZJYUl5MXVNa2k5\ndGV1MnFWbUNLNVdxeEtCVUc3MTd0ck9aeFFBCnFhZW40amVYc3FlN1FPRTFSWTJR\nQzhNOERKbnRnSlJVeElNSEM5ZUJsZGsKLS0tIG1uNnlNN3MweHlYczNRTW9xSytu\neThzUmxKZTJBT2lCcTdiNUI4N3paTVEKgS9j2/GVt1KBoggUj9d6UK/mIlK4niLQ\nzVq2BHt3irxQpkpGUogXH2b86zSAOEJFzsL1Rk8HM1mogTG8jqf0qA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlR3RGQ2ZLTkR3ZWxNVCsv\naXJHRjBiVUVYZVRIY2swY2xubGhmb3pLRkNvCldhQUV2WDlqYjZ4ZUFWYXkvUEEw\nZi9XRWw0Mi9mRENDcnI0aENDR2Z4MHcKLS0tIGFQU3Q4WEErbnBjOHpNR1BSR2cr\nRFg0anE1cHExT0sySmxuUks1R05nczAKZO3R6+f9co2+YGO8HPufoq1fLqqrdTWD\n4zqemMmG2BjMRDumxtcKp8CLaZWlJoP4e/+tonfdoe42qmNF5NJcFw==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzZWo4WGh1cWxKeDhDdlBm\nTVFjVFBIUU9xaGRkanNHaUVUUHN1czNRSUhNCkp5MmwzSGdycmsrZGhaRUhEbXBF\nNUhtdEF6bHZQOGJYUVhFVHlYc3FPODAKLS0tIDBRQ2VGT2IvU1F4MEVabzhYSFJq\nOWZmbGpkQmNSMnNKa0s4K2JXdGgwRlkKUQRREpG5H1mNHSc/cZrdMiSz0veJFR4N\n+W49XL/wQUZwajykwYj++G+dWDO7DQ+fpbB9w4mzbsAmCsXirseTLA==\n-----END AGE ENCRYPTED FILE-----\n"
This service is experimental and will change in the future.
---
This module is part of Clan's [networking interface](https://docs.clan.lol/guides/networking/networking/).
Clan's networking module automatically manages connections across available network transports and falls back intelligently. When you run `clan ssh` or `clan machines update`, Clan attempts each configured network in priority order until a connection succeeds.
The example below shows how to configure a domain so server1 is reachable over the clearnet. By default, the `internet` module has the highest priority among networks.
This NixOS module installs and configures Synapse — a federated Matrix homeserver with end-to-end encryption — and optionally provides the Element web client.
The example below demonstrates a minimal setup that includes:
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaeXRjU214aWk5ajl1aW9E\naGJlb1ViaVRmMTBHdkFDQUNDZS94WFZiNUNvCllmWTJBck9hR3U3V09VWDZwQ2xI\nd3ZEQnBIUG5ZSTVIdS8rQ2FMYVhyNk0KLS0tIEE1UG8rSzFyU01sVXhGVHpoaE9i\nSis4Qi9tMGFqbTNMTDZUVk1ZdXkrM28Km4VkfaOsZ69ckjvrg+os43H/O1IoWHzC\nt4LqZRz1Tk7/d1aLWavSPPjVYrCOMZeNBqGbQpGfjjuXrafClRNQdQ==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNQS96MUFubVdOR2VCc2xO\ncTc5QnNHNTFpdURnSnF3dVhBQXQ3bnBuRW1RCngzSVlhSW9rNUxoSWdKcEtKVXc3\nQitLZ2NDUXBSUmxtVWpYRUlvOHVXcW8KLS0tIGZaWlRVak9NYmt2elpwYStYenRE\nanlkT3BET1FjQ2lFZkp3SXFMSkJSaVkKKkr+MNNqs6Ve3K5OrZfBEGlnc7OAthqf\nOZrP9NYOTMgkvhFsZTVpUS0zskry0iwmTNt+KeluYf0Tko8K53Kx2A==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3R1RHTGViTnRLVVkyM3J0\nbm96cGVPTlo4NXBNL0g1eEVSNG9DUkgwVFRBCmRKVTlMRmV3Tmg2RTZIclBlWlcr\ndzI5MUxhcllzbE1IMDNxa08zVkpITmsKLS0tIG01Y2dyQkY3UmRudFk2d0p6bThn\nemlaWnZoS3p4VHhMTFFwTm9VN0ttYzQKVbLFgtK6NIRIiryWHeeOPD45iwUds4QD\n7b8xYYoxlo+DETggxK6Vz3IdT/BSK5bFtgAxl864b5gW+Aw4c6AO5w==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXd2dVYmJIbUVVeXk5Nk1E\nekFiUldVVUhRTmE4dHRiTHNDdEMyS1pRV1RrCkNScGdXVSs4UU5id29DV0pZWDQr\nenV1QmpnOFk5aFpTTUxmb0hDVHZDdFkKLS0tIHpmalJtRC94bEhaUStmeUlHT21w\nd3o3UzJHZklxK0RCYUUxc2c3aG1XclkKEPq1ZgyGiAK/Hy4zT7wfdDfPEE3vMHpR\nzwQV5y3M3DmlnKQEvJu0DpQ334CyAcubZC7cswQdUrM8TPqJhb/TuA==\n-----END AGE ENCRYPTED FILE-----\n"
- Generates and persists SSH host keys via `vars`.
- Optionally issues CA‑signed host certificates for servers.
- Installs the `server` CA public key into `clients``known_hosts` for TOFU‑less verification.
- Optionally issues CA-signed host certificates for servers.
- Installs the `server` CA public key into `clients``known_hosts` for TOFU-less verification.
When to use it
- Zero‑TOFU SSH for dynamic fleets: admins/CI can connect to frequently rebuilt hosts (e.g., server-1.example.com) without prompts or per‑host `known_hosts` churn.
## When to use it
- Zero-TOFU SSH for dynamic fleets: admins/CI can connect to frequently rebuilt hosts (e.g., server-1.example.com) without prompts or per-host `known_hosts` churn.
Roles
- Server: runs sshd, presents a CA‑signed host certificate for `<machine>.<domain>`.
- Client: trusts the CA for the given domains to verify servers’ certificates.
### Roles
- Server: runs sshd, presents a CA-signed host certificate for `<machine>.<domain>`.
- Client: trusts the CA for the given domains to verify servers' certificates.
Tip: assign both roles to a machine if it should both present a cert and verify others.
Quick start (with host certificates)
@@ -80,12 +80,13 @@ Admins should trust only production; CI should trust prod and staging. Servers a
};
}
```
- Admin -> server1.prod.example.com: zero‑TOFU (verified via cert).
### Explanation
- Admin -> server1.prod.example.com: zero-TOFU (verified via cert).
- Admin -> server1.staging.example.com: falls back to TOFU (or is blocked by policy).
- CI -> either prod or staging: zero‑TOFU for both.
Note: server and client searchDomains don’t have to be identical; they only need to overlap for the hostnames you actually use.
- CI -> either prod or staging: zero-TOFU for both.
Note: server and client searchDomains don't have to be identical; they only need to overlap for the hostnames you actually use.
Notes
### Notes
- Connect using a name that matches a cert principal (e.g., `server1.example.com`); wildcards are not allowed inside the certificate.
- CA private key stays in `vars` (not deployed); only the CA public key is distributed.
- Logins still require your user SSH keys on the server (passwords are disabled).
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5b0Y3aldQWXJyZzU3aGZU\naWpOK1VXdUVlSUVvZzJqSDVCekQ0Z2JxblRvCmFWd0c1SC9jckMweTIrNmg0VnN3\ncTNwMkVTL0ZyT3RGeUs2NnlNb21GWTQKLS0tIEpGM2FacUNoakJ0dlJwMWZMNU0x\nVWhmV1pDOTRFNExpVHBTRUx2L2ZaMVUK+ka9oqcvoLjwwUqIol0rU1VsJHhs4S1P\nWpKKPetUPEF4xxWj0OdeMc40XCTjl6CBdbtcrslH3tuZHjeSWQ6QCg==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkNlpCNGR0SHVtVzJ2K0hM\ncng1ZWlTSGQzWndXVWhlbEZMN25TUklXV1I4Cm9PZkJ3Zi81YXoxdzVPTFI3dE1a\nUnJnUmJPbi9CYmdFL2ltaTRSQ1MreFUKLS0tIDE4Y05IamJjL0huY2l2YU4zbDJs\ndTl1b0wzaTM4MndlcFZYVThqbWtVeFUKuSZLJpUrccuusJPU2xWHw19wTN8mKZW3\n1GJJjlb79rZp/RbSMxFxkyVHgu+F9kbpRgViICJSWkeR495786oArA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLM3lNL1UyUjhRdFBvenlv\naXBTYXJva0hCTS8vK1hCYmdQdlpBNGFNTkNrCmVTbFROTWVWRzZyc2E0SjVDT1hs\nMm9qT0plcHNJaWczcWJTd0llYldGMVkKLS0tIGh6M04yQ3RiMGVYbTNYMEdCVTNK\nUDhaS3FSVWl4ZGlPYTRodW80VElsZ1UKxi48UZpxuu7gkRtQrCi4//suOpuFY6sl\n8b1xcN/tMn2MWW9hvx4K4qJLXTWOm+9GiZqJ51JBb0hihRh7fC3SfA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGK2Z5OGFsVjBJcGFITENH\nL205TDBaNkRvQ3ZBbGVDU0wrWnl5QkJaSFZNCjhNSXpMTTd1ejlqbVNBUDZ2TlFn\neUhNdEh4M1RhQnFabHpaMVd5eG11THcKLS0tIE9PS3JlVFVPNG5sM3hpWG95V1ho\nSXBySU1SUExkVHNHZElmQWExTVN3cHMKvzdlCWP8/9xviu/9AMxw/4ZyXo4O3AE9\n84IQBDO4GYrqnXvOroxjsNCDrCBDH0WPuYAphctJvyI5SSAtL4uHhQ==\n-----END AGE ENCRYPTED FILE-----\n"
This service is experimental and will change in the future.
---
This module is part of Clan's [networking interface](https://docs.clan.lol/guides/networking/networking/).
Clan's networking module automatically manages connections across available network transports and falls back intelligently. When you run `clan ssh` or `clan machines update`, Clan attempts each configured network in priority order until a connection succeeds.
The example below configures all your nixos machines to be reachable over the Tor network. By default, the `tor` module has the lowest priority among networks, as it's the slowest.
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjZnpWd0grazhjak0ra3NK\nSEpVTWVEaXEzc3ZIeloySXBqVk01SVNsVmtzCk5weWJCSGNlb2FRM0RWVEYwTHlC\nTVFBd1cvYlZrNlQ4TFRydFNzWXNicE0KLS0tIFZ5WllRNEI0Q3hQaVU2WjhGNDFr\nLy9pSXU5Y2FINy9LbXg4dzdHREQveE0KyxWDDyRpo0eTIXj0lHQtOunLtAP/Q+70\n+GvfjW7WXHXvXyg6CXzpCy6F6UWie4LHO9VrJM2mTjoh+q4l5DT6CA==\n-----END AGE ENCRYPTED FILE-----\n"
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.