Compare commits

...

559 Commits

Author SHA1 Message Date
Jörg Thalheim
7b49653aaf add fake_sudo 2025-03-28 16:59:19 +00:00
Qubasa
1beb9a8ca0 test_secrets_upload: Don't prepend sudo inside test; Improve secret upload test 2025-03-28 16:59:19 +00:00
Qubasa
d1a79653fe checks/installation-without-system: modify to install through normal user instead of root 2025-03-26 18:37:31 +01:00
RTUnreal
351ce1414a clan_cli: fix support for non-root deployment user 2025-03-26 18:37:31 +01:00
DavHau
e2ccd979ed vars/prompts: print var name even if custom description is set 2025-03-26 10:48:05 +00:00
renovate[bot]
f5f3f96809 chore(deps): update treefmt-nix digest to 61c8834 2025-03-26 10:10:09 +00:00
Mic92
59253a9c71 Merge pull request 'ADR: init clan api as library decision record' (#2975) from hsjobeki/clan-core:adr/architecture into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2975
2025-03-26 10:01:55 +00:00
Johannes Kirschbauer
aa03adc581 ADR: init clan api as library decision record 2025-03-26 09:52:05 +00:00
Mic92
ffd84d50f7 Merge pull request 'Fix(classgen): support number conversion from jsonschema' (#3119) from hsjobeki/clan-core:class-fix into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3119
2025-03-26 09:45:09 +00:00
Johannes Kirschbauer
679387e4ba Fix(classgen): support number conversion from jsonschema 2025-03-25 19:27:01 +01:00
hsjobeki
1d60f94cc5 Merge pull request 'docs/configure: Remove reference to unfinished feature' (#3097) from kenji/clan-core:docs-remove-upcoming into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3097
2025-03-25 18:12:09 +00:00
Mic92
1235177541 Merge pull request 'Enable all pytest without core' (#3118) from enable-more-macos into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3118
2025-03-25 17:41:04 +00:00
Jörg Thalheim
5c08e9a38d add missing lock around "flake" "lock" 2025-03-25 18:30:18 +01:00
Jörg Thalheim
28dd54d866 make gnupg a dependency of sops
if anything uses a gnupg key, we need the gnupg binary.
Sucks a bit, but at least it makes it work everywhere.
2025-03-25 18:30:18 +01:00
Jörg Thalheim
5baf37f7e9 fix gpg key fixture on macOS
macOS has length limitations for unix sockets, which are violated by the
default length of temporary directories.
2025-03-25 18:30:18 +01:00
Jörg Thalheim
ff669e2957 move git_repo fixture to its own file for consistency 2025-03-25 18:30:11 +01:00
Jörg Thalheim
8d4c1839e7 use pre-generate gpg key for tests
this is a bit faster.
2025-03-25 18:30:11 +01:00
Jörg Thalheim
0765d981c6 enable python tests without core on macOS 2025-03-25 18:29:49 +01:00
Jörg Thalheim
10c27a0152 skip sshd-based tests on macOS for now 2025-03-25 18:29:49 +01:00
Mic92
ccb5af9565 Merge pull request 'docs/index: Clear up API Reference description' (#3098) from kenji/clan-core:docs-overview into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3098
2025-03-25 09:34:18 +00:00
renovate[bot]
828eff528a chore(deps): lock file maintenance 2025-03-25 02:10:52 +00:00
renovate[bot]
cbf47580cf chore(deps): update nixpkgs digest to 1750f3c 2025-03-25 01:50:24 +00:00
renovate[bot]
355ac57ccb chore(deps): update nixpkgs digest to dd61313 2025-03-24 19:30:24 +00:00
renovate[bot]
227e293421 chore(deps): update typescript-eslint monorepo to v8.28.0 2025-03-24 17:20:18 +00:00
renovate[bot]
9b3621b516 chore(deps): update dependency @types/node to v22.13.13 2025-03-24 11:20:15 +00:00
renovate[bot]
62f09a450f chore(deps): update dependency vite to v6.2.3 2025-03-24 10:30:17 +00:00
Michael Hoang
95282bd880 Merge pull request 'checks/flash: fix on aarch64-linux' (#3109) from push-wyyyplplwnpy into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3109
2025-03-24 10:23:24 +00:00
Michael Hoang
7a49ec252e checks/flash: support aarch64-linux 2025-03-24 19:13:20 +09:00
Michael Hoang
5f9ee97cab Merge pull request 'checks/installation-without-system: support aarch64-linux' (#3108) from push-wnsmqwtkplqw into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3108
2025-03-24 09:47:53 +00:00
Michael Hoang
c6be9bbf07 checks/installation-without-system: add aarch64-linux facter.json
This doesn't fix the test on `aarch64-linux` but brings it inline with
where `test-installation` fails.
2025-03-24 18:37:46 +09:00
Michael Hoang
d77ae5eed0 Merge pull request 'checks/backups: don't hardcode system' (#3107) from push-unpltryrzlsx into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3107
2025-03-24 08:38:28 +00:00
Michael Hoang
3c2888edc7 checks: don't build test machines as they may be system-less now 2025-03-24 17:27:36 +09:00
Michael Hoang
b0f23353ef checks/backups: don't hardcode system 2025-03-24 17:26:48 +09:00
renovate[bot]
3fccccc092 chore(deps): update dependency @types/node to v22.13.12 2025-03-24 06:40:15 +00:00
Michael Hoang
0a5d1bf322 Merge pull request 'checks: disable all failing aarch64-linux checks' (#3104) from push-zqxwrttvxuqy into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3104
2025-03-24 04:01:16 +00:00
Michael Hoang
9ca5cb7bcc checks: disable all failing aarch64-linux checks 2025-03-24 12:50:57 +09:00
renovate[bot]
cc1b356a94 chore(deps): update sops-nix digest to 67566fe 2025-03-23 04:00:13 +00:00
kenji
9aa8c1b8eb Merge pull request 'docs/configure: Fix erroneous option attribute' (#3099) from kenji/clan-core:docs-fix-3094 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3099
2025-03-22 23:27:16 +00:00
a-kenji
709d773768 docs/configure: Fix erroneous option attribute
Fixes: 3094
2025-03-22 13:05:55 -07:00
a-kenji
845abd1356 docs/index: Clear up API Reference description
The term "auto generated" gives leeway to the incorrect assumption
that this is not a curated reference that contains written documentation
especially for the rendered reference.

This is not the case.
2025-03-22 12:56:51 -07:00
a-kenji
2b4a4f2422 docs/configure: Remove reference to unfinished feature 2025-03-22 12:53:59 -07:00
Mic92
82da5b6734 Merge pull request 'don't add nixpkgs to nix registry to not conflict with nixpkgs' (#3096) from nixpkgs-conflict into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3096
2025-03-22 16:16:27 +00:00
Jörg Thalheim
33a9fd8d3d tests/installer/client: increase RAM 2025-03-22 17:07:52 +01:00
Jörg Thalheim
4beb097a95 don't add nixpkgs to nix registry to not conflict with nixpkgs
NixOS is already doing this for us.
2025-03-22 14:45:53 +01:00
renovate[bot]
b4cd62b9f8 chore(deps): update nixpkgs digest to 94c4dbe 2025-03-22 04:00:29 +00:00
renovate[bot]
ee7b98c34d chore(deps): update sops-nix digest to b775692 2025-03-21 22:50:10 +00:00
renovate[bot]
8552d4b3bd chore(deps): update dependency eslint to v9.23.0 2025-03-21 20:40:14 +00:00
renovate[bot]
375edcff81 chore(deps): update dependency @eslint/js to v9.23.0 2025-03-21 20:20:13 +00:00
renovate[bot]
3183b26777 chore(deps): update nixpkgs digest to bfa9810 2025-03-21 19:00:27 +00:00
Luis Hebendanz
0feacaf300 Merge pull request 'sshd: Fix missing cfg.fqdn regression' (#3087) from Qubasa/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3087
2025-03-21 16:47:25 +00:00
Qubasa
6917021996 sshd: Fix missing cfg.fqdn regression 2025-03-21 17:45:25 +01:00
lassulus
3965f7b59f Merge pull request 'clan-cli: cleanup broken deployment cache' (#3066) from fix_caching into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3066
2025-03-21 15:49:22 +00:00
renovate[bot]
610a70e4f8 chore(deps): update nixpkgs digest to 7344a3b 2025-03-21 12:30:23 +00:00
Jörg Thalheim
6134eb0293 tests/sshd: add a 5 second timeout for sshd to start 2025-03-21 12:41:36 +01:00
renovate[bot]
62e9fe8f9f chore(deps): update dependency @types/node to v22.13.11 2025-03-21 09:20:13 +00:00
renovate[bot]
5bc2d00014 chore(deps): update nixpkgs digest to 2a725d4 2025-03-20 21:20:28 +00:00
renovate[bot]
616b294b8c chore(deps): update nixpkgs digest to 44e422b 2025-03-20 20:20:27 +00:00
Michael Hoang
2d7b92b3f9 Merge pull request 'networking: add a default value for targetHost' (#3080) from push-rlvulrtxqkyq into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3080
2025-03-20 14:10:19 +00:00
Michael Hoang
0487670d30 networking: add a default value for targetHost 2025-03-20 22:45:19 +09:00
Michael Hoang
4cd174b268 Merge pull request 'sshd: trust own ed25519 host key as a known host' (#3077) from push-opymuwrqqqvv into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3077
2025-03-20 13:44:25 +00:00
Michael Hoang
a8b257f32c sshd: trust own ed25519 host key as a known host 2025-03-20 18:40:32 +09:00
Qubasa
047b767054 clan-cli: cleanup broken deployment cache 2025-03-20 00:17:36 -07:00
Michael Hoang
c74d23b799 Merge pull request 'checks: use pkgs.nixVersions.latest until pkgs.nix is 2.26+' (#3076) from push-vswxxyynxtmz into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3076
2025-03-20 07:01:57 +00:00
Michael Hoang
850627c5c6 checks: use pkgs.nixVersions.latest until pkgs.nix is 2.26+ 2025-03-20 15:52:13 +09:00
renovate[bot]
60d56c4e3b chore(deps): update typescript-eslint monorepo to v8.27.0 2025-03-20 01:20:15 +00:00
renovate[bot]
4911901f7c chore(deps): update sops-nix digest to 1770be8 2025-03-19 18:10:10 +00:00
Mic92
a96860a24b Merge pull request 'pytests: use /tmp on macos to avoid unix socket issues' (#3073) from nixpkgs-update into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3073
2025-03-19 17:45:15 +00:00
Jörg Thalheim
c429b41d2e pytests: use /tmp on macos to avoid unix socket issues 2025-03-19 18:35:38 +01:00
Mic92
fe305f7f47 Merge pull request 'Decisions/clanModules: Add example borgbackup as real world example' (#3070) from hsjobeki/clan-core:decisions-01 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3070
2025-03-19 16:39:59 +00:00
Johannes Kirschbauer
591d397df9 Decisions/clanModules: Add example borgbackup as real world example 2025-03-19 16:39:52 +00:00
Mic92
8231979bae Merge pull request 'Silence mypy error after nixpkgs update' (#3072) from nixpkgs-update into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3072
2025-03-19 16:39:32 +00:00
Jörg Thalheim
6899461d0d disabe pytests on macOS for now 2025-03-19 17:33:27 +01:00
Jörg Thalheim
16b067d291 tests/fixtures_flakes: remove unused remote flag 2025-03-19 16:55:30 +01:00
Jörg Thalheim
93cbe62765 always resolve symlinks for TemporaryDirectory
On macOS mktemp returns a temporary directory in a symlink.
Nix has a bug where it won't accept path:// located in a symlink.
This avoid this issue by always resolving symlinks as returned by
TemporaryDirectory.
2025-03-19 16:47:18 +01:00
Jörg Thalheim
7fef29d7aa make sshd test work on macOS 2025-03-19 15:55:20 +01:00
Jörg Thalheim
952d1facce vm-manager: ignore interface between GObject and ListModel 2025-03-19 15:29:03 +01:00
Jörg Thalheim
a565a85a5e clan-vm-manager: support basic devshell on macOS 2025-03-19 15:29:03 +01:00
renovate[bot]
3d5ef5e909 chore(deps): update nixpkgs digest to 3549532 2025-03-19 13:40:12 +00:00
Luis Hebendanz
a5c5033273 Merge pull request 'clan-cli: machines delete: delete the machine's vars and secrets' (#2994) from lopter/clan-core:lo-machines-delete into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2994
2025-03-19 12:25:48 +00:00
Louis Opter
0ee0351e3e clan-cli: add DavHau's explanation about the with_core pytest marker
See: https://git.clan.lol/clan/clan-core/pulls/2994#issuecomment-22542
2025-03-19 10:53:38 +00:00
Louis Opter
c02f19205f clan-cli: tests: call SopsSetup.init while setting up fixtures
We do this by introducing `flake_with_sops` fixture, that calls the
init method ahead of the test. We did not want to do this in the `flake`
fixture since not all tests using the `flake` fixture need to have sops
setup.
2025-03-19 10:53:38 +00:00
Louis Opter
dbcb8d6a4c clan-cli: don't try to delete a dir that doesn't exist in the pass vars backend
Do not crash in `delete_store`, if the machine has no vars, or the store
has been deleted already.
2025-03-19 10:53:38 +00:00
Louis Opter
039b309255 clan-cli: do not crash if a machine being deleted is missing from the inventory
We implement that by actually raising `KeyError` in `inventory.delete_by_path`
(as advertised in the docstring), since it makes more sense to catch a
`KeyError` than a generic `ClanError`.
2025-03-19 10:53:38 +00:00
Louis Opter
538374558d clan-cli: machines delete: delete the machine's vars and secrets
When a machine is deleted with `clan machines delete`, remove its
vars and legacy secrets, and update any secrets that reference the
machine's key.

This command is a superset of `clan secrets machine delete`, and I am
wondering if we could remove the `clan secrets machine` subcommand,
unless there is an use case for having a machine defined without its
key, and any secrets/vars?

Note:

- This deletes the `ListSecretsOptions` dataclass, as it did not seem to
  bring any value, especially since `list_secrets` was receiving its
  individual members instead of the whole dataclass. We can always bring
  it back if complexity grows to demand it.
2025-03-19 10:53:38 +00:00
Louis Opter
ef5ad09b2d clan-cli: add delete and delete_store to StoreBase
- `delete` lets you delete a specific var under a specific generator;
- `delete_store` deletes an entire store.

The `delete` method could be useful to "garbage-collect" unused vars as
a machine's configuration changes.

The `delete_store` method can be used to delete all the vars for a
machine when the machine is deleted. The current behavior is to leave
everything behind.

Important point:

- `delete_store` needs to be idempotent because public and
  "private"/"secret" vars for a machine can share the same physical
  store (directory), and deleting either type of store (public or
  private) will delete both.
2025-03-19 10:53:38 +00:00
Louis Opter
9780463e6a clan-cli: add an integration test for clan machines delete
This tests the changes made to that command to clean-up vars and secrets
when a machine is deleted.
2025-03-19 10:53:38 +00:00
Louis Opter
cac4b1200c clan-cli: tests/age_keys.py add notes, move function to check sops recipients
This supports the new integration test for `clan machines delete`.
2025-03-19 10:53:38 +00:00
Mic92
c8db27340e Merge pull request 'Fix clan machines create' (#3040) from Qubasa/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3040
2025-03-19 10:53:17 +00:00
Jörg Thalheim
31a9c74e88 deduplicate CLAN_CORE/CLAN_CORE_PATH environment variables 2025-03-19 10:30:52 +00:00
Qubasa
dc8bfab65d clan-cli: Fix templates not downloading template, Make templates use Flake cache, Fix flake cache exception on conditional attribute, add more tests 2025-03-19 10:30:52 +00:00
DavHau
33abb7ecd7 docs: add guide for testing 2025-03-19 09:43:05 +00:00
renovate[bot]
fcbdae9d09 chore(deps): update treefmt-nix digest to adc195e 2025-03-19 08:10:09 +00:00
Michael Hoang
27b5680441 Merge pull request 'checks: ensure updating hardware config doesn't require system' (#3067) from fix/update-hardware-config-without-system into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3067
2025-03-19 06:53:50 +00:00
Michael Hoang
f13971167f checks: ensure updating hardware config doesn't require system 2025-03-19 15:28:52 +09:00
renovate[bot]
e75b5f3a2e chore(deps): lock file maintenance 2025-03-18 23:10:46 +00:00
renovate[bot]
d5c0a2eb9c chore(deps): update nixpkgs digest to 9bc8a90 2025-03-18 15:50:09 +00:00
renovate[bot]
8cc8d09a11 chore(deps): update treefmt-nix digest to b3b938a 2025-03-18 15:00:13 +00:00
Mic92
dfa3305450 Merge pull request 'nixpkgs-update' (#3061) from nixpkgs-update into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3061
2025-03-18 14:42:16 +00:00
Jörg Thalheim
94415dfd0e use pathlib.iterdir() everywhere 2025-03-18 15:34:06 +01:00
renovate[bot]
6fb5bca801 chore(deps): update nixpkgs digest to 0964789 2025-03-18 14:20:23 +00:00
renovate[bot]
4162810ee1 chore(deps): update disko digest to 0d8c6ad 2025-03-18 14:08:30 +00:00
Mic92
0b3badb0ef Merge pull request 'chore(deps): update dependency typescript to v5.8.2' (#3058) from typescript into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3058
2025-03-18 14:00:32 +00:00
Jörg Thalheim
6a5954ad77 remove unused typescript directive 2025-03-18 14:52:22 +01:00
Mic92
02231b979b Merge pull request 'Update eslint' (#3057) from eslint into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3057
2025-03-18 13:51:36 +00:00
Jörg Thalheim
028f6a4d3d prune npm deps 2025-03-18 14:43:30 +01:00
Jörg Thalheim
170908db7b address eslint warnings 2025-03-18 14:40:16 +01:00
renovate[bot]
39e6534dbb chore(deps): update typescript-eslint monorepo to v8 2025-03-18 14:26:21 +01:00
renovate[bot]
71809c1bdc chore(deps): update dependency eslint to v9 2025-03-18 14:26:19 +01:00
Mic92
eecedf95e4 Merge pull request 'cli: increase timeout for pytest' (#3056) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3056
2025-03-18 13:18:09 +00:00
Mic92
a208a9973c Merge pull request 'flake: switch back to using main branch of sops-nix' (#3050) from bump/sops-nix into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3050
2025-03-18 13:11:29 +00:00
renovate[bot]
d276d2faea chore(deps): update dependency typescript to v5.8.2 2025-03-18 13:10:11 +00:00
Mic92
d470283dca Merge pull request 'fix(deps): update dependency @solid-primitives/storage to v4' (#3046) from renovate/solid-primitives-storage-4.x into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3046
2025-03-18 13:08:51 +00:00
Mic92
88dab7d8bd Merge pull request 'chore(deps): update dependency vitest to v3' (#3044) from renovate/major-vitest-monorepo into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3044
2025-03-18 13:07:47 +00:00
Mic92
8474a0aaef Merge pull request 'chore(deps): update dependency @types/node to v22' (#3037) from renovate/node-22.x into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3037
2025-03-18 13:07:29 +00:00
Jörg Thalheim
5ab2f206ea cli: increase timeout for pytest 2025-03-18 14:04:43 +01:00
Michael Hoang
ea8037006f flake: switch back to using main branch of sops-nix 2025-03-18 12:55:13 +00:00
renovate[bot]
3a682a6b3e fix(deps): update dependency @solid-primitives/storage to v4 2025-03-18 12:50:42 +00:00
renovate[bot]
0556ea624f chore(deps): update dependency vitest to v3 2025-03-18 12:50:30 +00:00
renovate[bot]
8671fd7407 chore(deps): update dependency @types/node to v22 2025-03-18 12:50:14 +00:00
Mic92
3a9f0eb608 Merge pull request 'Fix broken installation tests' (#3055) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3055
2025-03-18 12:49:14 +00:00
Jörg Thalheim
1736b0f539 work around in installation test by using newer nix version 2025-03-18 13:29:28 +01:00
Jörg Thalheim
eb375f3d81 tests: fix warning about invalid nix registry 2025-03-18 13:29:28 +01:00
renovate[bot]
6162b82adb fix(deps): update tanstack-query monorepo 2025-03-18 12:10:39 +00:00
renovate[bot]
085189d1c4 fix(deps): update dependency nanoid to v5.1.4 2025-03-18 12:00:33 +00:00
renovate[bot]
3cb22ad2a1 chore(deps): update dependency vite to v6 2025-03-18 11:40:34 +00:00
Luis Hebendanz
27269d4ed9 Merge pull request 'ADR: init clanModules architecture decision' (#2838) from hsjobeki/clan-core:adr/clanModules into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2838
Reviewed-by: kenji <aks.kenji@protonmail.com>
Reviewed-by: pinpox <clan@pablo.tools>
Reviewed-by: Luis Hebendanz <consulting@qube.email>
Reviewed-by: DavHau <d.hauer.it@gmail.com>
2025-03-18 11:15:16 +00:00
Johannes Kirschbauer
7cbedc74a5 ADR: init clanModules architecture decision
ADR: improve after review

improve wording

improve based on feedback

decisions/clanModules
2025-03-18 11:14:16 +00:00
renovate[bot]
5ac30a767b chore(deps): update dependency jsdom to v26 2025-03-12 15:01:24 +00:00
renovate[bot]
89c6bcda4d chore(deps): update actions/checkout action to v4 2025-03-12 13:01:16 +00:00
renovate[bot]
51da020de2 fix(deps): update tanstack-query monorepo 2025-03-12 12:12:37 +00:00
renovate[bot]
e943d8531f fix(deps): update dependency nanoid to v5.1.3 2025-03-12 12:01:17 +00:00
renovate[bot]
13b9c23db9 fix(deps): update dependency @solidjs/router to ^0.15.0 2025-03-12 11:12:36 +00:00
renovate[bot]
ad43f323b8 fix(deps): update dependency @solid-primitives/storage to v3.8.0 2025-03-12 11:01:19 +00:00
renovate[bot]
aeb3cc4428 chore(deps): update typescript-eslint monorepo to v7.18.0 2025-03-12 10:12:37 +00:00
renovate[bot]
d81ca7206b fix(deps): update dependency @modular-forms/solid to ^0.25.0 2025-03-12 09:22:33 +00:00
renovate[bot]
0011cf594a chore(deps): update eslint monorepo 2025-03-12 09:12:38 +00:00
renovate[bot]
41cd4533ba chore(deps): update dependency vite-plugin-solid to v2.11.6 2025-03-12 09:01:19 +00:00
renovate[bot]
c15544e928 chore(deps): update dependency vite to v5.4.14 2025-03-12 08:02:36 +00:00
renovate[bot]
fa0fe23985 chore(deps): update dependency solid-devtools to ^0.33.0 2025-03-12 07:52:35 +00:00
renovate[bot]
1497e76bc2 chore(deps): update dependency vitest to v1.6.1 2025-03-12 07:42:29 +00:00
renovate[bot]
b3d9c23e39 chore(deps): update dependency eslint-plugin-tailwindcss to v3.18.0 2025-03-12 07:32:34 +00:00
renovate[bot]
5520641feb chore(deps): update dependency daisyui to v4.12.24 2025-03-12 07:12:43 +00:00
renovate[bot]
97f5a6bd4c chore(deps): update dependency prettier to v3.5.3 2025-03-12 07:01:20 +00:00
renovate[bot]
3b2b5db84a chore(deps): update dependency tailwindcss to v3.4.17 2025-03-12 05:52:38 +00:00
renovate[bot]
84da7d437d fix(deps): update dependency material-icons to v1.13.14 2025-03-12 05:42:37 +00:00
renovate[bot]
b2db2c7abc fix(deps): update dependency corvu to v0.7.2 2025-03-12 05:32:47 +00:00
renovate[bot]
cb104b700d fix(deps): update dependency solid-markdown to v2.0.14 2025-03-12 05:12:55 +00:00
renovate[bot]
41054885db chore(deps): update dependency @types/node to v20.17.24 2025-03-12 05:01:29 +00:00
renovate[bot]
70c63221ec chore(deps): update dependency jsdom to v24.1.3 2025-03-11 17:17:25 +00:00
renovate[bot]
9c130c73e4 chore(deps): update dependency autoprefixer to v10.4.21 2025-03-11 16:57:31 +00:00
Mic92
178fff0618 Merge pull request 'nix fmt: renovate.json' (#3015) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3015
2025-03-11 16:57:08 +00:00
Jörg Thalheim
6324b495ee nix fmt: renovate.json 2025-03-11 17:56:52 +01:00
Mic92
ce7a70f9e1 Merge pull request 'renovate: enable recommend config/lock files/nix' (#3013) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3013
2025-03-11 16:43:51 +00:00
Jörg Thalheim
7102af9bd9 renovate: enable recommend config/lock files/nix 2025-03-11 17:43:31 +01:00
Mic92
b38fddaf29 Merge pull request 'drop renovate json' (#3012) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3012
2025-03-11 16:38:06 +00:00
Jörg Thalheim
e7ffcedd14 drop renovate json
we just use the defaults in clan-infra
2025-03-11 16:38:00 +00:00
Mic92
b5a66e767b Merge pull request 'renovate: also update flake.lock' (#3011) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3011
2025-03-11 16:33:00 +00:00
Jörg Thalheim
854d0fa83e renovate: also update flake.lock 2025-03-11 17:31:38 +01:00
Mic92
4ccf5ca373 Merge pull request 'renovate: enable dependency dashboard' (#3009) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3009
2025-03-11 16:26:55 +00:00
Jörg Thalheim
781d439567 renovate: enable dependency dashboard 2025-03-11 17:23:42 +01:00
Mic92
68e00ff613 Merge pull request 'chore(deps): update dependency @tailwindcss/typography to v0.5.16' (#3006) from renovate/tailwindcss-typography-0.x-lockfile into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3006
2025-03-11 15:39:10 +00:00
Mic92
828028e4b3 Merge pull request 'chore(deps): update dependency @floating-ui/dom to v1.6.13' (#3005) from renovate/floating-ui-dom-1.x-lockfile into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3005
2025-03-11 15:38:24 +00:00
renovate[bot]
b48d07f5c5 chore(deps): update dependency @tailwindcss/typography to v0.5.16 2025-03-11 15:31:37 +00:00
renovate[bot]
ea8c9ed649 chore(deps): update dependency @floating-ui/dom to v1.6.13 2025-03-11 15:31:33 +00:00
Mic92
68cb04c958 Merge pull request 'chore: Configure Renovate' (#3000) from renovate/configure into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3000
2025-03-11 15:06:28 +00:00
renovate[bot]
b8cb85fc72 Add renovate.json 2025-03-11 15:02:50 +00:00
Mic92
bdb97308d0 Merge pull request 'remove clan-bot' (#2999) from ci into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2999
2025-03-11 15:00:53 +00:00
Jörg Thalheim
9708bdc6e7 remove clan-bot
gitea has auto-merge builtin, so we don't need the clan-bot.
2025-03-11 15:02:41 +01:00
Jörg Thalheim
9ac8a45f1d actually hide test-fixture from user
if we actually want to avoid the dependency on this facter json, we
cannot expose this as a flake input because nix flake archive will have
to download this on each deployment step.
2025-03-11 12:23:59 +00:00
Jörg Thalheim
a14fe1aef8 try to reproduce CI error with newer nix version 2025-03-11 12:23:59 +00:00
Jörg Thalheim
b1401d6e6b fix only the first generator of each machine beeing re-encrypted 2025-03-11 12:09:00 +01:00
Jörg Thalheim
f882c86fb0 don't log cache miss by default
This is expected and happens regular, so there is no value in logging
this.
2025-03-11 12:03:55 +01:00
Jörg Thalheim
98d566c46e add test for parsing ssh options 2025-03-11 11:27:04 +01:00
Jörg Thalheim
c4ec4ccb3f checks/morph: after flake update, increase memory size to 2048 2025-03-11 09:46:54 +00:00
Clan Merge Bot
5a6677379a update flake lock - 2025-03-10T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/fa5746ecea1772cf59b3f34c5816ab3531478142?narHash=sha256-xFnU%2BuUl48Icas2wPQ%2BZzlL2O3n8f6J2LrzNK9f2nng%3D' (2025-02-15)
  → 'github:nix-community/disko/19c1140419c4f1cdf88ad4c1cfb6605597628940?narHash=sha256-WK%2BPZHbfDjLyveXAxpnrfagiFgZWaTJglewBWniTn2Y%3D' (2025-02-25)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/32ea77a06711b758da0ad9bd6a844c5740a87abd?narHash=sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm%2BzmZ7vxbJdo%3D' (2025-02-01)
  → 'github:hercules-ci/flake-parts/f4330d22f1c5d2ba72d3d22df5597d123fdb60a9?narHash=sha256-%2Bu2UunDA4Cl5Fci3m7S643HzKmIDAe%2BfiXrLqYsR2fs%3D' (2025-03-07)
• Updated input 'nixpkgs':
    'https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre762233.02032da4af07/nixexprs.tar.xz?narHash=sha256-%2BvOiMQwHEYBbWgvK//cuUqHZQ/y3DddCLyxZAbDdpnM%3D' (1980-01-01)
  → 'https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre764393.ed0b1881565c/nixexprs.tar.xz?narHash=sha256-Xre00/fcpD/SxZZfxRuMSu7YOBCY6vOfgFBYKNntox8%3D' (1980-01-01)
2025-03-11 09:46:54 +00:00
DavHau
30d19d088f docs: move contributing+debugging to section contributing 2025-03-11 15:19:46 +07:00
Luis Hebendanz
f3c45eb23e Merge pull request 'pkgs/webview-lib: Fix version' (#2991) from kenji/clan-core:webview-version into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2991
2025-03-10 13:20:38 +00:00
a-kenji
eaac6c76e2 pkgs/webview-lib: Fix version 2025-03-10 13:20:38 +00:00
Luis Hebendanz
0939b29a8e Merge pull request 'clan-cli/tests: limit jobs to 16' (#2986) from DavHau/clan-core:dave into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2986
2025-03-10 13:20:18 +00:00
DavHau
a2a395cdb0 clan-cli/tests: limit jobs to 16
This reduces overload on the CI, as it already runs multiple test instances in parallel (with-core, without-core, etc), and otherwise would spawn 96 workers for each of those.
2025-03-10 13:20:18 +00:00
Luis Hebendanz
df7429dbe7 Merge pull request 'fix: clan machines install on machines without hardware configuration' (#2983) from fix/systemless-installs into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2983
Reviewed-by: kenji <aks.kenji@protonmail.com>
2025-03-10 13:19:17 +00:00
Michael Hoang
362faaf063 checks: use facter.json from external test-fixtures repo 2025-03-10 12:30:03 +09:00
Michael Hoang
e215a9db6e install: let nixos-anywhere determine where to build automatically
This fixes installing machines that don't have `system` defined i.e.
when running `clan machines install` with `--update-hardware-config`.
2025-03-10 12:30:03 +09:00
Michael Hoang
a5dd76b66d checks: don't expose systems that can't be evaluated 2025-03-10 11:58:32 +09:00
Michael Hoang
4472c51c25 checks: test installation on system-less systems 2025-03-10 11:58:32 +09:00
Michael Hoang
c6cf9d1336 checks/installation: use test-flake instead of self 2025-03-10 11:58:32 +09:00
Clan Merge Bot
9b6e42790e update flake lock - nixpkgs - 2025-03-10T00:00+00:00
Flake lock file updates:

• Updated input 'nixpkgs':
    'https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre762233.02032da4af07/nixexprs.tar.xz?narHash=sha256-%2BvOiMQwHEYBbWgvK//cuUqHZQ/y3DddCLyxZAbDdpnM%3D' (1980-01-01)
  → 'https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre764393.ed0b1881565c/nixexprs.tar.xz?narHash=sha256-Xre00/fcpD/SxZZfxRuMSu7YOBCY6vOfgFBYKNntox8%3D' (1980-01-01)
2025-03-10 00:00:46 +00:00
a-kenji
547b012e0b clanModules/mycelium: Allow by default, if adding the module 2025-03-09 23:49:03 +00:00
DavHau
9797ef792a vars+facts: use bwrap only if supported 2025-03-09 13:52:15 +07:00
Luis Hebendanz
fe0de90a28 Merge pull request 'Fix iwd space handling' (#2980) from Qubasa/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2980
2025-03-07 13:34:48 +00:00
Qubasa
539fd30206 clan-cli: treefmt fix to iwd module 2025-03-07 14:26:37 +01:00
Guilhem Saurel
a11d5471ec Fix iwd space handling
ref man iwd.network:

> Key-value lines contain a setting key, an equal sign and the value of
> the setting. Whitespace preceding the key, the equal sign or the value,
> is ignored. The key must be a continuous string of alphanumeric and
> underscore characters and minus signs only. The value starts at the
> first non-whitespace character after the first equal sign on the line
> and ends at the end of the line and must be correctly UTF-8-encoded.
> […]
> String values, including file
> paths and hexstrings, are written as is except for five characters that
> may be backslash-escaped: space, \t, \r, \n and backslash itself.
> The latter three must be escaped. A space character must be escaped if
> it is the first character in the value string and is written as \s.

I guess this is what is expected then:
```
$ echo -e "  \t \r \\ "
 \

$ echo -e "  \t \r \\ " | sed "s=\\\=\\\\\\\=g;s=\t=\\\t=g;s=\r=\\\r=g;s=^ =\\\s="
\s \t \r \\
```
2025-03-07 14:26:37 +01:00
Luis Hebendanz
19f2facbce Merge pull request 'clan-cli flake: make lix compatible' (#2970) from lix-compat into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2970
2025-03-07 13:21:45 +00:00
Qubasa
468a25034e clan-cli: Make Lix compatible again 2025-03-07 14:06:35 +01:00
Johannes Kirschbauer
a2b76eb5a2 Inventory: rename internal inventory toplevel attribute to 'inventoryClass' 2025-03-07 12:30:29 +00:00
DavHau
ba0ed30997 update nixpkgs 2025-03-07 14:30:01 +07:00
DavHau
2a4d2c9cb5 switch to nixpkgs hosteded by cache.nixos.org
take 2 on https://git.clan.lol/clan/clan-core/pulls/2921
2025-03-07 07:20:07 +00:00
Michael Hoang
4c1e74fae6 nixos/clan: rename setDefaults to enableRecommendedDefaults 2025-03-05 03:37:41 +00:00
pinpox
cee62bf168 Merge pull request 'Automatic updates (phase 1)' (#2914) from pinpox/clan-core:auto-update-module into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2914
2025-03-04 10:26:20 +00:00
Pablo Ovelleiro Corral
a865213894 Add auto-upgrade module 2025-03-04 10:09:37 +01:00
Johannes Kirschbauer
d8f9375580 Docs: add comment where actual contributing.md is located 2025-03-04 15:16:54 +09:00
Luis Hebendanz
526072806f Merge pull request 'docs/repo-layout: Remove infra section' (#2964) from kenji/clan-core:docs/remove-infra into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2964
Reviewed-by: Enzime <enzime@noreply.git.clan.lol>
2025-03-03 11:34:45 +00:00
a-kenji
91a19d9ea9 docs/repo-layout: Remove infra section
Remove the public infra section, as it uses a bit of unfortunate
wording. It suggests we would add anyone to our infrastructure as an
admin.
2025-03-03 11:34:45 +00:00
Luis Hebendanz
38c7644692 Merge pull request 'docs/CONTRIBUTING: Remove internal tools documentation to streamline' (#2962) from kenji/clan-core:docs/remove-internal into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2962
Reviewed-by: Enzime <enzime@noreply.git.clan.lol>
2025-03-03 11:34:34 +00:00
a-kenji
726f2ab5f8 docs/CONTRIBUTING: Remove internal tools documentation to streamline
Remove our internal developer tools documentation to streamline the
CONTRIBUTING.md guide and to not confuse external contributors.
2025-03-03 11:34:34 +00:00
a-kenji
5918620535 docs/CONTRIBUTING: Add missing article 2025-03-02 20:44:42 -08:00
a-kenji
58e85eda9c clanModules/iwd: Fix conversion link 2025-03-02 20:27:40 -08:00
a-kenji
e98e817941 docs: Fix numbered markdown list 2025-03-02 20:10:43 -08:00
a-kenji
fe92c7d1e6 docs/CONTRIBUTING: Clarify wrong suggestion about debugging dependent tools 2025-03-03 03:57:33 +00:00
a-kenji
4222f9788c docs/site: Fix flake-parts link 2025-03-03 03:53:49 +00:00
a-kenji
3d80423259 docs/CONTRIBUTING: Fix data-mesher reference name 2025-03-02 19:42:57 -08:00
Johannes Kirschbauer
186e81d8b9 Tests: migrate backup tests to use inventory 2025-03-03 02:28:03 +00:00
Qubasa
212c899767 clan-cli: Revert generating facts in clan facts list, for consistency 2025-03-03 01:40:40 +01:00
Luis Hebendanz
312c12c98f Merge pull request 'clan-cli: Fix wrong clan vars generate regression added by a903a9028b555223ddcb897cf8a8fb198fb991b4' (#2951) from Qubasa/clan-core:fix_regression into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2951
2025-03-02 19:05:23 +00:00
Qubasa
2ec4e49650 clan-cli: Fix wrong clan vars generate regression added by a903a9028b 2025-03-02 19:53:17 +01:00
kenji
4e5b4a1b80 Merge pull request 'clanModules/root-password: don't deploy plain text password' (#2950) from vdbe/clan-core:clanModules/root-password/dont-deploy-plain-text into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2950
2025-03-02 18:43:38 +00:00
vdbe
ccb3bdb740 clanModules/root-password: don't deploy plain text password 2025-03-02 17:52:03 +01:00
Luis Hebendanz
a903a9028b Merge pull request 'clan-cli: Fix get_all_facts forgetting to generate facts before getting them' (#2949) from Qubasa/clan-core:other_fixes into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2949
2025-03-02 14:57:59 +00:00
Qubasa
ba28691747 clan-cli: Fix get_all_facts forgetting to generate facts before getting them 2025-03-02 15:07:57 +01:00
Luis Hebendanz
e7aa5cfb4e Merge pull request 'templates: Remove description attribute from templates' (#2933) from kenji/clan-core:templates/remove-description into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2933
Reviewed-by: Enzime <enzime@noreply.git.clan.lol>
2025-03-02 13:45:59 +00:00
a-kenji
8b74147721 templates: Remove description attribute from templates
Remove the `description` flake attribute from templates.
It has limited usefulness, is unset, is another thing the user has to
set and is confronted with.

It seems better to omit this attribute to keep the focus here on what
really matters.
2025-03-02 13:45:59 +00:00
Luis Hebendanz
299180703e Merge pull request 'clanModules/machine-id: fix value' (#2948) from vdbe/clan-core:fix/clanmodules/machine-id into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2948
2025-03-02 13:44:48 +00:00
vdbe
6c941deb96 clanModules/machine-id: fix value 2025-03-02 10:41:35 +01:00
Michael Hoang
39761946a0 vars/sops: fix clan vars fix missing machine name in error message 2025-03-02 08:22:23 +07:00
Luis Hebendanz
b71e16dd5d Merge pull request 'clan-cli: Remove can_build_locally and replace with nixos-anywhere --build-on auto' (#2944) from Qubasa/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2944
2025-03-01 17:34:17 +00:00
Qubasa
0da1a05b55 clan-cli: Remove can_build_locally and replace with nixos-anywhere --build-on auto 2025-03-01 17:52:41 +01:00
Luis Hebendanz
3551d061ce Merge pull request 'clan-cli: Make host upload function support uploading single files too' (#2943) from Qubasa/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2943
2025-03-01 16:35:19 +00:00
Qubasa
6099aeb0c6 clan-cli: Make host upload function support uploading single files too 2025-03-01 17:10:42 +01:00
lassulus
bcd6c7108a clan-cli: try to fix CI bug again 2025-02-28 04:58:42 +00:00
lassulus
d20f13abe7 clan-cli: set ssh port for nix copy 2025-02-28 04:58:42 +00:00
a-kenji
cfeda1f06d templates: Remove unneeded article 2025-02-27 11:28:48 +00:00
Luis Hebendanz
73dd981f71 Merge pull request 'docs/guide: Mention alternative secret store backends' (#2926) from kenji/clan-core:docs/add-reference-to-other-backend into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2926
2025-02-27 09:58:00 +00:00
a-kenji
bc239e104c docs/guide: Mention alternative secret store backends 2025-02-27 09:58:00 +00:00
Luis Hebendanz
bd2702df6d Merge pull request 'templates: Remove superfluous comment' (#2932) from kenji/clan-core:templates/remove-superfluuous-comment into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2932
2025-02-27 09:57:13 +00:00
a-kenji
7b0e652a7a templates: Remove superfluous comment
Remove this seemingly superfluous comment.
It is unclear what it really refers to.
Let's just remove it for brevity sake.
2025-02-27 09:57:13 +00:00
Luis Hebendanz
0c0eafe0f5 Merge pull request 'docs/guide: Deduplicate machine instructions' (#2924) from kenji/clan-core:docs/dedup-machines into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2924
2025-02-27 09:56:52 +00:00
a-kenji
3e0cd4bdfb docs/guide: Deduplicate machine instructions 2025-02-27 09:56:52 +00:00
Luis Hebendanz
2cf40fea51 Merge pull request 'tests/inventory: Drop zed-editor from the test inventory' (#2922) from kenji/clan-core:drop/zed into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2922
Reviewed-by: lassulus <clanlol@lassul.us>
2025-02-27 09:56:23 +00:00
a-kenji
40d1a76d8a tests/inventory: Drop zed-editor from the test inventory
Drop `zed-editor` from the test inventory and exchange it with `hello`.
The inventory packages are built in the tests, we don't want to build
large derivations there.
2025-02-27 09:56:23 +00:00
lassulus
60b22fdf0e clan-cli: another try to fix the CI bug 2025-02-27 08:24:28 +01:00
lassulus
cb13e7fab8 clan-cli: check if paths exist in cache check 2025-02-27 02:53:41 +01:00
Qubasa
b82a3b6085 clan-cli: Fix flake.py missing cache eviction if there is a garbage collected path 2025-02-27 01:01:50 +01:00
lassulus
44345ed28b Merge pull request 'fix(clan-cli): fix cross system' (#2935) from r17x/clan-core:fix/machine-cross-target-host into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2935
2025-02-26 09:18:08 +00:00
r17x
456b25c921 fix(clan-cli): fix cross system 2025-02-26 14:27:00 +07:00
a-kenji
dfb5e5123f docs/guide: Add devshell recommendation to getting started
Fixes: #2218
2025-02-25 18:16:50 +00:00
a-kenji
636ee65428 clanModules/zerotier: Fix documentation 2025-02-26 00:41:20 +07:00
a-kenji
cbf8685f6e templates/flake-parts: Add .envrc
Since the other template also has an `.envrc` let's keep everything
consistent.
2025-02-25 18:43:53 +07:00
Pablo Ovelleiro Corral
500af543bb Revert "switch to nixpkgs hosteded by cache.nixos.org"
This reverts commit 8f6dd4acc4.
2025-02-25 09:04:27 +01:00
Pablo Ovelleiro Corral
46971aa51f Apply suggestion 2025-02-25 08:51:51 +01:00
Pablo Ovelleiro Corral
3d83266916 Fix exists() check for age files 2025-02-25 08:51:51 +01:00
lassulus
b87768d44a Merge pull request 'clan-cli: add unit tests for test_parse_deployment_address' (#2910) from lopter/clan-core:lo-test-parse-deployment-address into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2910
2025-02-25 05:31:49 +00:00
Louis Opter
5b821c610d clan-cli: add unit tests for test_parse_deployment_address
Follow-up to #2899, more thorough than #2909.
2025-02-25 05:31:49 +00:00
Mic92
347a5a5f76 Merge pull request 'switch to nixpkgs hosteded by cache.nixos.org' (#2921) from fix-build into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2921
2025-02-24 03:48:43 +00:00
Jörg Thalheim
8f6dd4acc4 switch to nixpkgs hosteded by cache.nixos.org
This now works thanks to https://github.com/NixOS/infra/pull/562
2025-02-24 10:44:15 +07:00
Clan Merge Bot
f3cbd0b289 update flake lock - treefmt-nix - 2025-02-24T00:00+00:00
Flake lock file updates:

• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/4f09b473c936d41582dd744e19f34ec27592c5fd?narHash=sha256-yrK3Hjcr8F7qS/j2F%2Br7C7o010eVWWlm4T1PrbKBOxQ%3D' (2025-02-07)
  → 'github:numtide/treefmt-nix/3d0579f5cc93436052d94b73925b48973a104204?narHash=sha256-mL1szCeIsjh6Khn3nH2cYtwO5YXG6gBiTw1A30iGeDU%3D' (2025-02-17)
2025-02-24 00:00:55 +00:00
Qubasa
7b8a980336 clan-cli: Remove allow_uknown_placeholders flag. With upcoming nixos-anywhere patch this is not needed anymore. 2025-02-23 21:50:21 +01:00
Qubasa
d53e062024 clan-cli: Add an optional reference to an AsyncFuture to track origin of task. 2025-02-23 21:44:00 +01:00
lassulus
5ac629f549 clan-cli: use new flake caching for machines 2025-02-23 15:58:03 +01:00
lassulus
6c7fc15c0e try to fix profiles CI bug 2025-02-22 03:39:42 +00:00
lassulus
3121c5ecdb machines install: fix installation via tor 2025-02-22 03:39:42 +00:00
lassulus
ada544ef56 vars fs: fix 2025-02-22 03:39:42 +00:00
lassulus
3e0f9f52bb clan-cli deploy_info: fix find_reachable_host returning unreachable hosts 2025-02-22 03:39:42 +00:00
lassulus
3992d0ed0d add demo_iso code for iso-morphing 2025-02-22 03:39:42 +00:00
lassulus
6037dde559 Merge pull request 'Add support for XDG_* style directories on macos' (#2865) from Undone8/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2865
2025-02-22 03:34:56 +00:00
Denis Rosca
baa0a615ea Add support for XDG_* style directories on macos
Closes #2864
2025-02-22 03:34:56 +00:00
Jörg Thalheim
b0760bc2b9 recommend vars over facts 2025-02-22 03:34:40 +00:00
Mic92
6a33fe8e7a Merge pull request 'fix regex for detecting git+file inputs' (#2907) from fix-git-input into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2907
2025-02-21 02:57:22 +00:00
Jörg Thalheim
1f3bd09245 fix regex for detecting git+file inputs 2025-02-20 10:00:04 +07:00
a-kenji
122dbf4240 clanModules/mycelium: Remove certain options for compatibility reasons
Remove certain options for compatibility reasons

We want to reintroduce them once we pass in `vars` through the
inventory.
2025-02-19 09:54:00 +00:00
Qubasa
8ac286bcaf docs: Fix install documentation 2025-02-19 14:23:45 +07:00
hsjobeki
8fcc004b68 Merge pull request 'clan-cli: "fix" ssh option parsing' (#2899) from lopter/clan-core:lo-fix-ssh-option-parsing into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2899
2025-02-19 01:41:07 +00:00
Louis Opter
37bbbefa8e clan-cli: "fix" ssh option parsing
Calling it fix in double quotes since that's still quite hand-crafted,
but at least you can now specify options with `@` inside them (e.g.
`ProxyJump`) and have it work properly.

Moreover this fixes the syntax for GET-like variables in the networking
clanCore module. Only the fixed syntax is supported since that's what
was tested, and actually parsed in the code.
2025-02-18 21:37:38 +00:00
Qubasa
d44def5381 clan-cli: Fix clan create throwing a warning if --flake is not defined 2025-02-18 17:40:27 +07:00
Qubasa
03ce74fc74 clan-clI: Improve error message of clan update-hardware-config on non found nixos-facter 2025-02-18 17:40:27 +07:00
Qubasa
6c8137d30b docs: Fix multiple issues with the clan installation guide 2025-02-18 17:40:27 +07:00
Pablo Ovelleiro Corral
27a3126d68 Make store-backend configurable 2025-02-18 06:34:50 +01:00
Qubasa
faee6c2a79 clan-cli: Re-add test_copy_from_nixstore_symlink test but mark it impure 2025-02-17 14:21:50 +07:00
Qubasa
6070219b1a clan-cli: Remove set -x from pytest script 2025-02-17 14:10:22 +07:00
Qubasa
a5e32f9b6d clan-cli: Fix clan flakes create inside an already existing git repo 2025-02-17 13:23:31 +07:00
Qubasa
89e3793831 clan-cli: Add CLAN_TEST_STORE env var to clan-pytest-without-core 2025-02-17 13:19:45 +07:00
Michael Hoang
fd908e18c3 templates: move machine templates 2025-02-17 02:15:42 +00:00
Clan Merge Bot
a4d4b991a1 update flake lock - 2025-02-17T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/ff3568858c54bd306e9e1f2886f0f781df307dff?narHash=sha256-3Z40qHaFScWUCVQrGc4Y%2BRdoPsh1R/wIh%2BAN4cTXP0I%3D' (2025-02-05)
  → 'github:nix-community/disko/fa5746ecea1772cf59b3f34c5816ab3531478142?narHash=sha256-xFnU%2BuUl48Icas2wPQ%2BZzlL2O3n8f6J2LrzNK9f2nng%3D' (2025-02-15)
• Updated input 'nixos-facter-modules':
    'github:numtide/nixos-facter-modules/fa11d87b61b2163efbb9aed7b7a5ae0299e5ab9c?narHash=sha256-aY55yiifyo1XPPpbpH0kWlV1g2dNGBlx6622b7OK8ks%3D' (2025-01-15)
  → 'github:numtide/nixos-facter-modules/60f8b8f3f99667de6a493a44375e5506bf0c48b1?narHash=sha256-/nA3tDdp/2g0FBy8966ppC2WDoyXtUWaHkZWL%2BN3ZKc%3D' (2025-02-05)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/1128e89fd5e11bb25aedbfc287733c6502202ea9?narHash=sha256-3ebRdThRic9bHMuNi2IAA/ek9b32bsy8F5R4SvGTIog%3D' (2025-02-13)
  → 'github:NixOS/nixpkgs/fada727ee7c0bd487e311dede0a2b0725a0f7765?narHash=sha256-Zc%2BK4AxAwFaWKK18nSl/3TKidGf46En7bfK8SL%2BRevg%3D' (2025-02-14)
2025-02-17 00:52:05 +00:00
Clan Merge Bot
4670525106 update flake lock - disko - 2025-02-17T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/ff3568858c54bd306e9e1f2886f0f781df307dff?narHash=sha256-3Z40qHaFScWUCVQrGc4Y%2BRdoPsh1R/wIh%2BAN4cTXP0I%3D' (2025-02-05)
  → 'github:nix-community/disko/fa5746ecea1772cf59b3f34c5816ab3531478142?narHash=sha256-xFnU%2BuUl48Icas2wPQ%2BZzlL2O3n8f6J2LrzNK9f2nng%3D' (2025-02-15)
2025-02-17 00:34:01 +00:00
Clan Merge Bot
5a0ed03c56 update flake lock - nixpkgs - 2025-02-17T00:00+00:00
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/1128e89fd5e11bb25aedbfc287733c6502202ea9?narHash=sha256-3ebRdThRic9bHMuNi2IAA/ek9b32bsy8F5R4SvGTIog%3D' (2025-02-13)
  → 'github:NixOS/nixpkgs/fada727ee7c0bd487e311dede0a2b0725a0f7765?narHash=sha256-Zc%2BK4AxAwFaWKK18nSl/3TKidGf46En7bfK8SL%2BRevg%3D' (2025-02-14)
2025-02-17 00:00:54 +00:00
Michael Hoang
af228db398 machines: hide morph 2025-02-17 00:22:14 +07:00
Pablo Ovelleiro Corral
b0e7de3c8b Create directory 2025-02-16 17:08:54 +00:00
Pablo Ovelleiro Corral
cb89fb0847 Fix locking 2025-02-16 17:08:54 +00:00
Pablo Ovelleiro Corral
014aec9531 Fix output when rebuilding 2025-02-16 17:08:54 +00:00
Michael Hoang
160bbfcb37 cli: add morph command 2025-02-16 21:31:28 +07:00
Michael Hoang
5c68e129b7 nixos/clan: add option for opting out of Clan defaults
Also replace `documentation.nixos.enable = false` with
`documentation.doc.enable` to opt out of only `nixos-help` and the HTML
manual but leave `man configuration.nix`.
2025-02-16 21:31:28 +07:00
Michael Hoang
bc53c7a886 cli: make some functions only create commits optionally 2025-02-16 21:14:09 +07:00
Michael Hoang
61c1943ccc templates: allow specifying from flake-parts module 2025-02-16 21:10:22 +07:00
a-kenji
c3013c1a02 docs/mesh-vpn: Document inventory usage 2025-02-16 13:32:42 +07:00
a-kenji
3cff6577da docs: Extend backups guide
Closes #2792
2025-02-16 13:04:53 +07:00
a-kenji
c795a1d895 clanModules/syncthing-static-peers: Migrate to vars
Part of the #2511 migration.
2025-02-15 23:34:25 +07:00
a-kenji
66e166068e clanModules/garage: Migrate to vars
Part of the #2511 migration.
2025-02-15 11:21:09 +00:00
lassulus
0c7173afd0 cli: nix_add_to_gcroots: don't run in sandboxed tests 2025-02-15 09:59:41 +00:00
lassulus
d5e391ecc8 clan-cli flake caching: fix selectors not merging 2025-02-15 09:59:41 +00:00
lassulus
2a3bc7b31b clan-cli: hash the flake_hash to remove unwanted character from path 2025-02-15 09:59:41 +00:00
a-kenji
b54346ce03 clanModules/state-version: Remove trailing newlines
The state version is now matched against certain regex rules.
We strip possible trailing newlines to improve compatibility.
2025-02-15 16:29:07 +07:00
hsjobeki
39bc7c1f17 Merge pull request 'Fix: clan machines delete persistance logic' (#2871) from hsjobeki/clan-core:hsjobeki-main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2871
2025-02-15 08:34:47 +00:00
Johannes Kirschbauer
153b5560c3 Cli: delete machines bugfix. Dont modify the inventory in other places 2025-02-15 09:03:54 +07:00
Johannes Kirschbauer
2412513ad4 Inventory: init delete api 2025-02-15 09:03:46 +07:00
Jörg Thalheim
873f650678 remove directory = self from our documentation 2025-02-15 01:48:17 +00:00
Qubasa
35aedddf65 docs: Add --refresh flag to nix shell command to mitigate caching issues 2025-02-14 13:28:21 +07:00
Qubasa
663ab70465 clan-cli: Make copy_from_nixstore work with single files 2025-02-14 13:28:01 +07:00
Jörg Thalheim
4f1e2ba582 zt-tcp-releay: useFetchCargoVendor 2025-02-14 12:25:32 +07:00
Jörg Thalheim
d3bd120a04 fix system.stateVersion 2025-02-14 12:22:26 +07:00
Jörg Thalheim
f8bf39e43a bump nixpkgs 2025-02-14 12:09:04 +07:00
Jörg Thalheim
93a7e272b1 Revert "zerotierone: fix on macOS"
This reverts commit 2e212e3e31.

no longer needed after nixpkgs bump
2025-02-14 12:08:18 +07:00
Qubasa
de3153259d clan-cli: Fix garbled clan vms run output. docs: Improve debugging guide 2025-02-13 16:17:55 +07:00
Luis Hebendanz
bf492d4deb Merge pull request 'clan-cli: Remove flake-registry set to none in get_clan_nix_attrset' (#2862) from Qubasa/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2862
2025-02-13 08:55:40 +00:00
Qubasa
41cb679eab clan-cli: Remove flake-registry set to none in get_clan_nix_attrset 2025-02-13 15:47:28 +07:00
Qubasa
b138cfcd69 clan-cli: Fix symlink issue with copy_from_nixstore, add test for it. Also add more comprehensive clan template tests 2025-02-13 15:34:21 +07:00
Luis Hebendanz
a22d426b25 Merge pull request 'cli: machines install: Add phases option to pass to nixos-anywhere and update the "Disk Encryption" documentation to use it' (#2858) from sachk/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2858
2025-02-13 07:04:27 +00:00
Sacha Korban
c0f07afb98 docs: disc-encryption: change guide to use phases option and misc improvements 2025-02-13 17:10:07 +11:00
Sacha Korban
0eaaabcf63 clan-cli: machines install: add phases option for nixos-anywhere 2025-02-13 17:10:02 +11:00
kenji
7df51d0474 Merge pull request 'clan-cli: secrets machines remove: update secrets after removing the key' (#2832) from lopter/clan-core:lo-fix-secrets-machine-remove into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2832
Reviewed-by: kenji <aks.kenji@protonmail.com>
2025-02-13 03:53:23 +00:00
Louis Opter
5a6038f742 clan-cli: secrets machines remove: update secrets after removing the key
Quick follow up to PR #2781, this commit does the same kind of logic but
for machines instead of users and groups.

Note that this only affects the `clan secrets machines remove`
sub-command, and that `clan machines delete` still leaves unusable
secrets & vars behind. This can be addressed in a different change.
2025-02-13 03:53:23 +00:00
Luis Hebendanz
15e8df894e Merge pull request 'docs: fix git rm step in Add Machines' (#2853) from OliverNChalk/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2853
Reviewed-by: kenji <aks.kenji@protonmail.com>
2025-02-11 07:39:03 +00:00
OliverNChalk
50924ad7ff docs: fix git rm step in Add Machines 2025-02-11 09:41:25 +11:00
Michael Hoang
2e212e3e31 zerotierone: fix on macOS 2025-02-10 20:56:31 +07:00
Qubasa
23b57b0a3a clan-cli: Mark new test as impure 2025-02-10 20:36:55 +07:00
Qubasa
69d092c46b clan-cli: Add update_clan boolean option to create_clan 2025-02-10 20:36:55 +07:00
Qubasa
2663a181d0 clan-cli: Fix disko template to not fail because of missing bootloader. 2025-02-10 20:36:55 +07:00
Qubasa
9ab81a9c5d clan-cli: Add one more test for checking Flake with git+file: 2025-02-10 20:36:55 +07:00
lassulus
0872b781d7 clan-cli: add persistant flake caching 2025-02-10 13:29:01 +00:00
Jörg Thalheim
86e91c8604 cli: fix build on macOS 2025-02-10 17:41:50 +07:00
hsjobeki
14377f25c9 Merge pull request 'CLI: use partial update for machine create' (#2848) from hsjobeki/clan-core:hsjobeki-main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2848
2025-02-10 09:02:23 +00:00
Johannes Kirschbauer
9b706c148b Inventory: automatically create emtpy file on write 2025-02-10 09:02:23 +00:00
Johannes Kirschbauer
dee284d669 CLI: machine create use patch inventory for partial updates 2025-02-10 09:02:23 +00:00
lassulus
718e553211 clan_cli flake caching: support outPath 2025-02-10 04:33:37 +00:00
Clan Merge Bot
cbe3cb94b7 update flake lock - nixpkgs - 2025-02-10T00:00+00:00
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/102a39bfee444533e6b4e8611d7e92aa39b7bec1?narHash=sha256-Q4vhtbLYWBUnjWD4iQb003Lt%2BN5PuURDad1BngGKdUs%3D' (2025-02-01)
  → 'github:NixOS/nixpkgs/fa35a3c8e17a3de613240fea68f876e5b4896aec?narHash=sha256-7Fu7oazPoYCbDzb9k8D/DdbKrC3aU1zlnc39Y8jy/s8%3D' (2025-02-08)
2025-02-10 04:12:52 +00:00
hsjobeki
91661da320 revert 283aad7ea0
revert ADR: init clanModules architecture decision
2025-02-10 03:42:44 +00:00
Clan Merge Bot
7ebc11f96f update flake lock - disko - 2025-02-10T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/18d0a984cc2bc82cf61df19523a34ad463aa7f54?narHash=sha256-KYOATYEwaKysL3HdHdS5kbQMXvzS4iPJzJrML%2B3TKAo%3D' (2025-01-29)
  → 'github:nix-community/disko/ff3568858c54bd306e9e1f2886f0f781df307dff?narHash=sha256-3Z40qHaFScWUCVQrGc4Y%2BRdoPsh1R/wIh%2BAN4cTXP0I%3D' (2025-02-05)
2025-02-10 00:40:28 +00:00
Clan Merge Bot
27ef7040c2 update flake lock - treefmt-nix - 2025-02-10T00:00+00:00
Flake lock file updates:

• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/bebf27d00f7d10ba75332a0541ac43676985dea3?narHash=sha256-j6jC12vCFsTGDmY2u1H12lMr62fnclNjuCtAdF1a4Nk%3D' (2025-01-28)
  → 'github:numtide/treefmt-nix/4f09b473c936d41582dd744e19f34ec27592c5fd?narHash=sha256-yrK3Hjcr8F7qS/j2F%2Br7C7o010eVWWlm4T1PrbKBOxQ%3D' (2025-02-07)
2025-02-10 00:00:45 +00:00
Johannes Kirschbauer
283aad7ea0 ADR: init clanModules architecture decision 2025-02-09 05:04:36 +00:00
Mic92
775088ccd9 Merge pull request 'fix-repo-sync' (#2834) from fix-repo-sync into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2834
2025-02-08 14:59:52 +00:00
Jörg Thalheim
d71a8329f2 fix missing permissions for repo-sync 2025-02-08 14:37:46 +01:00
Jörg Thalheim
022d0babc5 fix dependabot settings 2025-02-08 14:37:36 +01:00
hsjobeki
934d8fc2a4 Merge pull request 'inventory: refactor role resolution into submodule' (#2826) from hsjobeki/clan-core:hsjobeki-main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2826
2025-02-08 04:03:51 +00:00
Johannes Kirschbauer
e75b50e335 Add missing test dependency 2025-02-08 10:48:57 +07:00
Johannes Kirschbauer
f9fc6904f0 inventory: refactor role resolution into submodule 2025-02-08 10:43:54 +07:00
Johannes Kirschbauer
6deaab506a Inventory: test include missing dependency folder 2025-02-08 10:43:53 +07:00
lassulus
32748c14f4 clan_cli machines: use Flake instead of FlakeId 2025-02-07 06:26:09 +01:00
a-kenji
6d2845c645 pkgs/cli: Rename create_file -> persist 2025-02-06 14:59:59 +00:00
kenji
4899c38e52 Merge pull request 'pgks/cli: Add toplevel aliases' (#2820) from kenji/clan-core:feat/alias/toplevel into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2820
2025-02-06 14:56:57 +00:00
a-kenji
0d69d72899 pgks/cli: Add toplevel aliases 2025-02-06 14:56:57 +00:00
Jörg Thalheim
34904b8758 add dependabot 2025-02-06 18:02:01 +07:00
lassulus
51d65873a7 clan-cli: test_flake_caching: add actual flake caching test 2025-02-05 10:17:37 +00:00
Johannes Kirschbauer
02929e9d42 Inventory: migrate import and config resolution into a module 2025-02-05 16:23:30 +07:00
Johannes Kirschbauer
2018de8d9e Inventory: move build inventory into a module 2025-02-05 11:06:43 +07:00
Johannes Kirschbauer
cffd2450e3 Fix: use older nodejs version due to breaking classnames in 22.12 2025-02-05 03:36:43 +00:00
Johannes Kirschbauer
b21c14d8a5 inventory: add better error for missing file 2025-02-05 10:26:05 +07:00
Johannes Kirschbauer
34ed0e8b0b checks: fix source of backups vm test 2025-02-05 10:25:45 +07:00
Johannes Kirschbauer
ae2990657a inventory: use special args to split build inventory into modules 2025-02-05 09:56:08 +07:00
Johannes Kirschbauer
3d8bececc3 inventory: fix test: supported roles beeing to lazy 2025-02-05 09:56:08 +07:00
Johannes Kirschbauer
9d06dec7d0 Inventory: add new module class: class='clan' 2025-02-05 09:56:08 +07:00
Qubasa
4878b773cb clan-app: Fix Gsettings schema files not found 2025-02-04 17:10:35 +07:00
Michael Hoang
5314eb4cfa blog: actually remove asciicinema player 2025-02-04 15:48:12 +07:00
Qubasa
decf340258 clan-cli: Fix incorrect input handling in get_templates 2025-02-04 08:10:32 +00:00
a-kenji
f2ab298caa vars/interface: Change prompt.persist default to false
Change `prompt.persist` default to false.
We want a consistent default that is not conditionally dependent on
other values.
This makes communication on how the functionality is used more
consistent and easier understood.
2025-02-04 07:47:22 +00:00
kenji
339bf9900e Merge pull request 'clan_cli: add select command' (#2815) from kenji/clan-core:lass/clan-select into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2815
2025-02-04 07:32:55 +00:00
a-kenji
11468c42af pkgs/clan: Remove select debug prints 2025-02-04 07:32:55 +00:00
a-kenji
6242416fc4 pkgs/clan: Fix help formatter 2025-02-04 07:32:55 +00:00
lassulus
3811aef9b2 clan_cli: add select command 2025-02-04 07:32:55 +00:00
Johannes Kirschbauer
6755aa2c70 inventory: migrate tests 2025-02-04 13:20:15 +07:00
Johannes Kirschbauer
316e33f54a Inventory: refactor build-inventory in more independent parts 2025-02-04 13:20:15 +07:00
Michael Hoang
871326fb91 clan-cli: fix clan-cli accidentally dependending on all packages 2025-02-04 04:52:47 +00:00
Jörg Thalheim
97f3963ac6 shut up eslint warnings 2025-02-04 04:02:42 +00:00
Jörg Thalheim
0309a80c92 fix mypy 2025-02-04 04:02:42 +00:00
Clan Merge Bot
9b438689fc update flake lock - nixpkgs - 2025-02-03T00:00+00:00
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/041c867bad68dfe34b78b2813028a2e2ea70a23c?narHash=sha256-DSenga8XjPaUV5KUFW/i3rNkN7jm9XmguW%2BqQ1ZJTR4%3D' (2025-01-17)
  → 'github:NixOS/nixpkgs/102a39bfee444533e6b4e8611d7e92aa39b7bec1?narHash=sha256-Q4vhtbLYWBUnjWD4iQb003Lt%2BN5PuURDad1BngGKdUs%3D' (2025-02-01)
2025-02-04 04:02:42 +00:00
DavHau
d0bfd5c879 add /decisions
see https://github.com/joelparkerhenderson/architecture-decision-record
2025-02-04 10:41:49 +07:00
Clan Merge Bot
8d12b0da31 update flake lock - disko - 2025-02-03T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/bf0abfde48f469c256f2b0f481c6281ff04a5db2?narHash=sha256-rMEuiK69MDhjz1JgbaeQ9mBDXMJ2/P8vmOYRbFndXsk%3D' (2025-01-16)
  → 'github:nix-community/disko/18d0a984cc2bc82cf61df19523a34ad463aa7f54?narHash=sha256-KYOATYEwaKysL3HdHdS5kbQMXvzS4iPJzJrML%2B3TKAo%3D' (2025-01-29)
2025-02-04 03:22:08 +00:00
Mic92
f85fd9ccc1 Merge pull request 'clan-cli: fix keys and symlinks updates when users, machines, or groups are updated' (#2781) from lopter/clan-core:lo-fix-secrets-user-remove into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2781
2025-02-04 03:13:20 +00:00
Louis Opter
e88c8a8f2d clan-cli: do not skip secrets.update_secrets when a group is removed
We need to remove all keys that were in the group from affected secrets.

With this change we now take `group_name` as an argument in
`{add,remove}_member`, which is a little bit more readable than
`group_folder.parent.name`, and helps DRY the code a bit.
2025-02-04 03:13:20 +00:00
Louis Opter
509a1bcb94 clan-cli: secrets users add: make sure only one key argument was passed
This is slightly better input validation FWIW.
2025-02-04 03:13:20 +00:00
Louis Opter
23d759219f clan-cli: secrets: properly update secrets when an user is removed
Fixes #2659.
2025-02-04 03:13:20 +00:00
Louis Opter
c99296aae8 clan-cli: improve tests on clan secrets …
When users or groups are updated :

- Check that keys are properly updated on sops secrets;
- Check that no dangling symlinks are left behind in sops secrets.

And when an user is removed from the clan, check that it is removed from
the groups it belonged to.

This doesn't check this works for vars explicitly, since they share the
same logic, see `secret_paths.extend(list_vars_secrets(flake_dir))` in
commit 7466445653.

Those improvements allow us to validate that #2659 is indeed fixed, and
tell us that we need to make the same kind of fixes for machines and
groups. For groups this is straightforward, and for machines, when one
is deleted, I wanna discuss first whether we want to delete all its
secrets as well.
2025-02-04 03:13:20 +00:00
Louis Opter
947095ad13 clan-cli: secrets: truly catch broken symlinks in collect_keys_for_type 2025-02-04 03:13:20 +00:00
Louis Opter
34b36fa309 clan-cli: secrets key generate: fix call to action message
So that it makes sense when an already existing PGP key is specified.
2025-02-04 03:13:20 +00:00
Louis Opter
67f26a3abe clan-cli: secrets: commit changes when group members are added or removed 2025-02-04 03:13:20 +00:00
Louis Opter
30c7e32a3d clan-cli: honor clan.core.sops.defaultGroups option in vars fix 2025-02-04 03:13:20 +00:00
Louis Opter
9387d64619 clan-cli: secrets/sops: fix error message in maybe_get_admin_public_key 2025-02-04 03:13:20 +00:00
Johannes Kirschbauer
dc02296243 buildClan: add more eager tests 2025-02-03 12:00:47 +01:00
Johannes Kirschbauer
0a27576021 flake.nix: remove unused self reference 2025-02-03 12:00:47 +01:00
Johannes Kirschbauer
2341b0e673 buildClan: add depercation warnings for directory=self 2025-02-03 12:00:47 +01:00
Jörg Thalheim
6f1ab30881 fix infinite recursion 2025-02-03 12:00:47 +01:00
Clan Merge Bot
45058ff818 update flake lock - treefmt-nix - 2025-02-03T00:00+00:00
Flake lock file updates:

• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/f2cc121df15418d028a59c9737d38e3a90fbaf8f?narHash=sha256-5An1wq5U8sNycOBBg3nsDDgpwBmR9liOpDGlhliA6Xo%3D' (2025-01-21)
  → 'github:numtide/treefmt-nix/bebf27d00f7d10ba75332a0541ac43676985dea3?narHash=sha256-j6jC12vCFsTGDmY2u1H12lMr62fnclNjuCtAdF1a4Nk%3D' (2025-01-28)
2025-02-03 00:20:56 +00:00
Clan Merge Bot
ffbf2ff801 update flake lock - flake-parts - 2025-02-03T00:00+00:00
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/b905f6fc23a9051a6e1b741e1438dbfc0634c6de?narHash=sha256-%2Bhu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU%3D' (2025-01-06)
  → 'github:hercules-ci/flake-parts/32ea77a06711b758da0ad9bd6a844c5740a87abd?narHash=sha256-7H9XgNiGLKN1G1CgRh0vUL4AheZSYzPm%2BzmZ7vxbJdo%3D' (2025-02-01)
2025-02-03 00:00:03 +00:00
a-kenji
1694f8b3a8 pkgs/clan: Fix typos 2025-02-02 23:20:39 +07:00
lassulus
c746b84a6f test_api_dataclass_compat: exlcude flake.py 2025-02-02 11:52:36 +00:00
lassulus
fe2cfd3b37 clan-cli: add a Flake class with caching 2025-02-02 11:52:36 +00:00
lassulus
26143b4b5b clan-cli: add ipython to dev dependencies 2025-02-02 11:52:36 +00:00
lassulus
90fbe807d6 clan-cli vars upload: add optional --directory 2025-02-02 11:52:36 +00:00
Jörg Thalheim
3ab497afa9 buildClan/tests: make test_only_required minimal again 2025-02-02 10:40:50 +00:00
kenji
e03ee4407c Merge pull request 'clanModules/user-password: Add inventory feature' (#2796) from kenji/clan-core:feat-inventory/user-password into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2796
2025-02-02 10:35:48 +00:00
a-kenji
c7e9bfbefe clanModules/root-password: Add inventory feature 2025-02-02 10:35:48 +00:00
kenji
83169dc93e Merge pull request 'clanModules/root-password: Add inventory feature' (#2795) from kenji/clan-core:feat-inventory/root-password into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2795
2025-02-02 10:32:58 +00:00
a-kenji
23360377cf clanModules/root-password: Add inventory feature 2025-02-02 10:32:58 +00:00
Jörg Thalheim
07bd686850 legacyPackages.evalTests-build-clan: fix comment to run tests 2025-02-02 10:30:26 +00:00
Jörg Thalheim
8634087309 Do not deprecate directory argument 2025-02-02 10:30:26 +00:00
a-kenji
fe6cca3c47 clanModules/root-password: Fix root-password persistence 2025-02-02 16:36:19 +07:00
Qubasa
1fb676affb clan-cli: Fix clan flakes create not working in nix shell 2025-02-01 12:16:20 +07:00
Mic92
1248adfd45 Merge pull request 'container test with writeable nix store' (#2655) from container-test into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2655
2025-01-31 11:51:00 +00:00
Jörg Thalheim
5d2e3b2b21 container test: with writeable nix store 2025-01-31 11:51:00 +00:00
Qubasa
0f4cdd31cd clan-cli: Make clan machines create use templating.py 2025-01-31 18:07:48 +07:00
Jörg Thalheim
0e3e6c29c7 remove createFile legacy alias from vars/interface
it's hard to filter this out in nix. So instead we just drop this
option.
2025-01-31 10:29:35 +00:00
Qubasa
d770830c03 clan-cli: Add test_clan_nix_attrset.py and minor fixups 2025-01-31 16:36:20 +07:00
Qubasa
57d82c9315 webview-ui: Fix create_clan js call 2025-01-30 17:26:41 +07:00
Qubasa
e96bd0816f clan-cli: Expand type_to_dict to support NewType and tuple types in dataclasses 2025-01-30 17:19:31 +07:00
Qubasa
7545a9a883 clan-cli: Make clan flakes create discover templates from inputs. Add clan flakes list command 2025-01-30 16:24:50 +07:00
Qubasa
c212538ac7 clan: Remove unecessary templates and modules interface 2025-01-29 19:24:15 +07:00
Qubasa
839bb17284 clan-cli: Add from_host function to Host class 2025-01-29 19:18:02 +07:00
Qubasa
4a144e77a4 clan-cli: Add ruff to devShell again. Add missing type annotations 2025-01-29 19:16:34 +07:00
Qubasa
6e47f1ee96 Add importable clan.modules and clan.template interfaces without implementation 2025-01-27 17:35:42 +07:00
Clan Merge Bot
1ba8090188 update flake lock - treefmt-nix - 2025-01-27T00:00+00:00
Flake lock file updates:

• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/d1ed3b385f8130e392870cfb1dbfaff8a63a1899?narHash=sha256-uPNWcYbhY2fjY3HOfRCR5jsfzdzemhfxLSxwjXYXqNc%3D' (2025-01-17)
  → 'github:numtide/treefmt-nix/f2cc121df15418d028a59c9737d38e3a90fbaf8f?narHash=sha256-5An1wq5U8sNycOBBg3nsDDgpwBmR9liOpDGlhliA6Xo%3D' (2025-01-21)
2025-01-27 00:00:24 +00:00
Luis Hebendanz
974279eddd Merge pull request 'clan: Add autoloaded clanModules from flake inputs. Rename 'directory' to 'self' in buildClan' (#2782) from Qubasa/clan-core:dynamic_clanModulesv2 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2782
Reviewed-by: lassulus <clanlol@lassul.us>
2025-01-24 07:29:14 +00:00
Qubasa
e36654daa1 clan: Add autoloaded clanModules from flake inputs. Rename 'directory' to 'self' in buildClan 2025-01-24 12:32:04 +07:00
Johannes Kirschbauer
559a95cdde Docs: change navigation to use tabs again 2025-01-23 13:49:55 +01:00
lassulus
cabd848fb7 vars: set persist to true if the script is empty 2025-01-22 19:36:19 +00:00
a-kenji
dfdcad7fc5 Fix various typos 2025-01-22 13:26:58 +01:00
a-kenji
ce148c23a5 Fix various typos 2025-01-22 13:19:28 +01:00
a-kenji
7308eb8dc7 clanModules/mycelium: init mycelium
This adds a clanModule for `mycelium`.
`Mycelium` is an IPv6 overlay network written in Rust.
Each node that joins the overlay network will receive an overlay network IP in the 400::/7 range.

An example configuration might look like this in the inventory:

```nix
mycelium.default = {
  roles.peer.machines = [
    "berlin"
    "munich"
  ];
  config = {
    topLevelDomain = "m";
    openFirewall = true;
    addHostedPublicNodes = true;
  };
};
```

This will add the machines named `berlin` and `munich` to the `mycelium` vpn.
And will also set the toplevel domain of the mycelium vpn to `m`, meaning the
machines are now reachable via `berlin.m` and `munich.m`.
2025-01-22 11:56:10 +00:00
hsjobeki
fe399f773e Merge pull request 'Vars/Facts: improve api, fix some errors' (#2712) from hsjobeki/clan-core:zerotier into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2712
2025-01-22 09:02:55 +00:00
Johannes Kirschbauer
906126f91f Vars/tests: secrets dont raise backend error depending on the previous backend 2025-01-22 09:02:55 +00:00
Johannes Kirschbauer
8c75051611 Facts/api: export method for getting the public store 2025-01-22 09:02:55 +00:00
Johannes Kirschbauer
096f1b5e8a Vars/secrets-store: omit folder exists errors for secrets 2025-01-22 09:02:55 +00:00
Mic92
47257cf56a Merge pull request 'remove eval warning for createFile' (#2773) from network into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2773
2025-01-21 16:15:17 +00:00
Jörg Thalheim
62c6da4c32 clan/update: deploy_machine -> deploy_machines 2025-01-21 15:20:38 +01:00
Jörg Thalheim
076de05a88 remove eval warning for createFile 2025-01-21 15:20:38 +01:00
Michael Hoang
6ba1850678 flash: don't allow partitioning time secrets 2025-01-21 11:13:51 +00:00
lassulus
6f2ae1e1f2 extend installation-test to check partitioning secrets 2025-01-21 11:13:51 +00:00
Michael Hoang
0ec38c7919 vars: support secrets for partitioning the disk 2025-01-21 11:13:51 +00:00
Mic92
8acb15612d Merge pull request 'Automatic flake update - 2025-01-20T00:00+00:00' (#2769) from flake-update-2025-01-20 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2769
2025-01-21 11:09:13 +00:00
Clan Merge Bot
7b1639e8f3 update flake lock - 2025-01-20T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/f720e64ec37fa16ebba6354eadf310f81555cc07?narHash=sha256-8hKhPQuMtXfJi%2B4lPvw3FBk/zSJVHeb726Zo0uF1PP8%3D' (2025-01-12)
  → 'github:nix-community/disko/bf0abfde48f469c256f2b0f481c6281ff04a5db2?narHash=sha256-rMEuiK69MDhjz1JgbaeQ9mBDXMJ2/P8vmOYRbFndXsk%3D' (2025-01-16)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/ae2fb9f1fb5fcf17fb59f25c2a881c170c501d6f?narHash=sha256-BYsp8PA1j691FupfrLVOQzm4CaYaKtkh4U%2BKuGMnBWw%3D' (2025-01-15)
  → 'github:NixOS/nixpkgs/041c867bad68dfe34b78b2813028a2e2ea70a23c?narHash=sha256-DSenga8XjPaUV5KUFW/i3rNkN7jm9XmguW%2BqQ1ZJTR4%3D' (2025-01-17)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/13c913f5deb3a5c08bb810efd89dc8cb24dd968b?narHash=sha256-p2r8xhQZ3TYIEKBoiEhllKWQqWNJNoT9v64Vmg4q8Zw%3D' (2025-01-06)
  → 'github:numtide/treefmt-nix/d1ed3b385f8130e392870cfb1dbfaff8a63a1899?narHash=sha256-uPNWcYbhY2fjY3HOfRCR5jsfzdzemhfxLSxwjXYXqNc%3D' (2025-01-17)
2025-01-21 11:09:13 +00:00
Mic92
505d038918 Merge pull request 'Automatic flake update - treefmt-nix - 2025-01-20T00:00+00:00' (#2770) from flake-update-treefmt-nix-2025-01-20 into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2770
2025-01-21 11:09:03 +00:00
Clan Merge Bot
f09aaa57f1 update flake lock - treefmt-nix - 2025-01-20T00:00+00:00
Flake lock file updates:

• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/13c913f5deb3a5c08bb810efd89dc8cb24dd968b?narHash=sha256-p2r8xhQZ3TYIEKBoiEhllKWQqWNJNoT9v64Vmg4q8Zw%3D' (2025-01-06)
  → 'github:numtide/treefmt-nix/d1ed3b385f8130e392870cfb1dbfaff8a63a1899?narHash=sha256-uPNWcYbhY2fjY3HOfRCR5jsfzdzemhfxLSxwjXYXqNc%3D' (2025-01-17)
2025-01-21 11:09:03 +00:00
Mic92
86219f436d Merge pull request 'use nix flake archive in clan machines update for git+file flake inputs' (#2771) from machine-update into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2771
2025-01-20 09:55:25 +00:00
Jörg Thalheim
c5a72f67c3 use nix flake archive in clan machines update for git+file flake inputs 2025-01-20 10:49:25 +01:00
Clan Merge Bot
553fb24657 update flake lock - disko - 2025-01-20T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/f720e64ec37fa16ebba6354eadf310f81555cc07?narHash=sha256-8hKhPQuMtXfJi%2B4lPvw3FBk/zSJVHeb726Zo0uF1PP8%3D' (2025-01-12)
  → 'github:nix-community/disko/bf0abfde48f469c256f2b0f481c6281ff04a5db2?narHash=sha256-rMEuiK69MDhjz1JgbaeQ9mBDXMJ2/P8vmOYRbFndXsk%3D' (2025-01-16)
2025-01-20 00:00:01 +00:00
Michael Hoang
01d86b6482 install: support -i flag for specifying SSH private key 2025-01-19 18:53:18 +11:00
Qubasa
3ffefc3064 clan: revert imports.nix and wait till tuesday 2025-01-18 20:21:49 +07:00
Qubasa
65bd3a9ac6 docs: Rename mentions of inventory module to clanModule with inventory support 2025-01-18 10:17:20 +07:00
Qubasa
8d0a9762a2 Reapply "buildClan: Add automatic inventory import directory"
This reverts commit e5bfa926e2.

This is incorrect we have mentions to inventory.modules in the codebase since much longer.
As can be seen in the documentation: https://docs.clan.lol/reference/nix-api/inventory/
As this PR improves the readability of the docs, I will re-apply it.
2025-01-18 10:01:19 +07:00
Qubasa
0d2ee39746 Reapply "docs: Document imports dir. Remove What's next sections everywhere. Merge guide overview and hompage view."
This reverts commit b19beb8913.
2025-01-18 10:00:56 +07:00
Jörg Thalheim
b19beb8913 Revert "docs: Document imports dir. Remove What's next sections everywhere. Merge guide overview and hompage view."
This reverts commit d4305f8b3c.
2025-01-17 15:44:44 +01:00
Jörg Thalheim
e5bfa926e2 Revert "buildClan: Add automatic inventory import directory"
This reverts commit 850eabb98c.

This introduces the name "inventory module" whereas we already use the
term clan modules everywhere else. I don't don't too many confusing
termologies in the codebase. Let's discuss this before adding it back.
2025-01-17 15:43:44 +01:00
Jörg Thalheim
33de028409 fix getting-started deploy link4 2025-01-17 14:08:58 +00:00
Qubasa
d4305f8b3c docs: Document imports dir. Remove What's next sections everywhere. Merge guide overview and hompage view. 2025-01-17 21:03:25 +07:00
Qubasa
850eabb98c buildClan: Add automatic inventory import directory 2025-01-17 20:58:48 +07:00
DavHau
708a3aabf6 tea-create-pr: don't use clan-core formatter 2025-01-17 19:22:19 +07:00
Mic92
8ff71d1445 Merge pull request 'fix flash-check' (#2715) from fix-flash-check into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2715
2025-01-17 11:37:03 +00:00
Jörg Thalheim
d10eb7189d update nixpkgs 2025-01-17 11:37:03 +00:00
lassulus
081dc4a5fd checks.flash: add missing grub-install deps 2025-01-17 11:37:03 +00:00
lassulus
cb2f0c5222 clan-cli: exit with errorcode also in debug mode 2025-01-17 11:37:03 +00:00
DavHau
3ec028d672 tests: reduce unnecessary rebuilds of several tests
Some test were referring to the whole source code via ${self} which amde them rebuild on every single commit.

This is not mitigated by introduceing `self.filter { include = [...]; }` allowin to a content addressed subset of the source code in tests.
2025-01-17 17:00:18 +07:00
clan-bot
9cd0572734 Merge pull request 'merge-acfter-ci: don't append username to remote branch' (#2757) from DavHau/clan-core:DavHau-dave into main 2025-01-17 03:41:09 +00:00
DavHau
669295b8f7 merge-acfter-ci: don't append username to remote branch 2025-01-17 10:36:45 +07:00
clan-bot
72ca99e2c7 Merge pull request 'Migrate borgbackup module to vars' (#2741) from pinpox/clan-core:migrate-borgbackup-vars into main 2025-01-16 12:16:37 +00:00
Pablo Ovelleiro Corral
7a17a04698 Migrate borgbackup module to vars 2025-01-16 13:14:24 +01:00
Mic92
8aa0a9c0d0 Merge pull request 'switch to nixos-facter for hardware-config' (#2747) from switch-to-nixos-facter into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2747
2025-01-15 13:59:49 +00:00
Jörg Thalheim
f55b02e1c9 remove flip functions from sops code 2025-01-15 13:59:49 +00:00
Jörg Thalheim
c4a1e3ec95 switch to nixos-facter for hardware-config 2025-01-15 13:59:49 +00:00
kenji
e973e64aaf Merge pull request 'docs: fix dev shell in migration guide' (#2748) from kmein/clan-core:main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2748
Reviewed-by: kenji <aks.kenji@protonmail.com>
2025-01-15 10:35:30 +00:00
Kierán Meinhardt
ca2d7e9afc docs: fix dev shell in migration guide 2025-01-15 10:35:30 +00:00
clan-bot
def681c125 Merge pull request 'docs/vars: fix syntax error' (#2751) from DavHau/clan-core:DavHau-docs into main 2025-01-15 06:26:08 +00:00
DavHau
2dfff1b314 docs/vars: fix syntax error 2025-01-15 13:21:50 +07:00
clan-bot
30825361a4 Merge pull request 'docs: set sidebar headers to accent color' (#2750) from pinpox/clan-core:main into main 2025-01-14 22:30:16 +00:00
Pablo Ovelleiro Corral
af3f652011 docs: set sidebar headers to accent color
Fixes #2749
2025-01-14 23:24:49 +01:00
clan-bot
aabf2b0796 Merge pull request 'Vars/docs minor fixes' (#2746) from hsjobeki/clan-core:vars/misc into main 2025-01-14 16:47:18 +00:00
hsjobeki
0b06970a33 Merge pull request 'docs(installer): Fix typography and align headers' (#2697) from kenji/clan-core:kenji-docs/fix-flash into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2697
2025-01-14 16:42:36 +00:00
a-kenji
16e6b0d406 docs(installer): Fix typography and align headers 2025-01-14 16:42:36 +00:00
hsjobeki
968f427404 Merge pull request 'Migrate clanModule root-password to vars' (#2701) from hsjobeki/clan-core:vars/root-password into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2701
2025-01-14 16:42:29 +00:00
Johannes Kirschbauer
16ccebc1fb Vars: interface improve docs formatting 2025-01-14 17:40:57 +01:00
Johannes Kirschbauer
5a179f4b91 Fix: f-string in generator error 2025-01-14 17:33:55 +01:00
Johannes Kirschbauer
57c4e8e929 Root-password: remove deprecated default option 2025-01-14 17:28:12 +01:00
Johannes Kirschbauer
4000571550 Fix: remove password from facts store tests 2025-01-14 17:19:51 +01:00
Johannes Kirschbauer
a53367bd11 Fix: secret facts store test 2025-01-14 17:19:50 +01:00
Johannes Kirschbauer
e00195f2ef Fixup: improve mkpasswd generator line 2025-01-14 17:19:50 +01:00
Johannes Kirschbauer
4e9901ab19 Vars: migrate root-password from facts 2025-01-14 17:19:50 +01:00
Mic92
a240bbcf04 Merge pull request 'installer: substitute packages from local nix store' (#2744) from speed-up-installer into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2744
Reviewed-by: lassulus <clanlol@lassul.us>
2025-01-14 15:11:33 +00:00
Jörg Thalheim
2b18e6eccc installer: substitute packages from local nix store
this can speed up the installation if both the installer and the
installed system use similar versions.
2025-01-14 15:11:33 +00:00
clan-bot
010caab16c Merge pull request 'vars in_repo: throw as a default so we can catch it with tryEval' (#2745) from lassulus/clan-core:throw_inrepo into main 2025-01-14 14:58:20 +00:00
lassulus
1a70165260 vars in_repo: throw as a default so we can catch it with tryEval 2025-01-14 15:53:54 +01:00
clan-bot
66d5f5b55e Merge pull request 'Automatic flake update - 2025-01-13T00:00+00:00' (#2728) from flake-update-2025-01-13 into main 2025-01-14 14:48:14 +00:00
Mic92
31479d47fc Merge branch 'main' into flake-update-2025-01-13 2025-01-14 14:46:25 +00:00
clan-bot
40ad0ee8fb Merge pull request 'Automatic flake update - nixpkgs - 2025-01-13T00:00+00:00' (#2729) from flake-update-nixpkgs-2025-01-13 into main 2025-01-14 14:38:17 +00:00
Jörg Thalheim
fbdf0931b9 ignore ruff A005 for now 2025-01-14 15:32:13 +01:00
clan-bot
7531ff4499 Merge pull request 'Automatic flake update - disko - 2025-01-13T00:00+00:00' (#2726) from flake-update-disko-2025-01-13 into main 2025-01-14 14:31:22 +00:00
Jörg Thalheim
e2aa66d86f reformat after update 2025-01-14 15:30:29 +01:00
clan-bot
1b420baa3f Merge pull request 'Automatic flake update - flake-parts - 2025-01-13T00:00+00:00' (#2727) from flake-update-flake-parts-2025-01-13 into main 2025-01-14 14:30:29 +00:00
Clan Merge Bot
9d29cc63ad update flake lock - nixpkgs - 2025-01-13T00:00+00:00
Flake lock file updates:

• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/4989a246d7a390a859852baddb1013f825435cee?narHash=sha256-kMBQ5PRiFLagltK0sH%2B08aiNt3zGERC2297iB6vrvlU%3D' (2024-12-17)
  → 'github:NixOS/nixpkgs/2f9e2f85cb14a46410a1399aa9ea7ecf433e422e?narHash=sha256-FWlPMUzp0lkQBdhKlPqtQdqmp%2B/C%2B1MBiEytaYfrCTY%3D' (2025-01-12)
2025-01-14 15:29:16 +01:00
clan-bot
ef62e0b04c Merge pull request 'Automatic flake update - treefmt-nix - 2025-01-13T00:00+00:00' (#2730) from flake-update-treefmt-nix-2025-01-13 into main 2025-01-14 14:28:02 +00:00
clan-bot
9a11c183e7 Merge pull request 'link to migration guide' (#2733) from migration-guide into main 2025-01-14 14:28:01 +00:00
Mic92
5dee67de6f Merge branch 'main' into flake-update-disko-2025-01-13 2025-01-14 14:19:21 +00:00
Mic92
53dde03ce9 Merge branch 'main' into flake-update-flake-parts-2025-01-13 2025-01-14 14:19:13 +00:00
Mic92
2310379d7f Merge branch 'main' into flake-update-2025-01-13 2025-01-14 14:19:07 +00:00
Mic92
a6d5ed96d1 Merge branch 'main' into flake-update-treefmt-nix-2025-01-13 2025-01-14 14:18:54 +00:00
Jörg Thalheim
479d89f9f0 link to migration guide 2025-01-14 15:18:11 +01:00
Mic92
4bc84542e4 Merge pull request 'matrix-synapse: migrate to vars' (#2714) from matrix into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2714
2025-01-14 14:16:19 +00:00
Jörg Thalheim
41ceb40d13 matrix-synapse: migrate to vars 2025-01-14 14:16:19 +00:00
hsjobeki
923b100e3e Merge pull request 'Docs: change navigation to use sidebar sections only' (#2743) from hsjobeki/clan-core:docs/sections into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2743
2025-01-14 12:31:45 +00:00
Johannes Kirschbauer
819e66c2da Docs: change navigation to use sidebar sections only 2025-01-14 12:31:45 +00:00
clan-bot
0c1c65f519 Merge pull request 'minor fixes' (#2736) from pinpox/clan-core:fix-migration-guide into main 2025-01-14 12:17:49 +00:00
Pablo Ovelleiro Corral
ae7e9e75a9 minor fixes 2025-01-13 21:37:01 +01:00
Clan Merge Bot
572bc30a82 update flake lock - treefmt-nix - 2025-01-13T00:00+00:00
Flake lock file updates:

• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/1788ca5acd4b542b923d4757d4cfe4183cc6a92d?narHash=sha256-FBG9d7e0BTFfxVdw4b5EmNll2Mv7hfRc54hbB4LrKko%3D' (2025-01-05)
  → 'github:numtide/treefmt-nix/13c913f5deb3a5c08bb810efd89dc8cb24dd968b?narHash=sha256-p2r8xhQZ3TYIEKBoiEhllKWQqWNJNoT9v64Vmg4q8Zw%3D' (2025-01-06)
2025-01-13 00:00:54 +00:00
Clan Merge Bot
983cddc979 update flake lock - 2025-01-13T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/4d5d07d37ff773338e40a92088f45f4f88e509c8?narHash=sha256-9Sy17XguKdEU9M5peTrkWSlI/O5IAqjHzdzxbXnc30g%3D' (2025-01-09)
  → 'github:nix-community/disko/f720e64ec37fa16ebba6354eadf310f81555cc07?narHash=sha256-8hKhPQuMtXfJi%2B4lPvw3FBk/zSJVHeb726Zo0uF1PP8%3D' (2025-01-12)
• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/f2f7418ce0ab4a5309a4596161d154cfc877af66?narHash=sha256-soePLBazJk0qQdDVhdbM98vYdssfs3WFedcq%2BraipRI%3D' (2025-01-01)
  → 'github:hercules-ci/flake-parts/b905f6fc23a9051a6e1b741e1438dbfc0634c6de?narHash=sha256-%2Bhu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU%3D' (2025-01-06)
• Updated input 'nixpkgs':
    'github:NixOS/nixpkgs/4989a246d7a390a859852baddb1013f825435cee?narHash=sha256-kMBQ5PRiFLagltK0sH%2B08aiNt3zGERC2297iB6vrvlU%3D' (2024-12-17)
  → 'github:NixOS/nixpkgs/2f9e2f85cb14a46410a1399aa9ea7ecf433e422e?narHash=sha256-FWlPMUzp0lkQBdhKlPqtQdqmp%2B/C%2B1MBiEytaYfrCTY%3D' (2025-01-12)
• Updated input 'treefmt-nix':
    'github:numtide/treefmt-nix/1788ca5acd4b542b923d4757d4cfe4183cc6a92d?narHash=sha256-FBG9d7e0BTFfxVdw4b5EmNll2Mv7hfRc54hbB4LrKko%3D' (2025-01-05)
  → 'github:numtide/treefmt-nix/13c913f5deb3a5c08bb810efd89dc8cb24dd968b?narHash=sha256-p2r8xhQZ3TYIEKBoiEhllKWQqWNJNoT9v64Vmg4q8Zw%3D' (2025-01-06)
2025-01-13 00:00:26 +00:00
Clan Merge Bot
159946606c update flake lock - flake-parts - 2025-01-13T00:00+00:00
Flake lock file updates:

• Updated input 'flake-parts':
    'github:hercules-ci/flake-parts/f2f7418ce0ab4a5309a4596161d154cfc877af66?narHash=sha256-soePLBazJk0qQdDVhdbM98vYdssfs3WFedcq%2BraipRI%3D' (2025-01-01)
  → 'github:hercules-ci/flake-parts/b905f6fc23a9051a6e1b741e1438dbfc0634c6de?narHash=sha256-%2Bhu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU%3D' (2025-01-06)
2025-01-13 00:00:03 +00:00
Clan Merge Bot
f40b1484f8 update flake lock - disko - 2025-01-13T00:00+00:00
Flake lock file updates:

• Updated input 'disko':
    'github:nix-community/disko/4d5d07d37ff773338e40a92088f45f4f88e509c8?narHash=sha256-9Sy17XguKdEU9M5peTrkWSlI/O5IAqjHzdzxbXnc30g%3D' (2025-01-09)
  → 'github:nix-community/disko/f720e64ec37fa16ebba6354eadf310f81555cc07?narHash=sha256-8hKhPQuMtXfJi%2B4lPvw3FBk/zSJVHeb726Zo0uF1PP8%3D' (2025-01-12)
2025-01-13 00:00:01 +00:00
clan-bot
17c62612ff Merge pull request 'pass move-mount-beneath: add more debug info' (#2725) from lassulus/clan-core:pass-debug into main 2025-01-12 10:22:22 +00:00
lassulus
3eaffe1ac6 pass move-mount-beneath: add more debug info 2025-01-12 11:17:22 +01:00
clan-bot
37fd0b3b6a Merge pull request 'clan-app: Change tkinter file dialogue to gtk4 file dialogue' (#2723) from Qubasa/clan-core:Qubasa-main into main 2025-01-12 07:43:56 +00:00
Qubasa
d6dd1e4652 clan-app: Change tkinter file dialogue to gtk4 file dialogue 2025-01-12 14:39:41 +07:00
clan-bot
35ae1f2286 Merge pull request 'Implement clan ssh <hostname>' (#2722) from pinpox/clan-core:clan-ssh-hostname into main 2025-01-11 22:23:00 +00:00
Pablo Ovelleiro Corral
b56dac3b96 Implement clan ssh <hostname>
Fixes #2317
2025-01-11 23:15:39 +01:00
pinpox
26d286a234 migration-guide (#2717)
This PR adds a migration guide for existing NixOS configurations.

Co-authored-by: Pablo Ovelleiro Corral <mail@pablo.tools>
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2717
Co-authored-by: pinpox <clan@pablo.tools>
Co-committed-by: pinpox <clan@pablo.tools>
2025-01-11 20:38:08 +00:00
clan-bot
103c740b10 Merge pull request 'vars: fix formatting in guide' (#2721) from DavHau/clan-core:DavHau-docs into main 2025-01-11 13:21:20 +00:00
DavHau
9df9e97970 vars: fix formatting in guide 2025-01-11 20:17:16 +07:00
clan-bot
00e9ef28fd Merge pull request 'vars: add guide for using vars to manage shared passwords' (#2720) from DavHau/clan-core:DavHau-docs into main 2025-01-11 13:06:19 +00:00
DavHau
afa03bc8d7 vars: add guide for using vars to manage shared passwords
This could be extended forther to cover more features, but it is a start
2025-01-11 20:01:47 +07:00
Luis Hebendanz
cd48ad1bbc Merge pull request 'clan-app: Rename dynamic library name, set macos x64 to unsupported' (#2719) from Qubasa/clan-core:Qubasa-main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2719
2025-01-11 06:07:15 +00:00
Qubasa
0ec238f406 clan-app: Rename dynamic library name, set macos x64 to unsupported 2025-01-11 13:06:40 +07:00
clan-bot
2b96e1b6d9 Merge pull request 'webview-lib: Force clangStdenv everywhere as MacOS requires clangStdenv. Add clang-tools else clang headers aren't found' (#2718) from Qubasa/clan-core:Qubasa-main into main 2025-01-11 05:59:28 +00:00
Qubasa
ed5754abb3 webview-lib: Force clangStdenv everywhere as MacOS requires clangStdenv. Add clang-tools else clang headers aren't found 2025-01-11 12:55:03 +07:00
DavHau
bbe37a998f vars: rename createFile -> persist 2025-01-11 04:19:46 +00:00
clan-bot
f743ec2616 Merge pull request 'clan-app: Fix default.nix' (#2699) from Qubasa/clan-core:Qubasa-main into main 2025-01-11 04:01:14 +00:00
Qubasa
f9314ea139 clan-app: allow darwin build 2025-01-11 10:55:50 +07:00
Qubasa
0caba58441 clan-app: allow darwin build 2025-01-11 10:55:50 +07:00
Qubasa
64e37a8970 clan-app: Add .local.env source script for local debug builds 2025-01-11 10:55:50 +07:00
Qubasa
df0550b6a6 clan-app: Fix webview crash on exception in api wrapper 2025-01-11 10:55:50 +07:00
Qubasa
0536127044 clan-app: Add gpg to allowed-programs.json 2025-01-11 10:52:22 +07:00
Qubasa
8d4d98361d clan-app: Fix default.nix 2025-01-11 10:52:22 +07:00
clan-bot
4f416eb32d Merge pull request 'Fix clan state list command' (#2716) from pinpox/clan-core:fix-state-list-command into main 2025-01-11 00:45:39 +00:00
Pablo Ovelleiro Corral
aa846cb39f Fix clan state list command 2025-01-11 01:39:41 +01:00
clan-bot
a68760d9c7 Merge pull request 'bump sops-nix' (#2713) from merge-when-green-joerg into main 2025-01-10 13:39:07 +00:00
Jörg Thalheim
898d762366 bump sops-nix 2025-01-10 14:33:18 +01:00
clan-bot
3dd4ff31dd Merge pull request 'Docs: add inventory concept introduction' (#2711) from hsjobeki/clan-core:docs/inventory into main 2025-01-10 12:20:27 +00:00
Johannes Kirschbauer
baeb31c228 Docs: add inventory concept introduction 2025-01-10 13:15:58 +01:00
clan-bot
aa762a7301 Merge pull request 'Add vars step to UI' (#2710) from hsjobeki/clan-core:hsjobeki-main into main 2025-01-10 12:15:33 +00:00
Johannes Kirschbauer
a3f6fb21c8 UI: add vars step to installation 2025-01-10 13:10:20 +01:00
Johannes Kirschbauer
4dcdb3e926 API: rename get_prompts to get_generators 2025-01-10 13:10:19 +01:00
Johannes Kirschbauer
b73de90487 Fix: select add portalRef instead of modalContextId 2025-01-10 13:07:47 +01:00
hsjobeki
b02dc42b0a Merge pull request 'Disk Templates: Fix invalid toml frontmatter' (#2702) from hsjobeki/clan-core:fix/disk into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2702
2025-01-10 12:06:41 +00:00
Johannes Kirschbauer
944ac371bd Disk Templates: Fix invalid toml frontmatter 2025-01-10 12:06:41 +00:00
hsjobeki
cfaa2f2e26 Merge pull request 'Inventory: warning on undefined tags, instead of error.' (#2696) from hsjobeki/clan-core:hsjobeki-main into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2696
2025-01-10 12:06:01 +00:00
Johannes Kirschbauer
65ccf8e970 Fix: add values prios eval tests 2025-01-10 12:06:01 +00:00
Johannes Kirschbauer
7fe996848e Webview: fix thread_task cannot raise exceptions 2025-01-10 12:06:01 +00:00
Johannes Kirschbauer
c6fe4f2625 API/vars: use string based interfaces to get and set vars to avoid state mutations 2025-01-10 12:06:01 +00:00
Johannes Kirschbauer
b6059fc506 Inventory: warning on undefined tags, instead of error. 2025-01-10 12:06:01 +00:00
clan-bot
3d962ee948 Merge pull request 'create synapse registration in systemd service instead of systemd.tmpfiles' (#2709) from merge-when-green-joerg into main 2025-01-10 11:50:36 +00:00
Jörg Thalheim
fe80e3c630 container-driver: also include journal/systemd status 2025-01-10 12:45:00 +01:00
Jörg Thalheim
20b8532822 create synapse registration in systemd service instead of systemd.tmpfiles 2025-01-10 12:45:00 +01:00
clan-bot
c21cc4b00d Merge pull request 'Update disko flake input' (#2708) from pinpox/clan-core:update-disko-input into main 2025-01-09 16:12:26 +00:00
Pablo Ovelleiro Corral
c7d9a7de2b Update disko flake input
Include fix from https://github.com/nix-community/disko/pull/934
The disko version before this makes the evaluation fail, if machines
import their own disko directly already.
2025-01-09 16:52:34 +01:00
Mic92
ca3e989aba Merge pull request 'docs: Add debugging.md and repo-layout.md guides' (#2706) from Mic92/clan-core:Qubasa-debugging-docs into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2706
2025-01-09 13:01:49 +00:00
Qubasa
5b51950e6d docs: Add debugging.md and repo-layout.md guides 2025-01-09 13:01:49 +00:00
clan-bot
4f76368f8e Merge pull request 'gui-install: replace expect with bash' (#2704) from test-pr into main 2025-01-09 11:49:13 +00:00
Jörg Thalheim
1420430d39 replace expect with bash. 2025-01-09 12:43:33 +01:00
319 changed files with 12302 additions and 6556 deletions

View File

@@ -8,5 +8,5 @@ jobs:
checks-impure:
runs-on: nix
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: nix run .#impure-checks

View File

@@ -7,7 +7,7 @@ jobs:
deploy-docs:
runs-on: nix
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: nix run .#deploy-docs
env:
SSH_HOMEPAGE_KEY: ${{ secrets.SSH_HOMEPAGE_KEY }}

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View File

@@ -3,10 +3,8 @@ on:
schedule:
- cron: "39 * * * *"
workflow_dispatch:
permissions:
contents: write
jobs:
repo-sync:
if: github.repository_owner == 'clan-lol'
@@ -15,10 +13,15 @@ jobs:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: actions/create-github-app-token@v1
id: app-token
with:
app-id: ${{ vars.CI_APP_ID }}
private-key: ${{ secrets.CI_PRIVATE_KEY }}
- name: repo-sync
uses: repo-sync/github-sync@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
with:
source_repo: "https://git.clan.lol/clan/clan-core.git"
source_branch: "main"

2
.gitignore vendored
View File

@@ -14,7 +14,7 @@ example_clan
nixos.qcow2
**/*.glade~
/docs/out
**/.local.env
# dream2nix
.dream2nix

View File

@@ -1,23 +1,4 @@
# Contributing to Clan
## Live-reloading documentation
Enter the `docs` directory:
```shell-session
cd docs
```
Enter the development shell or enable `direnv`:
```shell-session
direnv allow
```
Run a local server:
```shell-session
mkdocs serve
```
Open http://localhost:8000/ in your browser.
<!-- Local file: docs/CONTRIBUTING.md -->
Go to the Contributing guide at https://docs.clan.lol/manual/contribute/

View File

@@ -5,6 +5,12 @@
fileSystems."/".device = "/dev/null";
boot.loader.grub.device = "/dev/null";
};
clan.inventory.services = {
borgbackup.test-backup = {
roles.client.machines = [ "test-backup" ];
roles.server.machines = [ "test-backup" ];
};
};
flake.nixosModules = {
test-backup =
{
@@ -22,13 +28,20 @@
in
{
imports = [
self.clanModules.borgbackup
# Do not import inventory modules. They should be configured via 'clan.inventory'
#
# TODO: Configure localbackup via inventory
self.clanModules.localbackup
];
# Borgbackup overrides
services.borgbackup.repos.test-backups = {
path = "/var/lib/borgbackup/test-backups";
authorizedKeys = [ (builtins.readFile ../lib/ssh/pubkey) ];
};
clan.borgbackup.destinations.test-backup.repo = lib.mkForce "borg@machine:.";
clan.core.networking.targetHost = "machine";
networking.hostName = "machine";
services.openssh.settings.UseDns = false;
nixpkgs.hostPlatform = "x86_64-linux";
programs.ssh.knownHosts = {
machine.hostNames = [ "machine" ];
@@ -37,6 +50,8 @@
services.openssh = {
enable = true;
settings.UsePAM = false;
settings.UseDns = false;
hostKeys = [
{
path = "/root/.ssh/id_ed25519";
@@ -47,6 +62,10 @@
users.users.root.openssh.authorizedKeys.keyFiles = [ ../lib/ssh/pubkey ];
# This is needed to unlock the user for sshd
# Because we use sshd without setuid binaries
users.users.borg.initialPassword = "hello";
systemd.tmpfiles.settings."vmsecrets" = {
"/root/.ssh/id_ed25519" = {
C.argument = "${../lib/ssh/privkey}";
@@ -62,14 +81,14 @@
user = "root";
};
};
"/etc/secrets/borgbackup.ssh" = {
"/etc/secrets/borgbackup/borgbackup.ssh" = {
C.argument = "${../lib/ssh/privkey}";
z = {
mode = "0400";
user = "root";
};
};
"/etc/secrets/borgbackup.repokey" = {
"/etc/secrets/borgbackup/borgbackup.repokey" = {
C.argument = builtins.toString (pkgs.writeText "repokey" "repokey12345");
z = {
mode = "0400";
@@ -78,8 +97,7 @@
};
};
clan.core.facts.secretStore = "vm";
# TODO: set this backend as well, once we have implemented it.
#clan.core.vars.settings.secretStore = "vm";
clan.core.vars.settings.secretStore = "vm";
environment.systemPackages = [ self.packages.${pkgs.system}.clan-cli ];
environment.etc.install-closure.source = "${closureInfo}/store-paths";
@@ -104,7 +122,6 @@
'';
folders = [ "/var/test-service" ];
};
clan.borgbackup.destinations.test-backup.repo = "borg@machine:.";
fileSystems."/mnt/external-disk" = {
device = "/dev/vdb"; # created in tests with virtualisation.emptyDisks
@@ -125,29 +142,55 @@
touch /run/unmount-external-disk
'';
};
services.borgbackup.repos.test-backups = {
path = "/var/lib/borgbackup/test-backups";
authorizedKeys = [ (builtins.readFile ../lib/ssh/pubkey) ];
};
};
};
perSystem =
{ pkgs, ... }:
let
clanCore = self.filter {
include = [
"checks/backups"
"checks/flake-module.nix"
"clanModules/borgbackup"
"clanModules/flake-module.nix"
"clanModules/localbackup"
"clanModules/packages"
"clanModules/single-disk"
"clanModules/zerotier"
"flake.lock"
"flakeModules"
"inventory.json"
"lib/build-clan"
"lib/default.nix"
"lib/select.nix"
"lib/flake-module.nix"
"lib/frontmatter"
"lib/inventory"
"lib/constraints"
"nixosModules"
];
};
in
{
# Needs investigation on aarch64-linux
# vm-test-run-test-backups> qemu-kvm: No machine specified, and there is no default
# vm-test-run-test-backups> Use -machine help to list supported machines
checks = pkgs.lib.mkIf (pkgs.stdenv.isLinux && pkgs.stdenv.hostPlatform.system != "aarch64-linux") {
test-backups = (import ../lib/test-base.nix) {
checks = pkgs.lib.mkIf pkgs.stdenv.isLinux {
test-backups = (import ../lib/container-test.nix) {
name = "test-backups";
nodes.machine = {
imports = [
self.nixosModules.clanCore
self.nixosModules.test-backup
];
virtualisation.emptyDiskImages = [ 256 ];
imports =
[
self.nixosModules.clanCore
# Some custom overrides for the backup tests
self.nixosModules.test-backup
]
++
# import the inventory generated nixosModules
self.clanInternals.inventoryClass.machines.test-backup.machineImports;
clan.core.settings.directory = ./.;
environment.systemPackages = [
(pkgs.writeShellScriptBin "foo" ''
echo ${clanCore}
'')
];
};
testScript = ''
@@ -159,14 +202,14 @@
machine.succeed("echo testing > /var/test-backups/somefile")
# create
machine.succeed("clan backups create --debug --flake ${self} test-backup")
machine.succeed("clan backups create --debug --flake ${clanCore} test-backup")
machine.wait_until_succeeds("! systemctl is-active borgbackup-job-test-backup >&2")
machine.succeed("test -f /run/mount-external-disk")
machine.succeed("test -f /run/unmount-external-disk")
# list
backup_id = json.loads(machine.succeed("borg-job-test-backup list --json"))["archives"][0]["archive"]
out = machine.succeed("clan backups list --debug --flake ${self} test-backup").strip()
out = machine.succeed("clan backups list --debug --flake ${clanCore} test-backup").strip()
print(out)
assert backup_id in out, f"backup {backup_id} not found in {out}"
localbackup_id = "hdd::/mnt/external-disk/snapshot.0"
@@ -174,7 +217,7 @@
## borgbackup restore
machine.succeed("rm -f /var/test-backups/somefile")
machine.succeed(f"clan backups restore --debug --flake ${self} test-backup borgbackup 'test-backup::borg@machine:.::{backup_id}' >&2")
machine.succeed(f"clan backups restore --debug --flake ${clanCore} test-backup borgbackup 'test-backup::borg@machine:.::{backup_id}' >&2")
assert machine.succeed("cat /var/test-backups/somefile").strip() == "testing", "restore failed"
machine.succeed("test -f /var/test-service/pre-restore-command")
machine.succeed("test -f /var/test-service/post-restore-command")
@@ -182,7 +225,7 @@
## localbackup restore
machine.succeed("rm -rf /var/test-backups/somefile /var/test-service/ && mkdir -p /var/test-service")
machine.succeed(f"clan backups restore --debug --flake ${self} test-backup localbackup '{localbackup_id}' >&2")
machine.succeed(f"clan backups restore --debug --flake ${clanCore} test-backup localbackup '{localbackup_id}' >&2")
assert machine.succeed("cat /var/test-backups/somefile").strip() == "testing", "restore failed"
machine.succeed("test -f /var/test-service/pre-restore-command")
machine.succeed("test -f /var/test-service/post-restore-command")

View File

@@ -21,14 +21,14 @@
clan.core.state.testState.folders = [ "/etc/state" ];
environment.etc.state.text = "hello world";
systemd.tmpfiles.settings."vmsecrets" = {
"/etc/secrets/borgbackup.ssh" = {
"/etc/secrets/borgbackup/borgbackup.ssh" = {
C.argument = "${../lib/ssh/privkey}";
z = {
mode = "0400";
user = "root";
};
};
"/etc/secrets/borgbackup.repokey" = {
"/etc/secrets/borgbackup/borgbackup.repokey" = {
C.argument = builtins.toString (pkgs.writeText "repokey" "repokey12345");
z = {
mode = "0400";
@@ -36,7 +36,8 @@
};
};
};
clan.core.facts.secretStore = "vm";
# clan.core.facts.secretStore = "vm";
clan.core.vars.settings.secretStore = "vm";
clan.borgbackup.destinations.test.repo = "borg@localhost:.";
}

View File

@@ -1,7 +1,7 @@
(import ../lib/container-test.nix) (
{ ... }:
{
name = "secrets";
name = "container";
nodes.machine =
{ ... }:

View File

@@ -1,11 +1,19 @@
{ self, ... }:
{ self, lib, ... }:
let
inherit (lib)
filter
pathExists
;
in
{
imports = [
imports = filter pathExists [
./backups/flake-module.nix
./devshell/flake-module.nix
./flash/flake-module.nix
./impure/flake-module.nix
./installation/flake-module.nix
./installation-without-system/flake-module.nix
./morph/flake-module.nix
./nixos-documentation/flake-module.nix
];
perSystem =
@@ -42,7 +50,7 @@
flakeOutputs =
lib.mapAttrs' (
name: config: lib.nameValuePair "nixos-${name}" config.config.system.build.toplevel
) self.nixosConfigurations
) (lib.filterAttrs (n: _: !lib.hasPrefix "test-" n) self.nixosConfigurations)
// lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages
// lib.mapAttrs' (n: lib.nameValuePair "devShell-${n}") self'.devShells
// lib.mapAttrs' (name: config: lib.nameValuePair "home-manager-${name}" config.activation-script) (

View File

@@ -1,5 +1,39 @@
{ self, ... }:
{
config,
self,
lib,
...
}:
{
clan.machines = lib.listToAttrs (
lib.map (
system:
lib.nameValuePair "test-flash-machine-${system}" {
clan.core.networking.targetHost = "test-flash-machine";
fileSystems."/".device = lib.mkDefault "/dev/vda";
boot.loader.grub.device = lib.mkDefault "/dev/vda";
# We need to use `mkForce` because we inherit from `test-install-machine`
# which currently hardcodes `nixpkgs.hostPlatform`
nixpkgs.hostPlatform = lib.mkForce system;
imports = [ self.nixosModules.test-flash-machine ];
}
) (lib.filter (lib.hasSuffix "linux") config.systems)
);
flake.nixosModules = {
test-flash-machine =
{ lib, ... }:
{
imports = [ self.nixosModules.test-install-machine ];
clan.core.vars.generators.test = lib.mkForce { };
disko.devices.disk.main.preCreateHook = lib.mkForce "";
};
};
perSystem =
{
nodes,
@@ -10,17 +44,20 @@
let
dependencies = [
pkgs.disko
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-install-machine.config.system.build.toplevel
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-install-machine.config.system.build.diskoScript
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-install-machine.config.system.build.diskoScript.drvPath
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-install-machine.config.system.clan.deployment.file
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.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.hostPlatform.system}".config.system.clan.deployment.file
] ++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
in
{
# Currently disabled...
checks = pkgs.lib.mkIf (pkgs.stdenv.isLinux) {
flash = (import ../lib/test-base.nix) {
checks = pkgs.lib.mkIf pkgs.stdenv.isLinux {
test-flash = (import ../lib/test-base.nix) {
name = "flash";
nodes.target = {
virtualisation.emptyDiskImages = [ 4096 ];
@@ -42,7 +79,7 @@
testScript = ''
start_all()
machine.succeed("clan flash write --debug --flake ${../..} --yes --disk main /dev/vdb test-install-machine")
machine.succeed("clan flash write --debug --flake ${../..} --yes --disk main /dev/vdb test-flash-machine-${pkgs.hostPlatform.system}")
'';
} { inherit pkgs self; };
};

View File

@@ -30,6 +30,7 @@
# this disables dynamic dependency loading in clan-cli
export CLAN_NO_DYNAMIC_DEPS=1
export IN_PYTEST=1
nix develop "$ROOT#clan-cli" -c bash -c "TMPDIR=/tmp python -m pytest -m impure ./tests $@"
'';
};

View File

@@ -0,0 +1,241 @@
{
self,
lib,
...
}:
{
# The purpose of this test is to ensure `clan machines install` works
# for machines that don't have a hardware config yet.
# If this test starts failing it could be due to the `facter.json` being out of date
# you can get a new one by adding
# client.fail("cat test-flake/machines/test-install-machine/facter.json >&2")
# to the installation test.
clan.machines.test-install-machine-without-system = {
fileSystems."/".device = lib.mkDefault "/dev/vda";
boot.loader.grub.device = lib.mkDefault "/dev/vda";
imports = [ self.nixosModules.test-install-machine-without-system ];
};
clan.machines.test-install-machine-with-system =
{ pkgs, ... }:
{
# https://git.clan.lol/clan/test-fixtures
facter.reportPath = builtins.fetchurl {
url = "https://git.clan.lol/clan/test-fixtures/raw/commit/4a2bc56d886578124b05060d3fb7eddc38c019f8/nixos-vm-facter-json/${pkgs.hostPlatform.system}.json";
sha256 =
{
aarch64-linux = "sha256:1rlfymk03rmfkm2qgrc8l5kj5i20srx79n1y1h4nzlpwaz0j7hh2";
x86_64-linux = "sha256:16myh0ll2gdwsiwkjw5ba4dl23ppwbsanxx214863j7nvzx42pws";
}
.${pkgs.hostPlatform.system};
};
fileSystems."/".device = lib.mkDefault "/dev/vda";
boot.loader.grub.device = lib.mkDefault "/dev/vda";
imports = [ self.nixosModules.test-install-machine-without-system ];
};
flake.nixosModules = {
test-install-machine-without-system =
{ lib, modulesPath, ... }:
{
imports = [
(modulesPath + "/testing/test-instrumentation.nix") # we need these 2 modules always to be able to run the tests
(modulesPath + "/profiles/qemu-guest.nix")
../lib/minify.nix
];
networking.hostName = "test-install-machine";
environment.etc."install-successful".text = "ok";
boot.consoleLogLevel = lib.mkForce 100;
boot.kernelParams = [ "boot.shell_on_fail" ];
# disko config
boot.loader.grub.efiSupport = lib.mkDefault true;
boot.loader.grub.efiInstallAsRemovable = lib.mkDefault true;
clan.core.vars.settings.secretStore = "vm";
clan.core.vars.generators.test = {
files.test.neededFor = "partitioning";
script = ''
echo "notok" > $out/test
'';
};
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/vda";
preCreateHook = ''
test -e /run/partitioning-secrets/test/test
'';
content = {
type = "gpt";
partitions = {
boot = {
size = "1M";
type = "EF02"; # for grub MBR
priority = 1;
};
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
};
};
perSystem =
{
pkgs,
lib,
...
}:
let
dependencies = [
self
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-install-machine-with-system.config.system.build.toplevel
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-install-machine-with-system.config.system.build.diskoScript
self.clanInternals.machines.${pkgs.hostPlatform.system}.test-install-machine-with-system.config.system.clan.deployment.file
pkgs.stdenv.drvPath
pkgs.bash.drvPath
pkgs.nixos-anywhere
pkgs.bubblewrap
] ++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
# with Nix 2.24 we get:
# vm-test-run-test-installation> client # error: sized: unexpected end-of-file
# vm-test-run-test-installation> client # error: unexpected end-of-file
# This seems to be fixed with Nix 2.26
# Remove this line once `pkgs.nix` is 2.26+
nixPackage =
assert
lib.versionOlder pkgs.nix.version "2.26"
&& lib.versionAtLeast pkgs.nixVersions.latest.version "2.26";
pkgs.nixVersions.latest;
in
{
# On aarch64-linux, hangs on reboot with after installation:
# vm-test-run-test-installation-without-system> installer # [ 288.002871] reboot: Restarting system
# vm-test-run-test-installation-without-system> client # [test-install-machine] ### Done! ###
# vm-test-run-test-installation-without-system> client # [test-install-machine] + step 'Done!'
# vm-test-run-test-installation-without-system> client # [test-install-machine] + echo '### Done! ###'
# vm-test-run-test-installation-without-system> client # [test-install-machine] + rm -rf /tmp/tmp.qb16EAq7hJ
# vm-test-run-test-installation-without-system> (finished: must succeed: clan machines install --debug --flake test-flake --yes test-install-machine-without-system --target-host root@installer --update-hardware-config nixos-facter >&2, in 154.62 seconds)
# vm-test-run-test-installation-without-system> target: starting vm
# vm-test-run-test-installation-without-system> target: QEMU running (pid 144)
# vm-test-run-test-installation-without-system> target: waiting for unit multi-user.target
# vm-test-run-test-installation-without-system> target: waiting for the VM to finish booting
# vm-test-run-test-installation-without-system> target: Guest root shell did not produce any data yet...
# vm-test-run-test-installation-without-system> target: To debug, enter the VM and run 'systemctl status backdoor.service'.
checks = pkgs.lib.mkIf (pkgs.stdenv.isLinux && !pkgs.stdenv.isAarch64) {
test-installation-without-system = (import ../lib/test-base.nix) {
name = "test-installation-without-system";
nodes.target = {
services.openssh.enable = true;
virtualisation.diskImage = "./target.qcow2";
virtualisation.useBootLoader = true;
nix.package = nixPackage;
};
nodes.installer =
{ modulesPath, ... }:
{
imports = [
(modulesPath + "/../tests/common/auto-format-root-device.nix")
];
services.openssh.enable = true;
system.nixos.variant_id = "installer";
environment.systemPackages = [ pkgs.nixos-facter ];
virtualisation.emptyDiskImages = [ 512 ];
virtualisation.diskSize = 8 * 1024;
virtualisation.rootDevice = "/dev/vdb";
# both installer and target need to use the same diskImage
virtualisation.diskImage = "./target.qcow2";
nix.package = nixPackage;
nix.settings = {
substituters = lib.mkForce [ ];
hashed-mirrors = null;
connect-timeout = lib.mkForce 3;
flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}'';
experimental-features = [
"nix-command"
"flakes"
];
};
users.users.nonrootuser = {
isNormalUser = true;
openssh.authorizedKeys.keyFiles = [ ../lib/ssh/pubkey ];
extraGroups = [ "wheel" ];
};
security.sudo.wheelNeedsPassword = false;
system.extraDependencies = dependencies;
};
nodes.client = {
environment.systemPackages = [
self.packages.${pkgs.system}.clan-cli
] ++ self.packages.${pkgs.system}.clan-cli.runtimeDependencies;
environment.etc."install-closure".source = "${closureInfo}/store-paths";
virtualisation.memorySize = 3048;
nix.package = nixPackage;
nix.settings = {
substituters = lib.mkForce [ ];
hashed-mirrors = null;
connect-timeout = lib.mkForce 3;
flake-registry = pkgs.writeText "flake-registry" ''{"flakes":[],"version":2}'';
experimental-features = [
"nix-command"
"flakes"
];
};
system.extraDependencies = dependencies;
};
testScript = ''
client.start()
installer.start()
client.succeed("${pkgs.coreutils}/bin/install -Dm 600 ${../lib/ssh/privkey} /root/.ssh/id_ed25519")
client.wait_until_succeeds("timeout 2 ssh -o StrictHostKeyChecking=accept-new -v nonrootuser@installer hostname")
client.succeed("cp -r ${../..} test-flake && chmod -R +w test-flake")
client.fail("test -f test-flake/machines/test-install-machine-without-system/hardware-configuration.nix")
client.fail("test -f test-flake/machines/test-install-machine-without-system/facter.json")
client.succeed("clan machines update-hardware-config --flake test-flake test-install-machine-without-system nonrootuser@installer >&2")
client.succeed("test -f test-flake/machines/test-install-machine-without-system/facter.json")
client.succeed("rm test-flake/machines/test-install-machine-without-system/facter.json")
client.succeed("clan machines install --debug --flake test-flake --yes test-install-machine-without-system --target-host nonrootuser@installer --update-hardware-config nixos-facter >&2")
try:
installer.shutdown()
except BrokenPipeError:
# qemu has already exited
pass
target.state_dir = installer.state_dir
target.start()
target.wait_for_unit("multi-user.target")
assert(target.succeed("cat /etc/install-successful").strip() == "ok")
'';
} { inherit pkgs self; };
};
};
}

View File

@@ -1,6 +1,5 @@
{
self,
inputs,
lib,
...
}:
@@ -17,18 +16,68 @@
{ lib, modulesPath, ... }:
{
imports = [
self.clanModules.single-disk
(modulesPath + "/testing/test-instrumentation.nix") # we need these 2 modules always to be able to run the tests
(modulesPath + "/profiles/qemu-guest.nix")
../lib/minify.nix
];
clan.single-disk.device = "/dev/vda";
environment.etc."install-successful".text = "ok";
nixpkgs.hostPlatform = "x86_64-linux";
boot.consoleLogLevel = lib.mkForce 100;
boot.kernelParams = [ "boot.shell_on_fail" ];
# disko config
boot.loader.grub.efiSupport = lib.mkDefault true;
boot.loader.grub.efiInstallAsRemovable = lib.mkDefault true;
clan.core.vars.settings.secretStore = "vm";
clan.core.vars.generators.test = {
files.test.neededFor = "partitioning";
script = ''
echo "notok" > $out/test
'';
};
disko.devices = {
disk = {
main = {
type = "disk";
device = "/dev/vda";
preCreateHook = ''
test -e /run/partitioning-secrets/test/test
'';
content = {
type = "gpt";
partitions = {
boot = {
size = "1M";
type = "EF02"; # for grub MBR
priority = 1;
};
ESP = {
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
root = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
};
};
};
};
};
};
};
};
perSystem =
@@ -43,10 +92,23 @@
self.nixosConfigurations.test-install-machine.config.system.build.toplevel
self.nixosConfigurations.test-install-machine.config.system.build.diskoScript
self.nixosConfigurations.test-install-machine.config.system.clan.deployment.file
pkgs.bash.drvPath
pkgs.stdenv.drvPath
pkgs.nixos-anywhere
pkgs.bubblewrap
] ++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
# with Nix 2.24 we get:
# vm-test-run-test-installation> client # error: sized: unexpected end-of-file
# vm-test-run-test-installation> client # error: unexpected end-of-file
# This seems to be fixed with Nix 2.26
# Remove this line once `pkgs.nix` is 2.26+
nixPackage =
assert
lib.versionOlder pkgs.nix.version "2.26"
&& lib.versionAtLeast pkgs.nixVersions.latest.version "2.26";
pkgs.nixVersions.latest;
in
{
# On aarch64-linux, hangs on reboot with after installation:
@@ -58,13 +120,14 @@
# vm-test-run-test-installation> new_machine: QEMU running (pid 80)
# vm-test-run-test-installation> new_machine: Guest root shell did not produce any data yet...
# vm-test-run-test-installation> new_machine: To debug, enter the VM and run 'systemctl status backdoor.service'.
checks = pkgs.lib.mkIf (pkgs.stdenv.isLinux && pkgs.stdenv.hostPlatform.system != "aarch64-linux") {
checks = pkgs.lib.mkIf (pkgs.stdenv.isLinux && !pkgs.stdenv.isAarch64) {
test-installation = (import ../lib/test-base.nix) {
name = "test-installation";
nodes.target = {
services.openssh.enable = true;
virtualisation.diskImage = "./target.qcow2";
virtualisation.useBootLoader = true;
nix.package = nixPackage;
# virtualisation.fileSystems."/" = {
# device = "/dev/disk/by-label/this-is-not-real-and-will-never-be-used";
@@ -86,6 +149,7 @@
virtualisation.rootDevice = "/dev/vdb";
# both installer and target need to use the same diskImage
virtualisation.diskImage = "./target.qcow2";
nix.package = nixPackage;
nix.settings = {
substituters = lib.mkForce [ ];
hashed-mirrors = null;
@@ -103,7 +167,8 @@
self.packages.${pkgs.system}.clan-cli
] ++ self.packages.${pkgs.system}.clan-cli.runtimeDependencies;
environment.etc."install-closure".source = "${closureInfo}/store-paths";
virtualisation.memorySize = 2048;
virtualisation.memorySize = 3048;
nix.package = nixPackage;
nix.settings = {
substituters = lib.mkForce [ ];
hashed-mirrors = null;
@@ -124,12 +189,19 @@
client.succeed("${pkgs.coreutils}/bin/install -Dm 600 ${../lib/ssh/privkey} /root/.ssh/id_ed25519")
client.wait_until_succeeds("timeout 2 ssh -o StrictHostKeyChecking=accept-new -v root@installer hostname")
client.succeed("cp -r ${../..} test-flake && chmod -R +w test-flake")
# test that we can generate hardware configurations
client.fail("test -f test-flake/machines/test-install-machine/facter.json")
client.fail("test -f test-flake/machines/test-install-machine/hardware-configuration.nix")
client.succeed("clan machines update-hardware-config --flake test-flake test-install-machine root@installer >&2")
client.succeed("test -f test-flake/machines/test-install-machine/hardware-configuration.nix")
client.succeed("clan machines update-hardware-config --backend nixos-facter --flake test-flake test-install-machine root@installer>&2")
client.succeed("test -f test-flake/machines/test-install-machine/facter.json")
client.succeed("clan machines install --debug --flake ${../..} --yes test-install-machine --target-host root@installer >&2")
client.succeed("clan machines update-hardware-config --backend nixos-generate-config --flake test-flake test-install-machine root@installer>&2")
client.succeed("test -f test-flake/machines/test-install-machine/hardware-configuration.nix")
# but we don't use them because they're not cached
client.succeed("rm test-flake/machines/test-install-machine/hardware-configuration.nix test-flake/machines/test-install-machine/facter.json")
client.succeed("clan machines install --debug --flake test-flake --yes test-install-machine --target-host root@installer >&2")
try:
installer.shutdown()
except BrokenPipeError:

View File

@@ -7,9 +7,19 @@
let
testDriver = hostPkgs.python3.pkgs.callPackage ./package.nix {
inherit (config) extraPythonPackages;
inherit (hostPkgs.pkgs) util-linux systemd;
inherit (hostPkgs.pkgs) util-linux systemd nix;
};
containers = map (m: m.system.build.toplevel) (lib.attrValues config.nodes);
containers =
testScript:
map (m: [
m.system.build.toplevel
(hostPkgs.closureInfo {
rootPaths = [
m.system.build.toplevel
(hostPkgs.writeText "testScript" testScript)
];
})
]) (lib.attrValues config.nodes);
pythonizeName =
name:
let
@@ -44,8 +54,6 @@ in
''
mkdir -p $out/bin
containers=(${toString containers})
${lib.optionalString (!config.skipTypeCheck) ''
# prepend type hints so the test script can be type checked with mypy
cat "${./test-script-prepend.py}" >> testScriptWithTypes
@@ -66,7 +74,13 @@ in
ln -s ${testDriver}/bin/nixos-test-driver $out/bin/nixos-test-driver
wrapProgram $out/bin/nixos-test-driver \
${lib.concatStringsSep " " (map (name: "--add-flags '--container ${name}'") containers)} \
${
lib.concatStringsSep " " (
map (container: "--add-flags '--container ${builtins.toString container}'") (
containers config.testScriptString
)
)
} \
--add-flags "--test-script '$out/test-script'"
''
);

View File

@@ -5,6 +5,7 @@
setuptools,
util-linux,
systemd,
nix,
colorama,
junit-xml,
}:
@@ -16,6 +17,7 @@ buildPythonApplication {
systemd
colorama
junit-xml
nix
] ++ extraPythonPackages python3Packages;
nativeBuildInputs = [ setuptools ];
format = "pyproject";

View File

@@ -1,4 +1,5 @@
import argparse
import ctypes
import os
import re
import subprocess
@@ -12,6 +13,55 @@ from typing import Any
from .logger import AbstractLogger, CompositeLogger, TerminalLogger
# Load the C library
libc = ctypes.CDLL("libc.so.6", use_errno=True)
# Define the mount function
libc.mount.argtypes = [
ctypes.c_char_p, # source
ctypes.c_char_p, # target
ctypes.c_char_p, # filesystemtype
ctypes.c_ulong, # mountflags
ctypes.c_void_p, # data
]
libc.mount.restype = ctypes.c_int
MS_BIND = 0x1000
MS_REC = 0x4000
def mount(
source: Path,
target: Path,
filesystemtype: str,
mountflags: int = 0,
data: str | None = None,
) -> None:
"""
A Python wrapper for the mount system call.
:param source: The source of the file system (e.g., device name, remote filesystem).
:param target: The mount point (an existing directory).
:param filesystemtype: The filesystem type (e.g., "ext4", "nfs").
:param mountflags: Mount options flags.
:param data: File system-specific data (e.g., options like "rw").
:raises OSError: If the mount system call fails.
"""
# Convert Python strings to C-compatible strings
source_c = ctypes.c_char_p(str(source).encode("utf-8"))
target_c = ctypes.c_char_p(str(target).encode("utf-8"))
fstype_c = ctypes.c_char_p(filesystemtype.encode("utf-8"))
data_c = ctypes.c_char_p(data.encode("utf-8")) if data else None
# Call the mount system call
result = libc.mount(
source_c, target_c, fstype_c, ctypes.c_ulong(mountflags), data_c
)
if result != 0:
errno = ctypes.get_errno()
raise OSError(errno, os.strerror(errno))
class Error(Exception):
pass
@@ -71,7 +121,7 @@ class Machine:
self.rootdir,
"--register=no",
"--resolv-conf=off",
"--bind-ro=/nix/store",
"--bind=/nix",
"--bind",
self.out_dir,
"--bind=/proc:/run/host/proc",
@@ -102,9 +152,9 @@ class Machine:
.read_text()
.split()
)
assert (
len(childs) == 1
), f"Expected exactly one child process for systemd-nspawn, got {childs}"
assert len(childs) == 1, (
f"Expected exactly one child process for systemd-nspawn, got {childs}"
)
try:
return int(childs[0])
except ValueError as e:
@@ -253,7 +303,9 @@ class Machine:
info = self.get_unit_info(unit)
state = info["ActiveState"]
if state == "failed":
msg = f'unit "{unit}" reached state "{state}"'
proc = self.systemctl(f"--lines 0 status {unit}")
journal = self.execute(f"journalctl -u {unit} --no-pager")
msg = f'unit "{unit}" reached state "{state}":\n{proc.stdout}\n{journal.stdout}'
raise Error(msg)
if state == "inactive":
@@ -271,7 +323,9 @@ class Machine:
def succeed(self, command: str, timeout: int | None = None) -> str:
res = self.execute(command, timeout=timeout)
if res.returncode != 0:
msg = f"Failed to run command {command}"
msg = f"Failed to run command {command}\n"
msg += f"Exit code: {res.returncode}\n"
msg += f"Stdout: {res.stdout}"
raise RuntimeError(msg)
return res.stdout
@@ -288,6 +342,12 @@ class Machine:
self.shutdown()
NIX_DIR = Path("/nix")
NIX_STORE = Path("/nix/store/")
NEW_NIX_DIR = Path("/.nix-rw")
NEW_NIX_STORE_DIR = NEW_NIX_DIR / "store"
def setup_filesystems() -> None:
# We don't care about cleaning up the mount points, since we're running in a nix sandbox.
Path("/run").mkdir(parents=True, exist_ok=True)
@@ -296,6 +356,32 @@ def setup_filesystems() -> None:
Path("/etc").chmod(0o755)
Path("/etc/os-release").touch()
Path("/etc/machine-id").write_text("a5ea3f98dedc0278b6f3cc8c37eeaeac")
NEW_NIX_STORE_DIR.mkdir(parents=True)
# Read /proc/mounts and replicate every bind mount
with Path("/proc/self/mounts").open() as f:
for line in f:
columns = line.split(" ")
source = Path(columns[1])
if source.parent != NIX_STORE:
continue
target = NEW_NIX_STORE_DIR / source.name
if source.is_dir():
target.mkdir()
else:
target.touch()
try:
mount(source, target, "none", MS_BIND)
except OSError as e:
msg = f"mount({source}, {target}) failed"
raise Error(msg) from e
out = Path(os.environ["out"])
(NEW_NIX_STORE_DIR / out.name).mkdir()
mount(NEW_NIX_DIR, NIX_DIR, "none", MS_BIND | MS_REC)
def load_nix_db(closure_info: Path) -> None:
with (closure_info / "registration").open() as f:
subprocess.run(["nix-store", "--load-db"], stdin=f, check=True, text=True)
class Driver:
@@ -303,7 +389,7 @@ class Driver:
def __init__(
self,
containers: list[Path],
containers: list[tuple[Path, Path]],
logger: AbstractLogger,
testscript: str,
out_dir: str,
@@ -313,21 +399,24 @@ class Driver:
self.out_dir = out_dir
self.logger = logger
setup_filesystems()
# TODO: this won't work for multiple containers
assert len(containers) == 1, "Only one container is supported at the moment"
load_nix_db(containers[0][1])
self.tempdir = TemporaryDirectory()
tempdir_path = Path(self.tempdir.name)
self.machines = []
for container in containers:
name_match = re.match(r".*-nixos-system-(.+)-(.+)", container.name)
name_match = re.match(r".*-nixos-system-(.+)-(.+)", container[0].name)
if not name_match:
msg = f"Unable to extract hostname from {container.name}"
msg = f"Unable to extract hostname from {container[0].name}"
raise Error(msg)
name = name_match.group(1)
self.machines.append(
Machine(
name=name,
toplevel=container,
toplevel=container[0],
rootdir=tempdir_path / name,
out_dir=self.out_dir,
logger=self.logger,
@@ -399,9 +488,11 @@ def main() -> None:
arg_parser = argparse.ArgumentParser(prog="nixos-test-driver")
arg_parser.add_argument(
"--containers",
nargs="+",
nargs=2,
action="append",
type=Path,
help="container system toplevel paths",
metavar=("TOPLEVEL_STORE_DIR", "CLOSURE_INFO"),
help="container system toplevel store dir and closure info",
)
arg_parser.add_argument(
"--test-script",

View File

@@ -16,6 +16,9 @@ in
documentation.enable = lib.mkDefault false;
boot.isContainer = true;
# needed since nixpkgs 7fb2f407c01b017737eafc26b065d7f56434a992 removed the getty unit by default
console.enable = true;
# undo qemu stuff
system.build.initialRamdisk = "";
virtualisation.sharedDirectories = lib.mkForce { };
@@ -25,9 +28,13 @@ in
networking.interfaces = lib.mkForce { };
#networking.primaryIPAddress = lib.mkForce null;
systemd.services.backdoor.enable = false;
# we don't have permission to set cpu scheduler in our container
systemd.services.nix-daemon.serviceConfig.CPUSchedulingPolicy = lib.mkForce "";
};
# to accept external dependencies such as disko
node.specialArgs.self = self;
_module.args = { inherit self; };
imports = [
test
./container-driver/module.nix

View File

@@ -1,7 +1,8 @@
{ lib, ... }:
{
nixpkgs.flake.setFlakeRegistry = false;
nixpkgs.flake.setNixPath = false;
nix.registry.nixpkgs.to = { };
nix.registry = lib.mkForce { };
documentation.doc.enable = false;
documentation.man.enable = false;
}

View File

@@ -7,15 +7,19 @@ in
(nixos-lib.runTest {
hostPkgs = pkgs;
# speed-up evaluation
defaults = {
imports = [
./minify.nix
];
documentation.enable = lib.mkDefault false;
nix.settings.min-free = 0;
system.stateVersion = lib.version;
};
defaults = (
{ config, ... }:
{
imports = [
./minify.nix
];
documentation.enable = lib.mkDefault false;
nix.settings.min-free = 0;
system.stateVersion = config.system.nixos.release;
}
);
_module.args = { inherit self; };
# to accept external dependencies such as disko
node.specialArgs.self = self;
imports = [ test ];

View File

@@ -31,6 +31,8 @@
clan.matrix-synapse.users.someuser = { };
clan.core.facts.secretStore = "vm";
clan.core.vars.settings.secretStore = "vm";
clan.core.vars.settings.publicStore = "in_repo";
# because we use systemd-tmpfiles to copy the secrets, we need to a separate systemd-tmpfiles call to provision them.
boot.postBootCommands = "${config.systemd.package}/bin/systemd-tmpfiles --create /etc/tmpfiles.d/00-vmsecrets.conf";
@@ -41,21 +43,21 @@
d.mode = "0700";
z.mode = "0700";
};
"/etc/secrets/synapse-registration_shared_secret" = {
"/etc/secrets/matrix-synapse/synapse-registration_shared_secret" = {
f.argument = "supersecret";
z = {
mode = "0400";
user = "root";
};
};
"/etc/secrets/matrix-password-admin" = {
"/etc/secrets/matrix-password-admin/matrix-password-admin" = {
f.argument = "matrix-password1";
z = {
mode = "0400";
user = "root";
};
};
"/etc/secrets/matrix-password-someuser" = {
"/etc/secrets/matrix-password-someuser/matrix-password-someuser" = {
f.argument = "matrix-password2";
z = {
mode = "0400";

View File

@@ -0,0 +1,62 @@
{
self,
...
}:
{
clan.machines.test-morph-machine = {
imports = [
./template/configuration.nix
self.nixosModules.clanCore
];
nixpkgs.hostPlatform = "x86_64-linux";
environment.etc."testfile".text = "morphed";
};
clan.templates.machine.test-morph-template = {
description = "Morph a machine";
path = ./template;
};
perSystem =
{
pkgs,
...
}:
{
checks = pkgs.lib.mkIf (pkgs.stdenv.isLinux && !pkgs.stdenv.isAarch64) {
test-morph = (import ../lib/test-base.nix) {
name = "morph";
nodes = {
actual =
{ pkgs, ... }:
let
dependencies = [
self
pkgs.nixos-anywhere
pkgs.stdenv.drvPath
pkgs.stdenvNoCC
self.nixosConfigurations.test-morph-machine.config.system.build.toplevel
self.nixosConfigurations.test-morph-machine.config.system.clan.deployment.file
] ++ builtins.map (i: i.outPath) (builtins.attrValues self.inputs);
closureInfo = pkgs.closureInfo { rootPaths = dependencies; };
in
{
environment.etc."install-closure".source = "${closureInfo}/store-paths";
system.extraDependencies = dependencies;
virtualisation.memorySize = 2048;
environment.systemPackages = [ self.packages.${pkgs.system}.clan-cli ];
};
};
testScript = ''
start_all()
actual.fail("cat /etc/testfile")
actual.succeed("env CLAN_DIR=${self} clan machines morph test-morph-template --i-will-be-fired-for-using-this --debug --name test-morph-machine")
assert actual.succeed("cat /etc/testfile") == "morphed"
'';
} { inherit pkgs self; };
};
};
}

View File

@@ -0,0 +1,12 @@
{ modulesPath, ... }:
{
imports = [
# we need these 2 modules always to be able to run the tests
(modulesPath + "/testing/test-instrumentation.nix")
(modulesPath + "/virtualisation/qemu-vm.nix")
(modulesPath + "/profiles/minimal.nix")
];
clan.core.enableRecommendedDefaults = false;
}

View File

@@ -0,0 +1,8 @@
---
description = "Set up automatic upgrades"
categories = ["System"]
features = [ "inventory" ]
---
Whether to periodically upgrade NixOS to the latest version. If enabled, a
systemd timer will run `nixos-rebuild switch --upgrade` once a day.

View File

@@ -0,0 +1,24 @@
{
config,
lib,
...
}:
let
cfg = config.clan.autoUpgrade;
in
{
options.clan.autoUpgrade = {
flake = lib.mkOption {
type = lib.types.str;
description = "Flake reference";
};
};
config = {
system.autoUpgrade = {
inherit (cfg.clan.autoUpgrade) flake;
enable = true;
dates = "02:00";
randomizedDelaySec = "45min";
};
};
}

View File

@@ -63,9 +63,9 @@ in
rsh = lib.mkOption {
type = lib.types.str;
default = "ssh -i ${
config.clan.core.facts.services.borgbackup.secret."borgbackup.ssh".path
config.clan.core.vars.generators.borgbackup.files."borgbackup.ssh".path
} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=Yes";
defaultText = "ssh -i \${config.clan.core.facts.services.borgbackup.secret.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null";
defaultText = "ssh -i \${config.clan.core.vars.generators.borgbackup.files.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null";
description = "the rsh to use for the backup";
};
};
@@ -126,7 +126,7 @@ in
encryption = {
mode = "repokey";
passCommand = "cat ${config.clan.core.facts.services.borgbackup.secret."borgbackup.repokey".path}";
passCommand = "cat ${config.clan.core.vars.generators.borgbackup.files."borgbackup.repokey".path}";
};
prune.keep = {
@@ -177,20 +177,21 @@ in
})
];
# Facts generation. So the client can authenticate to the server
clan.core.facts.services.borgbackup = {
public."borgbackup.ssh.pub" = { };
secret."borgbackup.ssh" = { };
secret."borgbackup.repokey" = { };
generator.path = [
pkgs.openssh
clan.core.vars.generators.borgbackup = {
files."borgbackup.ssh.pub".secret = false;
files."borgbackup.ssh" = { };
files."borgbackup.repokey" = { };
migrateFact = "borgbackup";
runtimeInputs = [
pkgs.coreutils
pkgs.openssh
pkgs.xkcdpass
];
generator.script = ''
ssh-keygen -t ed25519 -N "" -f "$secrets"/borgbackup.ssh
mv "$secrets"/borgbackup.ssh.pub "$facts"/borgbackup.ssh.pub
xkcdpass -n 4 -d - > "$secrets"/borgbackup.repokey
script = ''
ssh-keygen -t ed25519 -N "" -f $out/borgbackup.ssh
xkcdpass -n 4 -d - > $out/borgbackup.repokey
'';
};

View File

@@ -1,7 +1,7 @@
{ config, lib, ... }:
let
dir = config.clan.core.settings.directory;
machineDir = dir + "/machines/";
machineDir = dir + "/vars/per-machine/";
machineName = config.clan.core.settings.machine.name;
# Instances might be empty, if the module is not used via the inventory
@@ -33,7 +33,8 @@ in
};
config.services.borgbackup.repos =
let
borgbackupIpMachinePath = machines: machineDir + machines + "/facts/borgbackup.ssh.pub";
borgbackupIpMachinePath = machine: machineDir + machine + "/borgbackup/borgbackup.ssh.pub/value";
machinesMaybeKey = builtins.map (
machine:
let
@@ -44,7 +45,7 @@ in
else
lib.warn ''
Machine ${machine} does not have a borgbackup key at ${fullPath},
run `clan facts generate ${machine}` to generate it.
run `clan var generate ${machine}` to generate it.
'' null
) allClients;

View File

@@ -52,7 +52,7 @@ let
migrateFact = "${secret_id opt}";
prompts.${secret_id opt} = {
type = "hidden";
createFile = true;
persist = true;
};
};
};

View File

@@ -1,7 +1,15 @@
{ ... }:
{ lib, ... }:
let
inherit (lib)
filterAttrs
pathExists
;
in
{
flake.clanModules = {
# only import available files, as this allows to filter the files for tests.
flake.clanModules = filterAttrs (_name: pathExists) {
admin = ./admin;
auto-upgrade = ./auto-upgrade;
borgbackup = ./borgbackup;
borgbackup-static = ./borgbackup-static;
deltachat = ./deltachat;
@@ -19,6 +27,7 @@
matrix-synapse = ./matrix-synapse;
moonlight = ./moonlight;
mumble = ./mumble;
mycelium = ./mycelium;
nginx = ./nginx;
packages = ./packages;
postgresql = ./postgresql;

View File

@@ -3,8 +3,7 @@ description = "S3-compatible object store for small self-hosted geo-distributed
---
This module generates garage specific keys automatically.
When using garage in a distributed deployment the `rpc_key` between connected instances must be shared.
This is currently still a manual process.
Also shares the `rpc_secret` between instances.
Options: [NixosModuleOptions](https://search.nixos.org/options?channel=unstable&size=50&sort=relevance&type=packages&query=garage)
Documentation: https://garagehq.deuxfleurs.fr/

View File

@@ -2,9 +2,9 @@
{
systemd.services.garage.serviceConfig = {
LoadCredential = [
"rpc_secret_path:${config.clan.core.facts.services.garage.secret.garage_rpc_secret.path}"
"admin_token_path:${config.clan.core.facts.services.garage.secret.garage_admin_token.path}"
"metrics_token_path:${config.clan.core.facts.services.garage.secret.garage_metrics_token.path}"
"rpc_secret_path:${config.clan.core.vars.generators.garage-shared.files.rpc_secret.path}"
"admin_token_path:${config.clan.core.vars.generators.garage.files.admin_token.path}"
"metrics_token_path:${config.clan.core.vars.generators.garage.files.metrics_token.path}"
];
Environment = [
"GARAGE_ALLOW_WORLD_READABLE_SECRETS=true"
@@ -14,37 +14,30 @@
];
};
clan.core.facts.services.garage = {
secret.garage_rpc_secret = { };
secret.garage_admin_token = { };
secret.garage_metrics_token = { };
generator.path = [
clan.core.vars.generators.garage = {
files.admin_token = { };
files.metrics_token = { };
runtimeInputs = [
pkgs.coreutils
pkgs.openssl
];
generator.script = ''
openssl rand -hex -out $secrets/garage_rpc_secret 32
openssl rand -base64 -out $secrets/garage_admin_token 32
openssl rand -base64 -out $secrets/garage_metrics_token 32
script = ''
openssl rand -base64 -out $out/admin_token 32
openssl rand -base64 -out $out/metrics_token 32
'';
};
# TODO: Vars is not in a useable state currently
# Move back, once it is implemented.
# clan.core.vars.generators.garage = {
# files.rpc_secret = { };
# files.admin_token = { };
# files.metrics_token = { };
# runtimeInputs = [
# pkgs.coreutils
# pkgs.openssl
# ];
# script = ''
# openssl rand -hex -out $out/rpc_secret 32
# openssl rand -base64 -out $out/admin_token 32
# openssl rand -base64 -out $out/metrics_token 32
# '';
# };
clan.core.vars.generators.garage-shared = {
share = true;
files.rpc_secret = { };
runtimeInputs = [
pkgs.coreutils
pkgs.openssl
];
script = ''
openssl rand -hex -out $out/rpc_secret 32
'';
};
clan.core.state.garage.folders = [ config.services.garage.settings.metadata_dir ];
}

View File

@@ -6,4 +6,4 @@ categories = [ "Network" ]
!!! Warning
If you've been using network manager + wpa_supplicant and now are switching to IWD read this migration guide:
https://iwd.wiki.kernel.org/networkmanager#converting_network_profiles
https://archive.kernel.org/oldwiki/iwd.wiki.kernel.org/networkmanager.html#converting_network_profiles

View File

@@ -1,4 +1,9 @@
{ lib, config, ... }:
{
lib,
config,
pkgs,
...
}:
let
cfg = config.clan.iwd;
@@ -12,12 +17,13 @@ let
{
secret.${secret_name} = { };
generator.prompt = "Wifi password for '${value.ssid}'";
# ref. man iwd.network
generator.script = ''
config="
[Settings]
AutoConnect=${if value.AutoConnect then "true" else "false"}
[Security]
Passphrase=\"$prompt_value\"
Passphrase=$(echo -e "$prompt_value" | ${lib.getExe pkgs.gnused} "s=\\\=\\\\\\\=g;s=\t=\\\t=g;s=\r=\\\r=g;s=^ =\\\s=")
"
echo "$config" > "$secrets/${secret_name}"
'';

View File

@@ -10,18 +10,18 @@ let
in
{
config = lib.mkMerge [
(lib.mkIf ((var.machineId.value or null) != null) {
(lib.mkIf ((var.value or null) != null) {
assertions = [
{
assertion = lib.stringLength var.machineId.value == 32;
assertion = lib.stringLength var.value == 32;
message = "machineId must be exactly 32 characters long.";
}
];
boot.kernelParams = [
''systemd.machine_id=${var.machineId.value}''
''systemd.machine_id=${var.value}''
];
environment.etc."machine-id" = {
text = var.machineId.value;
text = var.value;
};
})
{

View File

@@ -106,17 +106,6 @@ in
};
};
systemd.tmpfiles.settings."01-matrix" = {
"/run/synapse-registration-shared-secret" = {
C.argument =
config.clan.core.facts.services.matrix-synapse.secret.synapse-registration_shared_secret.path;
z = {
mode = "0400";
user = "matrix-synapse";
};
};
};
clan.postgresql.users.matrix-synapse = { };
clan.postgresql.databases.matrix-synapse.create.options = {
TEMPLATE = "template0";
@@ -127,26 +116,28 @@ in
};
clan.postgresql.databases.matrix-synapse.restore.stopOnRestore = [ "matrix-synapse" ];
clan.core.facts.services =
clan.core.vars.generators =
{
"matrix-synapse" = {
secret."synapse-registration_shared_secret" = { };
generator.path = with pkgs; [
files."synapse-registration_shared_secret" = { };
runtimeInputs = with pkgs; [
coreutils
pwgen
];
generator.script = ''
echo -n "$(pwgen -s 32 1)" > "$secrets"/synapse-registration_shared_secret
migrateFact = "matrix-synapse";
script = ''
echo -n "$(pwgen -s 32 1)" > "$out"/synapse-registration_shared_secret
'';
};
}
// lib.mapAttrs' (
name: user:
lib.nameValuePair "matrix-password-${user.name}" {
secret."matrix-password-${user.name}" = { };
generator.path = with pkgs; [ xkcdpass ];
generator.script = ''
xkcdpass -n 4 -d - > "$secrets"/${lib.escapeShellArg "matrix-password-${user.name}"}
files."matrix-password-${user.name}" = { };
migrateFact = "matrix-password-${user.name}";
runtimeInputs = with pkgs; [ xkcdpass ];
script = ''
xkcdpass -n 4 -d - > "$out"/${lib.escapeShellArg "matrix-password-${user.name}"}
'';
}
) cfg.users;
@@ -163,14 +154,20 @@ in
+ lib.concatMapStringsSep "\n" (user: ''
# only create user if it doesn't exist
/run/current-system/sw/bin/matrix-synapse-register_new_matrix_user --exists-ok --password-file ${
config.clan.core.facts.services."matrix-password-${user.name}".secret."matrix-password-${user.name}".path
config.clan.core.vars.generators."matrix-password-${user.name}".files."matrix-password-${user.name}".path
} --user "${user.name}" ${if user.admin then "--admin" else "--no-admin"}
'') (lib.attrValues cfg.users);
in
{
path = [ pkgs.curl ];
serviceConfig.ExecStartPre = lib.mkBefore [
"+${pkgs.coreutils}/bin/install -o matrix-synapse -g matrix-synapse ${
lib.escapeShellArg
config.clan.core.vars.generators.matrix-synapse.files."synapse-registration_shared_secret".path
} /run/synapse-registration-shared-secret"
];
serviceConfig.ExecStartPost = [
(''+${pkgs.writeShellScript "matrix-synapse-create-users" usersScript}'')
''+${pkgs.writeShellScript "matrix-synapse-create-users" usersScript}''
];
};

View File

@@ -0,0 +1,30 @@
---
description = "End-2-end encrypted IPv6 overlay network"
categories = ["System", "Network"]
features = [ "inventory" ]
---
Mycelium is an IPv6 overlay network written in Rust. Each node that joins the overlay network will receive an overlay network IP in the 400::/7 range.
Features:
- Mycelium, is locality aware, it will look for the shortest path between nodes
- All traffic between the nodes is end-2-end encrypted
- Traffic can be routed over nodes of friends, location aware
- If a physical link goes down Mycelium will automatically reroute your traffic
- The IP address is IPV6 and linked to private key
- A simple reliable messagebus is implemented on top of Mycelium
- Mycelium has multiple ways how to communicate quic, tcp, ... and we are working on holepunching for Quick which means P2P traffic without middlemen for NATted networks e.g. most homes
- Scalability is very important for us, we tried many overlay networks before and got stuck on all of them, we are trying to design a network which scales to a planetary level
- You can run mycelium without TUN and only use it as reliable message bus.
An example configuration might look like this in the inventory:
```nix
mycelium.default = {
roles.peer.machines = [
"berlin"
"munich"
];
};
```
This will add the machines named `berlin` and `munich` to the `mycelium` vpn.

View File

@@ -0,0 +1,45 @@
{
pkgs,
config,
lib,
...
}:
{
options = {
clan.mycelium.openFirewall = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Open the firewall for mycelium";
};
clan.mycelium.addHostedPublicNodes = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Add hosted Public nodes";
};
};
config.services.mycelium = {
enable = true;
addHostedPublicNodes = lib.mkDefault config.clan.mycelium.addHostedPublicNodes;
openFirewall = lib.mkDefault config.clan.mycelium.openFirewall;
keyFile = config.clan.core.vars.generators.mycelium.files.key.path;
};
config.clan.core.vars.generators.mycelium = {
files."key" = { };
files."ip".secret = false;
files."pubkey".secret = false;
runtimeInputs = [
pkgs.mycelium
pkgs.coreutils
pkgs.jq
];
script = ''
timeout 5 mycelium --key-file "$out"/key || :
mycelium inspect --key-file "$out"/key --json | jq -r .publicKey > "$out"/pubkey
mycelium inspect --key-file "$out"/key --json | jq -r .address > "$out"/ip
'';
};
}

View File

@@ -1,5 +1,7 @@
---
description = "Automatically generates and configures a password for the root user."
categories = ["System"]
features = [ "inventory" ]
---
After the system was installed/deployed the following command can be used to display the root-password:

View File

@@ -1,29 +1,6 @@
# Dont import this file
# It is only here for backwards compatibility.
# Dont author new modules with this file.
{
pkgs,
config,
lib,
...
}:
{
users.mutableUsers = false;
users.users.root.hashedPasswordFile =
config.clan.core.facts.services.root-password.secret.password-hash.path;
sops.secrets = lib.mkIf (config.clan.core.facts.secretStore == "sops") {
"${config.clan.core.settings.machine.name}-password-hash".neededForUsers = true;
};
clan.core.facts.services.root-password = {
secret.password = { };
secret.password-hash = { };
generator.path = with pkgs; [
coreutils
xkcdpass
mkpasswd
];
generator.script = ''
xkcdpass --numwords 3 --delimiter - --count 1 | tr -d "\n" > $secrets/password
cat $secrets/password | mkpasswd -s -m sha-512 | tr -d "\n" > $secrets/password-hash
'';
};
imports = [ ./roles/default.nix ];
}

View File

@@ -0,0 +1,38 @@
{
pkgs,
config,
...
}:
{
users.mutableUsers = false;
users.users.root.hashedPasswordFile =
config.clan.core.vars.generators.root-password.files.password-hash.path;
clan.core.vars.generators.root-password = {
files.password-hash = {
neededFor = "users";
};
files.password = {
deploy = false;
};
migrateFact = "root-password";
runtimeInputs = [
pkgs.coreutils
pkgs.mkpasswd
pkgs.xkcdpass
];
prompts.password.type = "hidden";
prompts.password.persist = true;
prompts.password.description = "You can autogenerate a password, if you leave this prompt blank.";
script = ''
prompt_value=$(cat $prompts/password)
if [[ -n ''${prompt_value-} ]]; then
echo $prompt_value | tr -d "\n" > $out/password
else
xkcdpass --numwords 3 --delimiter - --count 1 | tr -d "\n" > $out/password
fi
mkpasswd -s -m sha-512 < $out/password | tr -d "\n" > $out/password-hash
'';
};
}

View File

@@ -37,6 +37,7 @@ in
type = "rsa";
};
};
clan.core.vars.generators.openssh = {
files."ssh.id_ed25519" = { };
files."ssh.id_ed25519.pub".secret = false;
@@ -50,6 +51,14 @@ in
'';
};
programs.ssh.knownHosts.clan-sshd-self-ed25519 = {
hostNames = [
"localhost"
config.networking.hostName
] ++ (lib.optional (config.networking.domain != null) config.networking.fqdn);
publicKey = config.clan.core.vars.generators.openssh.files."ssh.id_ed25519.pub".value;
};
clan.core.vars.generators.openssh-rsa = lib.mkIf config.clan.sshd.hostKeys.rsa.enable {
files."ssh.id_rsa" = { };
files."ssh.id_rsa.pub".secret = false;

View File

@@ -3,7 +3,7 @@ let
var = config.clan.core.vars.generators.state-version.files.version or { };
in
{
system.stateVersion = lib.mkDefault var.value;
system.stateVersion = lib.mkDefault (lib.removeSuffix "\n" var.value);
clan.core.vars.generators.state-version = {
files.version = {

View File

@@ -7,7 +7,8 @@
let
dir = config.clan.core.settings.directory;
machineDir = dir + "/machines/";
syncthingPublicKeyPath = machines: machineDir + machines + "/facts/syncthing.pub";
machineVarDir = dir + "/vars/per-machine/";
syncthingPublicKeyPath = machines: machineVarDir + machines + "/syncthing/id/value";
machinesFileSet = builtins.readDir machineDir;
machines = lib.mapAttrsToList (name: _: name) machinesFileSet;
syncthingPublicKeysUnchecked = builtins.map (
@@ -83,24 +84,26 @@ in
configDir = "/var/lib/syncthing";
group = "syncthing";
key = lib.mkDefault config.clan.core.facts.services.syncthing.secret."syncthing.key".path or null;
cert = lib.mkDefault config.clan.core.facts.services.syncthing.secret."syncthing.cert".path or null;
key = lib.mkDefault config.clan.core.vars.generators.syncthing.files.key.path or null;
cert = lib.mkDefault config.clan.core.vars.generators.syncthing.files.cert.path or null;
};
clan.core.facts.services.syncthing = {
secret."syncthing.key" = { };
secret."syncthing.cert" = { };
public."syncthing.pub" = { };
generator.path = [
clan.core.vars.generators.syncthing = {
files.key = { };
files.cert = { };
files.api = { };
files.id.secret = false;
runtimeInputs = [
pkgs.coreutils
pkgs.gnugrep
pkgs.syncthing
];
generator.script = ''
syncthing generate --config "$secrets"
mv "$secrets"/key.pem "$secrets"/syncthing.key
mv "$secrets"/cert.pem "$secrets"/syncthing.cert
cat "$secrets"/config.xml | grep -oP '(?<=<device id=")[^"]+' | uniq > "$facts"/syncthing.pub
script = ''
syncthing generate --config $out
mv $out/key.pem $out/key
mv $out/cert.pem $out/cert
cat $out/config.xml | grep -oP '(?<=<device id=")[^"]+' | uniq > $out/id
cat $out/config.xml | grep -oP '<apikey>\K[^<]+' | uniq > $out/api
'';
};
}

View File

@@ -1,5 +1,7 @@
---
description = "Automatically generates and configures a password for the specified user account."
categories = ["System"]
features = ["inventory"]
---
If setting the option prompt to true, the user will be prompted to type in their desired password.

View File

@@ -1,58 +1,6 @@
# Dont import this file
# It is only here for backwards compatibility.
# Dont author new modules with this file.
{
pkgs,
config,
lib,
...
}:
let
cfg = config.clan.user-password;
in
{
options.clan.user-password = {
user = lib.mkOption {
type = lib.types.str;
example = "alice";
description = "The user the password should be generated for.";
};
prompt = lib.mkOption {
type = lib.types.bool;
default = true;
example = false;
description = "Whether the user should be prompted.";
};
};
config = {
users.mutableUsers = false;
users.users.${cfg.user} = {
hashedPasswordFile = config.clan.core.facts.services.user-password.secret.user-password-hash.path;
isNormalUser = lib.mkDefault true;
};
sops.secrets = lib.mkIf (config.clan.core.facts.secretStore == "sops") {
"${config.clan.core.settings.machine.name}-user-password-hash".neededForUsers = true;
};
clan.core.facts.services.user-password = {
secret.user-password = { };
secret.user-password-hash = { };
generator.prompt = (
lib.mkIf config.clan.user-password.prompt "Set the password for your user '${config.clan.user-password.user}'.
You can autogenerate a password, if you leave this prompt blank."
);
generator.path = with pkgs; [
coreutils
xkcdpass
mkpasswd
];
generator.script = ''
if [[ -n ''${prompt_value-} ]]; then
echo $prompt_value | tr -d "\n" > $secrets/user-password
else
xkcdpass --numwords 3 --delimiter - --count 1 | tr -d "\n" > $secrets/user-password
fi
cat $secrets/user-password | mkpasswd -s -m sha-512 | tr -d "\n" > $secrets/user-password-hash
'';
};
};
imports = [ ./roles/default.nix ];
}

View File

@@ -0,0 +1,58 @@
{
pkgs,
config,
lib,
...
}:
let
cfg = config.clan.user-password;
in
{
options.clan.user-password = {
user = lib.mkOption {
type = lib.types.str;
example = "alice";
description = "The user the password should be generated for.";
};
prompt = lib.mkOption {
type = lib.types.bool;
default = true;
example = false;
description = "Whether the user should be prompted.";
};
};
config = {
users.mutableUsers = false;
users.users.${cfg.user} = {
hashedPasswordFile = config.clan.core.facts.services.user-password.secret.user-password-hash.path;
isNormalUser = lib.mkDefault true;
};
sops.secrets = lib.mkIf (config.clan.core.facts.secretStore == "sops") {
"${config.clan.core.settings.machine.name}-user-password-hash".neededForUsers = true;
};
clan.core.facts.services.user-password = {
secret.user-password = { };
secret.user-password-hash = { };
generator.prompt = (
lib.mkIf config.clan.user-password.prompt "Set the password for your user '${config.clan.user-password.user}'.
You can autogenerate a password, if you leave this prompt blank."
);
generator.path = with pkgs; [
coreutils
xkcdpass
mkpasswd
];
generator.script = ''
if [[ -n ''${prompt_value-} ]]; then
echo $prompt_value | tr -d "\n" > $secrets/user-password
else
xkcdpass --numwords 3 --delimiter - --count 1 | tr -d "\n" > $secrets/user-password
fi
cat $secrets/user-password | mkpasswd -s -m sha-512 | tr -d "\n" > $secrets/user-password-hash
'';
};
};
}

View File

@@ -14,9 +14,9 @@ let
name = "iwd.${name}";
value = {
prompts.ssid.type = "line";
prompts.ssid.createFile = true;
prompts.ssid.persist = true;
prompts.password.type = "hidden";
prompts.password.createFile = true;
prompts.password.persist = true;
share = true;
};
};

View File

@@ -1,5 +1,5 @@
---
description = "Configures [Zerotier VPN](https://zerotier.com) secure and efficient networking within a Clan.."
description = "Configures [Zerotier VPN](https://zerotier.com) secure and efficient networking within a Clan."
features = [ "inventory" ]
categories = [ "Network", "System" ]

547
decisions/01-ClanModules.md Normal file
View File

@@ -0,0 +1,547 @@
# Clan service modules
Status: Accepted
## Context
To define a service in Clan, you need to define two things:
- `clanModule` - defined by module authors
- `inventory` - defined by users
The `clanModule` is currently a plain NixOS module. It is conditionally imported into each machine depending on the `service` and `role`.
A `role` is a function of a machine within a service. For example in the `backup` service there are `client` and `server` roles.
The `inventory` contains the settings for the user/consumer of the module. It describes what `services` run on each machine and with which `roles`.
Additionally any `service` can be instantiated multiple times.
This ADR proposes that we change how to write a `clanModule`. The `inventory` should get a new attribute called `instances` that allow for configuration of these modules.
### Status Quo
In this example the user configures 2 instances of the `networking` service:
The *user* defines
```nix
{
inventory.services = {
# anything inside an instance is instance specific
networking."instance1" = {
roles.client.tags = [ "all" ];
machines.foo.config = { ... /* machine specific settings */ };
# this will not apply to `clients` outside of `instance1`
roles.client.config = { ... /* client specific settings */ };
};
networking."instance2" = {
roles.server.tags = [ "all" ];
config = { ... /* applies to every machine that runs this instance */ };
};
};
}
```
The *module author* defines:
```nix
# networking/roles/client.nix
{ config, ... }:
let
instances = config.clan.inventory.services.networking or { };
serviceConfig = config.clan.networking;
in {
## Set some nixos options
}
```
### Problems
Problems with the current way of writing clanModules:
1. No way to retrieve the config of a single service instance, together with its name.
2. Directly exporting a single, anonymous nixosModule without any intermediary attribute layers doesn't leave room for exporting other inventory resources such as potentially `vars` or `homeManagerConfig`.
3. Can't access multiple config instances individually.
Example:
```nix
inventory = {
services = {
network.c-base = {
instanceConfig.ips = {
mors = "172.139.0.2";
};
};
network.gg23 = {
instanceConfig.ips = {
mors = "10.23.0.2";
};
};
};
};
```
This doesn't work because all instance configs are applied to the same namespace. So this results in a conflict currently.
Resolving this problem means that new inventory modules cannot be plain nixos modules anymore. If they are configured via `instances` / `instanceConfig` they cannot be configured without using the inventory. (There might be ways to inject instanceConfig but that requires knowledge of inventory internals)
4. Writing modules for multiple instances is cumbersome. Currently the clanModule author has to write one or multiple `fold` operations for potentially every nixos option to define how multiple service instances merge into every single one option. The new idea behind this adr is to pull the common fold function into the outer context provide it as a common helper. (See the example below. `perInstance` analog to the well known `perSystem` of flake-parts)
5. Each role has a different interface. We need to render that interface into json-schema which includes creating an unnecessary test machine currently. Defining the interface at a higher level (outside of any machine context) allows faster evaluation and an isolation by design from any machine.
This allows rendering the UI (options tree) of a service by just knowing the service and the corresponding roles without creating a dummy machine.
6. The interface of defining config is wrong. It is possible to define config that applies to multiple machine at once. It is possible to define config that applies to
a machine as a hole. But this is wrong behavior because the options exist at the role level. So config must also always exist at the role level.
Currently we merge options and config together but that may produce conflicts. Those module system conflicts are very hard to foresee since they depend on what roles exist at runtime.
## Proposed Change
We will create a new module class which is defined by `_class = "clan.service"` ([documented here](https://nixos.org/manual/nixpkgs/stable/#module-system-lib-evalModules-param-class)).
Existing clan modules will still work by continuing to be plain NixOS modules. All new modules can set `_class = "clan.service";` to use the proposed features.
In short the change introduces a new module class that makes the currently necessary folding of `clan.service`s `instances` and `roles` a common operation. The module author can define the inner function of the fold operations which is called a `clan.service` module.
There are the following attributes of such a module:
### `roles.<roleName>.interface`
Each role can have a different interface for how to be configured.
I.e.: A `client` role might have different options than a `server` role.
This attribute should be used to define `options`. (Not `config` !)
The end-user defines the corresponding `config`.
This submodule will be evaluated for each `instance role` combination and passed as argument into `perInstance`.
This submodules `options` will be evaluated to build the UI for that module dynamically.
### **Result attributes**
Some common result attributes are produced by modules of this proposal, those will be referenced later in this document but are commonly defined as:
- `nixosModule` A single nixos module. (`{config, ...}:{ environment.systemPackages = []; }`)
- `services.<serviceName>` An attribute set of `_class = clan.service`. Which contain the same thing as this whole ADR proposes.
- `vars` To be defined. Reserved for now.
### `roles.<roleName>.perInstance`
This acts like a function that maps over all `service instances` of a given `role`.
It produces the previously defined **result attributes**.
I.e. This allows to produce multiple `nixosModules` one for every instance of the service.
Hence making multiple `service instances` convenient by leveraging the module-system merge behavior.
### `perMachine`
This acts like a function that maps over all `machines` of a given `service`.
It produces the previously defined **result attributes**.
I.e. this allows to produce exactly one `nixosModule` per `service`.
Making it easy to set nixos-options only once if they have a one-to-one relation to a service being enabled.
Note: `lib.mkIf` can be used on i.e. `roleName` to make the scope more specific.
### `services.<serviceName>`
This allows to define nested services.
i.e the *service* `backup` might define a nested *service* `ssh` which sets up an ssh connection.
This can be defined in `perMachine` and `perInstance`
- For Every `instance` a given `service` may add multiple nested `services`.
- A given `service` may add a static set of nested `services`; Even if there are multiple instances of the same given service.
Q: Why is this not a top-level attribute?
A: Because nested service definitions may also depend on a `role` which must be resolved depending on `machine` and `instance`. The top-level module doesn't know anything about machines. Keeping the service layer machine agnostic allows us to build the UI for a module without adding any machines. (One of the problems with the current system)
```
zerotier/default.nix
```
```nix
# Some example module
{
_class = "clan.service";
# Analog to flake-parts 'perSystem' only that it takes instance
# The exact arguments will be specified and documented along with the actual implementation.
roles.client.perInstance = {
# attrs : settings of that instance
settings,
# string : name of the instance
instanceName,
# { name :: string , roles :: listOf string; }
machine,
# { {roleName} :: { machines :: listOf string; } }
roles,
...
}:
{
# Return a nixos module for every instance.
# The module author must be aware that this may return multiple modules (one for every instance) which are merged natively
nixosModule = {
config.debug."${instanceName}-client" = instanceConfig;
};
};
# Function that is called once for every machine with the role "client"
# Receives at least the following parameters:
#
# machine :: { name :: String, roles :: listOf string; }
# Name of the machine
#
# instances :: { instanceName :: { roleName :: { machines :: [ string ]; }}}
# Resolved roles
# Same type as currently in `clan.inventory.services.<ServiceName>.<InstanceName>.roles`
#
# The exact arguments will be specified and documented along with the actual implementation.
perMachine = {machine, instances, ... }: {
nixosModule =
{ lib, ... }:
{
# Some shared code should be put into a shared file
# Which is then imported into all/some roles
imports = [
../shared.nix
] ++
(lib.optional (builtins.elem "client" machine.roles)
{
options.debug = lib.mkOption {
type = lib.types.attrsOf lib.types.raw;
};
});
};
};
}
```
## Inventory.instances
This document also proposes to add a new attribute to the inventory that allow for exclusive configuration of the new modules.
This allows to better separate the new and the old way of writing and configuring modules. Keeping the new implementation more focussed and keeping existing technical debt out from the beginning.
The following thoughts went into this:
- Getting rid of `<serviceName>`: Using only the attribute name (plain string) is not sufficient for defining the source of the service module. Encoding meta information into it would also require some extensible format specification and parser.
- removing instanceConfig and machineConfig: There is no such config. Service configuration must always be role specific, because the options are defined on the role.
- renaming `config` to `settings` or similar. Since `config` is a module system internal name.
- Tags and machines should be an attribute set to allow setting `settings` on that level instead.
```nix
{
inventory.instances = {
"instance1" = {
# Allows to define where the module should be imported from.
module = {
input = "clan-core";
name = "borgbackup";
};
# settings that apply to all client machines
roles.client.settings = {};
# settings that apply to the client service of machine with name <machineName>
# There might be a server service that takes different settings on the same machine!
roles.client.machines.<machineName>.settings = {};
# settings that apply to all client-instances with tag <tagName>
roles.client.tags.<tagName>.settings = {};
};
"instance2" = {
# ...
};
};
}
```
## Iteration note
We want to implement the system as described. Once we have sufficient data on real world use-cases and modules we might revisit this document along with the updated implementation.
## Real world example
The following module demonstrates the idea in the example of *borgbackup*.
```nix
{
_class = "clan.service";
# Define the 'options' of 'settings' see argument of perInstance
roles.server.interface =
{ lib, ... }:
{
options = lib.mkOption {
type = lib.types.str;
default = "/var/lib/borgbackup";
description = ''
The directory where the borgbackup repositories are stored.
'';
};
};
roles.server.perInstance =
{
instanceName,
settings,
roles,
...
}:
{
nixosModule =
{ config, lib, ... }:
let
dir = config.clan.core.settings.directory;
machineDir = dir + "/vars/per-machine/";
allClients = roles.client.machines;
in
{
# services.borgbackup is a native nixos option
config.services.borgbackup.repos =
let
borgbackupIpMachinePath = machine: machineDir + machine + "/borgbackup/borgbackup.ssh.pub/value";
machinesMaybeKey = builtins.map (
machine:
let
fullPath = borgbackupIpMachinePath machine;
in
if builtins.pathExists fullPath then
machine
else
lib.warn ''
Machine ${machine} does not have a borgbackup key at ${fullPath},
run `clan var generate ${machine}` to generate it.
'' null
) allClients;
machinesWithKey = lib.filter (x: x != null) machinesMaybeKey;
hosts = builtins.map (machine: {
name = instanceName + machine;
value = {
path = "${settings.directory}/${machine}";
authorizedKeys = [ (builtins.readFile (borgbackupIpMachinePath machine)) ];
};
}) machinesWithKey;
in
if (builtins.listToAttrs hosts) != [ ] then builtins.listToAttrs hosts else { };
};
};
roles.client.interface =
{ lib, ... }:
{
# There might be a better interface now. This is just how clan borgbackup was configured in the 'old' way
options.destinations = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule (
{ name, ... }:
{
options = {
name = lib.mkOption {
type = lib.types.strMatching "^[a-zA-Z0-9._-]+$";
default = name;
description = "the name of the backup job";
};
repo = lib.mkOption {
type = lib.types.str;
description = "the borgbackup repository to backup to";
};
rsh = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
defaultText = "ssh -i \${config.clan.core.vars.generators.borgbackup.files.\"borgbackup.ssh\".path} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null";
description = "the rsh to use for the backup";
};
};
}
)
);
default = { };
description = ''
destinations where the machine should be backed up to
'';
};
options.exclude = lib.mkOption {
type = lib.types.listOf lib.types.str;
example = [ "*.pyc" ];
default = [ ];
description = ''
Directories/Files to exclude from the backup.
Use * as a wildcard.
'';
};
};
roles.client.perInstance =
{
instanceName,
roles,
machine,
settings,
...
}:
{
nixosModule =
{
config,
lib,
pkgs,
...
}:
let
allServers = roles.server.machines;
# machineName = config.clan.core.settings.machine.name;
# cfg = config.clan.borgbackup;
preBackupScript = ''
declare -A preCommandErrors
${lib.concatMapStringsSep "\n" (
state:
lib.optionalString (state.preBackupCommand != null) ''
echo "Running pre-backup command for ${state.name}"
if ! /run/current-system/sw/bin/${state.preBackupCommand}; then
preCommandErrors["${state.name}"]=1
fi
''
) (lib.attrValues config.clan.core.state)}
if [[ ''${#preCommandErrors[@]} -gt 0 ]]; then
echo "pre-backup commands failed for the following services:"
for state in "''${!preCommandErrors[@]}"; do
echo " $state"
done
exit 1
fi
'';
destinations =
let
destList = builtins.map (serverName: {
name = "${instanceName}-${serverName}";
value = {
repo = "borg@${serverName}:/var/lib/borgbackup/${machine.name}";
rsh = "ssh -i ${
config.clan.core.vars.generators."borgbackup-${instanceName}".files."borgbackup.ssh".path
} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentitiesOnly=Yes";
} // settings.destinations.${serverName};
}) allServers;
in
(builtins.listToAttrs destList);
in
{
config = {
# Derived from the destinations
systemd.services = lib.mapAttrs' (
_: dest:
lib.nameValuePair "borgbackup-job-${instanceName}-${dest.name}" {
# since borgbackup mounts the system read-only, we need to run in a ExecStartPre script, so we can generate additional files.
serviceConfig.ExecStartPre = [
''+${pkgs.writeShellScript "borgbackup-job-${dest.name}-pre-backup-commands" preBackupScript}''
];
}
) destinations;
services.borgbackup.jobs = lib.mapAttrs (_destinationName: dest: {
paths = lib.unique (
lib.flatten (map (state: state.folders) (lib.attrValues config.clan.core.state))
);
exclude = settings.exclude;
repo = dest.repo;
environment.BORG_RSH = dest.rsh;
compression = "auto,zstd";
startAt = "*-*-* 01:00:00";
persistentTimer = true;
encryption = {
mode = "repokey";
passCommand = "cat ${config.clan.core.vars.generators."borgbackup-${instanceName}".files."borgbackup.repokey".path}";
};
prune.keep = {
within = "1d"; # Keep all archives from the last day
daily = 7;
weekly = 4;
monthly = 0;
};
}) destinations;
environment.systemPackages = [
(pkgs.writeShellApplication {
name = "borgbackup-create";
runtimeInputs = [ config.systemd.package ];
text = ''
${lib.concatMapStringsSep "\n" (dest: ''
systemctl start borgbackup-job-${dest.name}
'') (lib.attrValues destinations)}
'';
})
(pkgs.writeShellApplication {
name = "borgbackup-list";
runtimeInputs = [ pkgs.jq ];
text = ''
(${
lib.concatMapStringsSep "\n" (
dest:
# we need yes here to skip the changed url verification
''echo y | /run/current-system/sw/bin/borg-job-${dest.name} list --json | jq '[.archives[] | {"name": ("${dest.name}::${dest.repo}::" + .name)}]' ''
) (lib.attrValues destinations)
}) | jq -s 'add // []'
'';
})
(pkgs.writeShellApplication {
name = "borgbackup-restore";
runtimeInputs = [ pkgs.gawk ];
text = ''
cd /
IFS=':' read -ra FOLDER <<< "''${FOLDERS-}"
job_name=$(echo "$NAME" | awk -F'::' '{print $1}')
backup_name=''${NAME#"$job_name"::}
if [[ ! -x /run/current-system/sw/bin/borg-job-"$job_name" ]]; then
echo "borg-job-$job_name not found: Backup name is invalid" >&2
exit 1
fi
echo y | /run/current-system/sw/bin/borg-job-"$job_name" extract "$backup_name" "''${FOLDER[@]}"
'';
})
];
# every borgbackup instance adds its own vars
clan.core.vars.generators."borgbackup-${instanceName}" = {
files."borgbackup.ssh.pub".secret = false;
files."borgbackup.ssh" = { };
files."borgbackup.repokey" = { };
migrateFact = "borgbackup";
runtimeInputs = [
pkgs.coreutils
pkgs.openssh
pkgs.xkcdpass
];
script = ''
ssh-keygen -t ed25519 -N "" -f $out/borgbackup.ssh
xkcdpass -n 4 -d - > $out/borgbackup.repokey
'';
};
};
};
};
perMachine = {
nixosModule =
{ ... }:
{
clan.core.backups.providers.borgbackup = {
list = "borgbackup-list";
create = "borgbackup-create";
restore = "borgbackup-restore";
};
};
};
}
```
## Prior-art
- https://github.com/NixOS/nixops
- https://github.com/infinisil/nixus

116
decisions/02-clan-api.md Normal file
View File

@@ -0,0 +1,116 @@
# Clan as library
## Status
Accepted
## Context
In the long term we envision the clan application will consist of the following user facing tools in the long term.
- `CLI`
- `TUI`
- `Desktop Application`
- `REST-API`
- `Mobile Application`
We might not be sure whether all of those will exist but the architecture should be generic such that those are possible without major changes of the underlying system.
## Decision
This leads to the conclusion that we should do `library` centric development.
With the current `clan` python code beeing a library that can be imported to create various tools ontop of it.
All **CLI** or **UI** related parts should be moved out of the main library.
*Note: The next person who wants implement any new frontend should do this first. Currently it looks like the TUI is the next one.*
Imagine roughly the following architecture:
```mermaid
graph TD
%% Define styles
classDef frontend fill:#f9f,stroke:#333,stroke-width:2px;
classDef backend fill:#bbf,stroke:#333,stroke-width:2px;
classDef storage fill:#ff9,stroke:#333,stroke-width:2px;
classDef testing fill:#cfc,stroke:#333,stroke-width:2px;
%% Define nodes
user(["User"]) -->|Interacts with| Frontends
subgraph "Frontends"
CLI["CLI"]:::frontend
APP["Desktop App"]:::frontend
TUI["TUI"]:::frontend
REST["REST API"]:::frontend
end
subgraph "Python"
API["Library <br>for interacting with clan"]:::backend
BusinessLogic["Business Logic<br>Implements actions like 'machine create'"]:::backend
STORAGE[("Persistence")]:::storage
NIX["Nix Eval & Build"]:::backend
end
subgraph "CI/CD & Tests"
TEST["Feature Testing"]:::testing
end
%% Define connections
CLI --> API
APP --> API
TUI --> API
REST --> API
TEST --> API
API --> BusinessLogic
BusinessLogic --> STORAGE
BusinessLogic --> NIX
```
With this very simple design it is ensured that all the basic features remain stable across all frontends.
In the end it is straight forward to create python library function calls in a testing framework to ensure that kind of stability.
Integration tests and smaller unit-tests should both be utilized to ensure the stability of the library.
Note: Library function don't have to be json-serializable in general.
Persistence includes but is not limited to: creating git commits, writing to inventory.json, reading and writing vars and to/from disk in general.
## Benefits / Drawbacks
- (+) Less tight coupling of frontend- / backend-teams
- (+) Consistency and inherent behavior
- (+) Performance & Scalability
- (+) Different frontends for different user groups
- (+) Documentation per library function makes it convenient to interact with the clan resources.
- (+) Testing the library ensures stability of the underlyings for all layers above.
- (-) Complexity overhead
- (-) library needs to be designed / documented
- (+) library can be well documented since it is a finite set of functions.
- (-) Error handling might be harder.
- (+) Common error reporting
- (-) different frontends need different features. The library must include them all.
- (+) All those core features must be implemented anyways.
- (+) VPN Benchmarking uses the existing library's already and works relatively well.
## Implementation considerations
Not all required details that need to change over time are possible to be pointed out ahead of time.
The goal of this document is to create a common understanding for how we like our project to be structured.
Any future commits should contribute to this goal.
Some ideas what might be needed to change:
- Having separate locations or packages for the library and the CLI.
- Rename the `clan_cli` package to `clan` and move the `cli` frontend into a subfolder or a separate package.
- Python Argparse or other cli related code should not exist in the `clan` python library.
- `__init__.py` should be very minimal. Only init the business logic models and resources. Note that all `__init__.py` files all the way up in the module tree are always executed as part of the python module import logic and thus should be as small as possible.
i.e. `from clan_cli.vars.generators import ...` executes both `clan_cli/__init__.py` and `clan_cli/vars/__init__.py` if any of those exist.
- `api` folder doesn't make sense since the python library `clan` is the api.
- Logic needed for the webui that performs json serialization and deserialization will be some `json-adapter` folder or package.
- Code for serializing dataclasses and typed dictionaries is needed for the persistence layer. (i.e. for read-write of inventory.json)
- The inventory-json is a backend resource, that is internal. Its logic includes merging, unmerging and partial updates with considering nix values and their priorities. Nobody should try to read or write to it directly.
Instead there will be library methods i.e. to add a `service` or to update/read/delete some information from it.
- Library functions should be carefully designed with suitable conventions for writing good api's in mind. (i.e: https://swagger.io/resources/articles/best-practices-in-api-design/)

1
decisions/README.md Normal file
View File

@@ -0,0 +1 @@
see [architecture-decision-record](https://github.com/joelparkerhenderson/architecture-decision-record)

24
decisions/_template.md Normal file
View File

@@ -0,0 +1,24 @@
# Decision record template by Michael Nygard
This is the template in [Documenting architecture decisions - Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
You can use [adr-tools](https://github.com/npryce/adr-tools) for managing the ADR files.
In each ADR file, write these sections:
# Title
## Status
What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.?
## Context
What is the issue that we're seeing that is motivating this decision or change?
## Decision
What is the change that we're proposing and/or doing?
## Consequences
What becomes easier or more difficult to do because of this change?

4
docs/.gitignore vendored
View File

@@ -1,3 +1,3 @@
/site/reference
/site/static/Roboto-Regular.ttf
/site/static/FiraCode-VF.ttf
/site/static
!/site/static/extra.css

View File

@@ -1,4 +1,5 @@
# Contributing
# Contributing to Clan
**Continuous Integration (CI)**: Each pull request gets automatically tested by gitea. If any errors are detected, it will block pull requests until they're resolved.
@@ -20,14 +21,14 @@ Let's get your development environment up and running:
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
```
2. **Install direnv**:
1. **Install direnv**:
- To automatically setup a devshell on entering the directory
```bash
nix profile install nixpkgs#nix-direnv-flakes
nix profile install nixpkgs#nix-direnv-flakes nixpkgs#direnv
```
3. **Add direnv to your shell**:
1. **Add direnv to your shell**:
- Direnv needs to [hook into your shell](https://direnv.net/docs/hook.html) to work.
You can do this by executing following command. The example below will setup direnv for `zsh` and `bash`
@@ -36,7 +37,10 @@ Let's get your development environment up and running:
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc && echo 'eval "$(direnv hook bash)"' >> ~/.bashrc && eval "$SHELL"
```
4. **Create a Gitea Account**:
1. **Allow the devshell**
- Go to `clan-core/pkgs/clan-cli` and do a `direnv allow` to setup the necessary development environment to execute the `clan` command
1. **Create a Gitea Account**:
- Register an account on https://git.clan.lol
- Fork the [clan-core](https://git.clan.lol/clan/clan-core) repository
- Clone the repository and navigate to it
@@ -44,30 +48,7 @@ Let's get your development environment up and running:
```bash
git remote add upstream gitea@git.clan.lol:clan/clan-core.git
```
5. **Create an access token**:
- Log in to Gitea.
- Go to your account settings.
- Navigate to the Applications section.
- Click Generate New Token.
- Name your token and select all available scopes.
- Generate the token and copy it for later use.
- Your access token is now ready to use with all permissions.
5. **Register Your Gitea Account Locally**:
- Execute the following command to add your Gitea account locally:
```bash
tea login add
```
- Fill out the prompt as follows:
- URL of Gitea instance: `https://git.clan.lol`
- Name of new Login [git.clan.lol]:
- Do you have an access token? Yes
- Token: <yourtoken>
- Set Optional settings: No
6. **Allow .envrc**:
1. **Allow .envrc**:
- When you enter the directory, you'll receive an error message like this:
```bash
@@ -75,7 +56,7 @@ Let's get your development environment up and running:
```
- Execute `direnv allow` to automatically execute the shell script `.envrc` when entering the directory.
7. **(Optional) Install Git Hooks**:
1. **(Optional) Install Git Hooks**:
- To syntax check your code you can run:
```bash
nix fmt
@@ -85,116 +66,44 @@ Let's get your development environment up and running:
./scripts/pre-commit
```
8. **Open a Pull Request**:
- To automatically open up a pull request you can use our tool called:
```
merge-after-ci --reviewers Mic92 Lassulus Qubasa
```
## Related Projects
# Debugging
- **Data Mesher**: [data-mesher](https://git.clan.lol/clan/data-mesher)
- **Nixos Facter**: [nixos-facter](https://github.com/nix-community/nixos-facter)
- **Nixos Anywhere**: [nixos-anywhere](https://github.com/nix-community/nixos-anywhere)
- **Disko**: [disko](https://github.com/nix-community/disko)
Here are some methods for debugging and testing the clan-cli:
## Fixing Bugs or Adding Features in Clan-CLI
## See all possible packages and tests
If you have a bug fix or feature that involves a related project, clone the relevant repository and replace its invocation in your local setup.
To quickly show all possible packages and tests execute:
For instance, if you need to update `nixos-anywhere` in clan-cli, find its usage:
```bash
nix flake show --system no-eval
```python
run(
nix_shell(
["nixpkgs#nixos-anywhere"],
cmd,
),
RunOpts(log=Log.BOTH, prefix=machine.name, needs_user_terminal=True),
)
```
Under `checks` you will find all tests that are executed in our CI. Under `packages` you find all our projects.
You can replace `"nixpkgs#nixos-anywhere"` with your local path:
```python
run(
nix_shell(
["<path_to_local_src>#nixos-anywhere"],
cmd,
),
RunOpts(log=Log.BOTH, prefix=machine.name, needs_user_terminal=True),
)
```
git+file:///home/lhebendanz/Projects/clan-core
├───apps
│ └───x86_64-linux
│ ├───install-vm: app
│ └───install-vm-nogui: app
├───checks
│ └───x86_64-linux
│ ├───borgbackup omitted (use '--all-systems' to show)
│ ├───check-for-breakpoints omitted (use '--all-systems' to show)
│ ├───clan-dep-age omitted (use '--all-systems' to show)
│ ├───clan-dep-bash omitted (use '--all-systems' to show)
│ ├───clan-dep-e2fsprogs omitted (use '--all-systems' to show)
│ ├───clan-dep-fakeroot omitted (use '--all-systems' to show)
│ ├───clan-dep-git omitted (use '--all-systems' to show)
│ ├───clan-dep-nix omitted (use '--all-systems' to show)
│ ├───clan-dep-openssh omitted (use '--all-systems' to show)
│ ├───"clan-dep-python3.11-mypy" omitted (use '--all-systems' to show)
├───packages
│ └───x86_64-linux
│ ├───clan-cli omitted (use '--all-systems' to show)
│ ├───clan-cli-docs omitted (use '--all-systems' to show)
│ ├───clan-ts-api omitted (use '--all-systems' to show)
│ ├───clan-app omitted (use '--all-systems' to show)
│ ├───default omitted (use '--all-systems' to show)
│ ├───deploy-docs omitted (use '--all-systems' to show)
│ ├───docs omitted (use '--all-systems' to show)
│ ├───editor omitted (use '--all-systems' to show)
└───templates
├───default: template: Initialize a new clan flake
└───new-clan: template: Initialize a new clan flake
```
You can execute every test separately by following the tree path `nix build .#checks.x86_64-linux.clan-pytest` for example.
## Test Locally in Devshell with Breakpoints
To test the cli locally in a development environment and set breakpoints for debugging, follow these steps:
1. Run the following command to execute your tests and allow for debugging with breakpoints:
```bash
cd ./pkgs/clan-cli
pytest -n0 -s --maxfail=1 ./tests/test_nameofthetest.py
```
You can place `breakpoint()` in your Python code where you want to trigger a breakpoint for debugging.
## Test Locally in a Nix Sandbox
To run tests in a Nix sandbox, you have two options depending on whether your test functions have been marked as impure or not:
### Running Tests Marked as Impure
If your test functions need to execute `nix build` and have been marked as impure because you can't execute `nix build` inside a Nix sandbox, use the following command:
```bash
nix run .#impure-checks
```
This command will run the impure test functions.
### Running Pure Tests
For test functions that have not been marked as impure and don't require executing `nix build`, you can use the following command:
```bash
nix build .#checks.x86_64-linux.clan-pytest --rebuild
```
This command will run all pure test functions.
### Inspecting the Nix Sandbox
If you need to inspect the Nix sandbox while running tests, follow these steps:
1. Insert an endless sleep into your test code where you want to pause the execution. For example:
```python
import time
time.sleep(3600) # Sleep for one hour
```
2. Use `cntr` and `psgrep` to attach to the Nix sandbox. This allows you to interactively debug your code while it's paused. For example:
```bash
psgrep -a -x your_python_process_name
cntr attach <container id, container name or process id>
```
Or you can also use the [nix breakpoint hook](https://nixos.org/manual/nixpkgs/stable/#breakpointhook)
The <path_to_local_src> doesn't need to be a local path, it can be any valid [flakeref](https://nix.dev/manual/nix/2.26/command-ref/new-cli/nix3-flake.html#flake-references).
And thus can point to test already opened PRs for example.
# Standards

View File

@@ -43,25 +43,31 @@ exclude_docs: |
nav:
- Home: index.md
- Getting Started:
- Getting Started: getting-started/index.md
- Installer: getting-started/installer.md
- Configure: getting-started/configure.md
- Setup Clan: getting-started/index.md
- Create Installer: getting-started/installer.md
- Add Machines: getting-started/configure.md
- Secrets & Facts: getting-started/secrets.md
- Deploy Machine: getting-started/deploy.md
- Continuous Integration: getting-started/check.md
- Guides:
- Overview: manual/index.md
- Disk Encryption: getting-started/disk-encryption.md
- Mesh VPN: getting-started/mesh-vpn.md
- Backup & Restore: getting-started/backups.md
- Adding Machines: manual/adding-machines.md
- Vars Backend: manual/vars-backend.md
- Facts Backend: manual/secrets.md
- Autoincludes: manual/adding-machines.md
- Inventory: manual/inventory.md
- Secrets: manual/secrets.md
- Secure Boot: manual/secure-boot.md
- Flake-parts: manual/flake-parts.md
- Authoring:
- Modules: clanmodules/index.md
- Disk Templates: manual/disk-templates.md
- Contribute: manual/contribute.md
- Contributing:
- Contribute: contributing/contribute.md
- Debugging: contributing/debugging.md
- Testing: contributing/testing.md
- Repo Layout: manual/repo-layout.md
- Migrate existing Flakes: manual/migration-guide.md
# - Concepts:
# - Overview: concepts/index.md
- Reference:
@@ -89,6 +95,7 @@ nav:
- reference/clanModules/matrix-synapse.md
- reference/clanModules/moonlight.md
- reference/clanModules/mumble.md
- reference/clanModules/mycelium.md
- reference/clanModules/nginx.md
- reference/clanModules/packages.md
- reference/clanModules/postgresql.md
@@ -103,6 +110,7 @@ nav:
- reference/clanModules/thelounge.md
- reference/clanModules/trusted-nix-caches.md
- reference/clanModules/user-password.md
- reference/clanModules/auto-upgrade.md
- reference/clanModules/vaultwarden.md
- reference/clanModules/xfce.md
- reference/clanModules/zerotier-static-peers.md
@@ -117,6 +125,7 @@ nav:
- reference/cli/flash.md
- reference/cli/history.md
- reference/cli/machines.md
- reference/cli/select.md
- reference/cli/secrets.md
- reference/cli/show.md
- reference/cli/ssh.md

View File

@@ -69,7 +69,13 @@
];
}
''
export CLAN_CORE_PATH=${self}
export CLAN_CORE_PATH=${
self.filter {
include = [
"clanModules"
];
}
}
export CLAN_CORE_DOCS=${jsonDocs.clanCore}/share/doc/nixos/options.json
# A file that contains the links to all clanModule docs
export CLAN_MODULES_VIA_ROLES=${clanModulesViaRoles}

View File

@@ -103,7 +103,7 @@ def render_option(
read_only = option.get("readOnly")
res = f"""
{"#" * level} {sanitize(name) if short_head is None else sanitize(short_head)} {"{: #"+sanitize_anchor(name)+"}" if level > 1 else ""}
{"#" * level} {sanitize(name) if short_head is None else sanitize(short_head)} {"{: #" + sanitize_anchor(name) + "}" if level > 1 else ""}
"""
@@ -125,7 +125,7 @@ def render_option(
**Default**:
```nix
{option.get("default",{}).get("text") if option.get("default") else "No default set."}
{option.get("default", {}).get("text") if option.get("default") else "No default set."}
```
"""
example = option.get("example", {}).get("text")
@@ -585,7 +585,7 @@ Each attribute is documented below
```nix
buildClan {
directory = self;
self = self;
machines = {
jon = { };
sara = { };

View File

@@ -48,12 +48,12 @@ clanModules/borgbackup
=== "User module"
If the module should be ad-hoc loaded.
It can be made avilable in any project via the [`clan.inventory.modules`](../reference/nix-api/inventory.md#inventory.modules) attribute.
It can be made available in any project via the [`clan.inventory.modules`](../reference/nix-api/inventory.md#inventory.modules) attribute.
```nix title="flake.nix"
# ...
buildClan {
# 1. Add the module to the avilable inventory modules
# 1. Add the module to the available clanModules with inventory support
inventory.modules = {
custom-module = ./modules/my_module;
};
@@ -111,7 +111,7 @@ Adds the roles: `client` and `server`
Sometimes a `ClanModule` should be usable via both clan's `inventory` concept but also natively as a NixOS module.
> In the long term, we want most modules to implement support for the inventory,
> but we are also aware that there are certain low-level modules that always serve as a backend for other higher-level inventory modules.
> but we are also aware that there are certain low-level modules that always serve as a backend for other higher-level `clanModules` with inventory support.
> These modules may not want to implement inventory interfaces as they are always used directly by other modules.
This can be achieved by placing an additional `default.nix` into the root of the ClanModules directory as shown:

View File

@@ -0,0 +1,167 @@
Here are some methods for debugging and testing the clan-cli
## Using a Development Branch
To streamline your development process, I suggest not installing `clan-cli`. Instead, clone the `clan-core` repository and add `clan-core/pkgs/clan-cli/bin` to your PATH to use the checked-out version directly.
!!! Note
After cloning, navigate to `clan-core/pkgs/clan-cli` and execute `direnv allow` to activate the devshell. This will set up a symlink to nixpkgs at a specific location; without it, `clan-cli` won't function correctly.
With this setup, you can easily use [breakpoint()](https://docs.python.org/3/library/pdb.html) to inspect the application's internal state as needed.
This approach is feasible because `clan-cli` only requires a Python interpreter and has no other dependencies.
```nix
pkgs.mkShell {
packages = [
pkgs.python3
];
shellHook = ''
export GIT_ROOT="$(git rev-parse --show-toplevel)"
export PATH=$PATH:~/Projects/clan-core/pkgs/clan-cli/bin
'';
}
```
## The Debug Flag
You can enhance your debugging process with the `--debug` flag in the `clan` command. When you add this flag to any command, it displays all subprocess commands initiated by `clan` in a readable format, along with the source code position that triggered them. This feature makes it easier to understand and trace what's happening under the hood.
```bash
$ clan machines list --debug 1
Debug log activated
nix \
--extra-experimental-features 'nix-command flakes' \
eval \
--show-trace --json \
--print-build-logs '/home/qubasa/Projects/qubasas-clan#clanInternals.machines.x86_64-linux' \
--apply builtins.attrNames \
--json
Caller: ~/Projects/clan-core/pkgs/clan-cli/clan_cli/machines/list.py:96::list_nixos_machines
warning: Git tree '/home/qubasa/Projects/qubasas-clan' is dirty
demo
gchq-local
wintux
```
## VSCode
If you're using VSCode, it has a handy feature that makes paths to source code files clickable in the integrated terminal. Combined with the previously mentioned techniques, this allows you to open a Clan in VSCode, execute a command like `clan machines list --debug`, and receive a printed path to the code that initiates the subprocess. With the `Ctrl` key (or `Cmd` on macOS) and a mouse click, you can jump directly to the corresponding line in the code file and add a `breakpoint()` function to it, to inspect the internal state.
## Finding Print Messages
To identify where a specific print message comes from, you can enable a helpful feature. Simply set the environment variable `export TRACE_PRINT=1`. When you run commands with `--debug` mode, each print message will include information about its source location.
If you need more details, you can expand the stack trace information that appears with each print by setting the environment variable `export TRACE_DEPTH=3`.
## Analyzing Performance
To understand what's causing slow performance, set the environment variable `export CLAN_CLI_PERF=1`. When you complete a clan command, you'll see a summary of various performance metrics, helping you identify what's taking up time.
## See all possible packages and tests
To quickly show all possible packages and tests execute:
```bash
nix flake show
```
Under `checks` you will find all tests that are executed in our CI. Under `packages` you find all our projects.
```
git+file:///home/lhebendanz/Projects/clan-core
├───apps
│ └───x86_64-linux
│ ├───install-vm: app
│ └───install-vm-nogui: app
├───checks
│ └───x86_64-linux
│ ├───borgbackup omitted (use '--all-systems' to show)
│ ├───check-for-breakpoints omitted (use '--all-systems' to show)
│ ├───clan-dep-age omitted (use '--all-systems' to show)
│ ├───clan-dep-bash omitted (use '--all-systems' to show)
│ ├───clan-dep-e2fsprogs omitted (use '--all-systems' to show)
│ ├───clan-dep-fakeroot omitted (use '--all-systems' to show)
│ ├───clan-dep-git omitted (use '--all-systems' to show)
│ ├───clan-dep-nix omitted (use '--all-systems' to show)
│ ├───clan-dep-openssh omitted (use '--all-systems' to show)
│ ├───"clan-dep-python3.11-mypy" omitted (use '--all-systems' to show)
├───packages
│ └───x86_64-linux
│ ├───clan-cli omitted (use '--all-systems' to show)
│ ├───clan-cli-docs omitted (use '--all-systems' to show)
│ ├───clan-ts-api omitted (use '--all-systems' to show)
│ ├───clan-app omitted (use '--all-systems' to show)
│ ├───default omitted (use '--all-systems' to show)
│ ├───deploy-docs omitted (use '--all-systems' to show)
│ ├───docs omitted (use '--all-systems' to show)
│ ├───editor omitted (use '--all-systems' to show)
└───templates
├───default: template: Initialize a new clan flake
└───new-clan: template: Initialize a new clan flake
```
You can execute every test separately by following the tree path `nix run .#checks.x86_64-linux.clan-pytest -L` for example.
## Test Locally in Devshell with Breakpoints
To test the cli locally in a development environment and set breakpoints for debugging, follow these steps:
1. Run the following command to execute your tests and allow for debugging with breakpoints:
```bash
cd ./pkgs/clan-cli
pytest -n0 -s --maxfail=1 ./tests/test_nameofthetest.py
```
You can place `breakpoint()` in your Python code where you want to trigger a breakpoint for debugging.
## Test Locally in a Nix Sandbox
To run tests in a Nix sandbox, you have two options depending on whether your test functions have been marked as impure or not:
### Running Tests Marked as Impure
If your test functions need to execute `nix build` and have been marked as impure because you can't execute `nix build` inside a Nix sandbox, use the following command:
```bash
nix run .#impure-checks -L
```
This command will run the impure test functions.
### Running Pure Tests
For test functions that have not been marked as impure and don't require executing `nix build`, you can use the following command:
```bash
nix build .#checks.x86_64-linux.clan-pytest --rebuild
```
This command will run all pure test functions.
### Inspecting the Nix Sandbox
If you need to inspect the Nix sandbox while running tests, follow these steps:
1. Insert an endless sleep into your test code where you want to pause the execution. For example:
```python
import time
time.sleep(3600) # Sleep for one hour
```
2. Use `cntr` and `psgrep` to attach to the Nix sandbox. This allows you to interactively debug your code while it's paused. For example:
```bash
psgrep <your_python_process_name>
cntr attach <container id, container name or process id>
```
Or you can also use the [nix breakpoint hook](https://nixos.org/manual/nixpkgs/stable/#breakpointhook)

View File

@@ -0,0 +1,316 @@
# Testing your contributions
Each feature added to clan should be tested extensively via automated tests.
This document covers different methods of automated testing, including creating, running and debugging such tests.
In order to test the behavior of clan, different testing frameworks are used depending on the concern:
- NixOS VM tests: for high level integration
- NixOS container tests: for high level integration
- Python tests via pytest: for unit tests and integration tests
- Nix eval tests: for nix functions, libraries, modules, etc.
## NixOS VM Tests
The [NixOS VM Testing Framework](https://nixos.org/manual/nixos/stable/index.html#sec-nixos-tests) is used to create high level integration tests, by running one or more VMs generated from a specified config. Commands can be executed on the booted machine(s) to verify a deployment of a service works as expected. All machines within a test are connected by a virtual network. Internet access is not available.
### When to use VM tests
- testing that a service defined through a clan module works as expected after deployment
- testing clan-cli subcommands which require accessing a remote machine
### When not to use VM tests
NixOS VM Tests are slow and expensive. They should only be used for testing high level integration of components.
VM tests should be avoided wherever it is possible to implement a cheaper unit test instead.
- testing detailed behavior of a certain clan-cli command -> use unit testing via pytest instead
- regression testing -> add a unit test
### Finding examples for VM tests
Existing nixos vm tests in clan-core can be found by using ripgrep:
```shellSession
rg "import.*/lib/test-base.nix"
```
### Locating definitions of failing VM tests
All nixos vm tests in clan are exported as individual flake outputs under `checks.x86_64-linux.{test-attr-name}`.
If a test fails in CI:
- look for the job name of the test near the top if the CI Job page, like, for example `gitea:clan/clan-core#checks.x86_64-linux.borgbackup/1242`
- in this case `checks.x86_64-linux.borgbackup` is the attribute path
- note the last element of that attribute path, in this case `borgbackup`
- search for the attribute name inside the `/checks` directory via ripgrep
example: locating the vm test named `borgbackup`:
```shellSession
$ rg "borgbackup =" ./checks
./checks/flake-module.nix
41: borgbackup = import ./borgbackup nixosTestArgs;
```
-> the location of that test is `/checks/flake-module.nix` line `41`.
### Adding vm tests
Create a nixos test module under `/checks/{name}/default.nix` and import it in `/checks/flake-module.nix`.
### Running VM tests
```shellSession
nix build .#checks.x86_64-linux.{test-attr-name}
```
(replace `{test-attr-name}` with the name of the test)
### Debugging VM tests
The following techniques can be used to debug a VM test:
#### Print Statements
Locate the definition (see above) and add print statements, like, for example `print(client.succeed("systemctl --failed"))`, then re-run the test via `nix build` (see above)
#### Interactive Shell
- Execute the vm test outside the nix Sandbox via the following command:
`nix run .#checks.x86_64-linux.{test-attr-name}.driver -- --interactive`
- Then run the commands in the machines manually, like for example:
```python3
start_all()
machine1.succeed("echo hello")
```
#### Breakpoints
To get an interactive shell at a specific line in the VM test script, add a `breakpoint()` call before the line to debug, then run the test outside of the sandbox via:
`nix run .#checks.x86_64-linux.{test-attr-name}.driver`
## NixOS Container Tests
Those are very similar to NixOS VM tests, as in they run virtualized nixos machines, but instead of using VMs, they use containers which are much cheaper to launch.
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:
- does not yet support networking
- supports only one machine as of now
### Where to find examples for NixOS container tests
Existing nixos container tests in clan-core can be found by using ripgrep:
```shellSession
rg "import.*/lib/container-test.nix"
```
## Python tests via pytest
Since the clan cli is written in python, the `pytest` framework is used to define unit tests and integration tests via python
Due to superior efficiency,
### When to use python tests
- writing unit tests for python functions and modules, or bugfixes of such
- all integrations tests that do not require building or running a nixos machine
- impure integrations tests that require internet access (very rare, try to avoid)
### When not to use python tests
- integrations tests that require building or running a nixos machine (use NixOS VM or container tests instead)
- testing behavior of a nix function or library (use nix eval tests instead)
### Finding examples of python tests
Existing python tests in clan-core can be found by using ripgrep:
```shellSession
rg "import pytest"
```
### Locating definitions of failing python tests
If any python test fails in the CI pipeline, an error message like this can be found at the end of the log:
```
...
FAILED tests/test_machines_cli.py::test_machine_delete - clan_cli.errors.ClanError: Template 'new-machine' not in 'inputs.clan-core
...
```
In this case the test is defined in the file `/tests/test_machines_cli.py` via the test function `test_machine_delete`.
### Adding python tests
If a specific python module is tested, the test should be located near the tested module in a subdirectory called `./tests`
If the test is not clearly related to a specific module, put it in the top-level `./tests` directory of the tested python package. For `clan-cli` this would be `/pkgs/clan-cli/clan_cli/tests`.
All filenames must be prefixed with `test_` and test functions prefixed with `test_` for pytest to discover them.
### Running python tests
#### Running all python tests
To run all python tests which are executed in the CI pipeline locally, use this `nix build` command
```shellSession
nix build .#checks.x86_64-linux.clan-pytest-{with,without}-core
```
#### Running a specific python test
To run a specific python test outside the nix sandbox
1. Enter the development environment of the python package, by either:
- Having direnv enabled and entering the directory of the package (eg. `/pkgs/clan-cli`)
- Or using the command `select-shell {package}` in the top-level dev shell of clan-core, (eg. `switch-shell clan-cli`)
2. Execute the test via pytest using issuing
`pytest ./path/to/test_file.py:test_function_name -s -n0`
The flags `-sn0` are useful to forwards all stdout/stderr output to the terminal and be able to debug interactively via `breakpoint()`.
### Debugging python tests
To debug a specific python test, find its definition (see above) and make sure to enter the correct dev environment for that python package.
Modify the test and add `breakpoint()` statements to it.
Execute the test using the flags `-sn0` in order to get an interactive shell at the breakpoint:
```shelSession
pytest ./path/to/test_file.py:test_function_name -sn0
```
## Nix Eval Tests
### When to use nix eval tests
Nix eval tests are good for testing any nix logic, including
- nix functions
- nix libraries
- modules for the nixos module system
When not to use
- tests that require building nix derivations (except some very cheap ones)
- tests that require running programs written in other languages
- tests that require building or running nixos machines
### Finding examples of nix eval tests
Existing nix eval tests can be found via this ripgrep command:
```shellSession
rg "nix-unit --eval-store"
```
### Locating definitions of failing nix eval tests
Failing nix eval tests look like this:
```shellSession
> ✅ test_attrsOf_attrsOf_submodule
> ✅ test_attrsOf_submodule
> ❌ test_default
> /build/nix-8-2/expected.nix --- Nix
> 1 { foo = { bar = { __prio = 1500; }; } 1 { foo = { bar = { __prio = 1501; }; }
> . ; } . ; }
>
>
> ✅ test_no_default
> ✅ test_submodule
> ✅ test_submoduleWith
> ✅ test_submodule_with_merging
>
> 😢 6/7 successful
> error: Tests failed
```
To locate the definition, find the flake attribute name of the failing test near the top of the CI Job page, like for example `gitea:clan/clan-core#checks.x86_64-linux.lib-values-eval/1242`.
In this case `lib-values-eval` is the attribute we are looking for.
Find the attribute via ripgrep:
```shellSession
$ rg "lib-values-eval ="
lib/values/flake-module.nix
21: lib-values-eval = pkgs.runCommand "tests" { nativeBuildInputs = [ pkgs.nix-unit ]; } ''
grmpf@grmpf-nix ~/p/c/clan-core (test-docs)>
```
In this case the test is defined in the file `lib/values/flake-module.nix` line 21
### Adding nix eval tests
In clan core, the following pattern is usually followed:
- tests are put in a `test.nix` file
- a CI Job is exposed via a `flake-module.nix`
- that `flake-module.nix` is imported via the `flake.nix` at the root of the project
For example see `/lib/values/{test.nix,flake-module.nix}`.
### Running nix eval tests
Since all nix eval tests are exposed via the flake outputs, they can be ran via `nix build`:
```shellSession
nix build .#checks.x86_64-linux.{test-attr-name}
```
For quicker iteration times, instead of `nix build` use the `nix-unit` command available in the dev environment.
Example:
```shellSession
nix-unit --flake .#legacyPackages.x86_64-linux.{test-attr-name}
```
### Debugging nix eval tests
Follow the instructions above to find the definition of the test, then use one of the following techniques:
#### Print debugging
Add `lib.trace` or `lib.traceVal` statements in order to print some variables during evaluation
#### Nix repl
Use `nix repl` to evaluate to inspec the test.
Each test consists opf an `expr` (expression) and an `expected` field. `nix-unit` simply checks if `expr == expected` and prints the diff if that's not the case.
`nix repl` can be used to inspect `expr` manually, or any other variables that you choose to expose.
Example:
```shellSession
$ nix repl
Nix 2.25.5
Type :? for help.
nix-repl> tests = import ./lib/values/test.nix {}
nix-repl> tests
{
test_attrsOf_attrsOf_submodule = { ... };
test_attrsOf_submodule = { ... };
test_default = { ... };
test_no_default = { ... };
test_submodule = { ... };
test_submoduleWith = { ... };
test_submodule_with_merging = { ... };
}
nix-repl> tests.test_default.expr
{
foo = { ... };
}
```

View File

@@ -1,6 +1,4 @@
# Backups
## Introduction to Backups
# Introduction to Backups
When you're managing your own services, creating regular backups is crucial to ensure your data's safety.
This guide introduces you to Clan's built-in backup functionalities.
@@ -9,8 +7,6 @@ We might add more options in the future, but for now, let's dive into how you ca
## Backing Up Locally with Localbackup
### What is Localbackup?
Localbackup lets you backup your data onto physical storage devices connected to your computer,
such as USB hard drives or network-attached storage. It uses a tool called rsnapshot for this purpose.
@@ -147,3 +143,25 @@ Ensure the path to the public key is correct.
```bash
clan backups create mymachine
```
- **Restoring Backups:** To restore a backup that has been listed by the list command (NAME):
```bash
clan backups restore [MACHINE] [PROVIDER] [NAME]
```
Example (Restoring a machine called `client` with the backup provider `borgbackup`):
```bash
clan backups restore client borgbackup [NAME]
```
The `backups` command is service aware and allows optional specification of the `--service` flag.
To only restore the service called `zerotier` on a machine called `controller` through the backup provider `borgbackup` use the following command:
```bash
clan backups restore client borgbackup [NAME] --service zerotier
```

View File

@@ -0,0 +1,28 @@
### Generate Facts and Vars
Typically, this step is handled automatically when a machine is deployed. However, to enable the use of `nix flake check` with your configuration, it must be completed manually beforehand.
Currently, generating all the necessary facts requires two separate commands. This is due to the coexistence of two parallel secret management solutions:
the newer, recommended version (`clan vars`) and the older version (`clan facts`) that we are slowly phasing out.
To generate both facts and vars, execute the following commands:
```sh
clan facts generate && clan vars generate
```
### Check Configuration
Validate your configuration by running:
```bash
nix flake check
```
This command helps ensure that your system configuration is correct and free from errors.
!!! Tip
You can integrate this step into your [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) workflow to ensure that only valid Nix configurations are merged into your codebase.

View File

@@ -1,10 +1,8 @@
# Configuration - How to configure clan with your own machines
Managing machine configurations can be done in the following ways:
- writing `nix` expressions in a `flake.nix` file,
- placing `autoincluded` files into your machine directory,
- configuring everything in a simple UI (upcoming).
Clan currently offers the following methods to configure machines:
@@ -80,9 +78,14 @@ Adding or configuring a new machine requires two simple steps:
└─nvme0n1p3 nvme-eui.e8238fa6bf530001001b448b4aec2929-part3 swap 16.8G
```
1. Edit the following fields inside the `./machines/jon/configuration.nix` and/or `./machines/sara/configuration.nix`
!!! Warning
Make sure to copy the `ID-LINK` from toplevel disk device like `nvme0n1` or `sda` instead of `nvme0n1p1` or `sda1`
```nix title="./machines/<machine>/configuration.nix" hl_lines="13 18 23 27"
2. Edit the following fields inside the `./machines/jon/configuration.nix` and/or `./machines/sara/configuration.nix`
<!-- Note: Use "jon" instead of "<machine>" as "<" is not supported in title tag -->
```nix title="./machines/jon/configuration.nix" hl_lines="13 18 22 26"
{
imports = [
./hardware-configuration.nix
@@ -95,16 +98,15 @@ Adding or configuring a new machine requires two simple steps:
];
# Put your username here for login
users.users.user.username = "__YOUR_USERNAME__";
users.users.user.name = "__YOUR_USERNAME__";
# Set this for clan commands use ssh i.e. `clan machines update`
# Set this for clan commands that use ssh
# If you change the hostname, you need to update this line to root@<new-hostname>
# This only works however if you have avahi running on your admin machine else use IP
clan.core.networking.targetHost = "root@__IP__";
# You can get your disk id by running the following command on the installer:
# Replace <IP> with the IP of the installer printed on the screen or by running the `ip addr` command.
# ssh root@<IP> lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT
# Replace this __CHANGE_ME__ with the result of the lsblk command from step 1.
disko.devices.disk.main.device = "/dev/disk/by-id/__CHANGE_ME__";
# IMPORTANT! Add your SSH key here
@@ -115,79 +117,32 @@ Adding or configuring a new machine requires two simple steps:
}
```
You can also create additional machines using the `clan machines create` command:
```
$ clan machines create --help
usage: clan [-h] [SUBCOMMAND] machines create [-h] [--tags TAGS [TAGS ...]] [--template-name TEMPLATE_NAME]
[--target-host TARGET_HOST] [--debug] [--option name value] [--flake PATH]
machine_name
positional arguments:
machine_name The name of the machine to create
options:
-h, --help show this help message and exit
--tags TAGS [TAGS ...]
Tags to associate with the machine. Can be used to assign multiple machines to services.
--template-name TEMPLATE_NAME
The name of the template machine to import
--target-host TARGET_HOST
Address of the machine to install and update, in the format of user@host:1234
--debug Enable debug logging
--option name value Nix option to set
--flake PATH path to the flake where the clan resides in, can be a remote flake or local, can be set through
the [CLAN_DIR] environment variable
```
!!! Info "Replace `__YOUR_USERNAME__` with the ip of your machine, if you use avahi you can also use your hostname"
!!! Info "Replace `__IP__` with the ip of your machine, if you use avahi you can also use your hostname"
!!! Info "Replace `__CHANGE_ME__` with the appropriate identifier, such as `nvme-eui.e8238fa6bf530001001b448b4aec2929`"
!!! Info "Replace `__CHANGE_ME__` with the appropriate `ID-LINK` identifier, such as `nvme-eui.e8238fa6bf530001001b448b4aec2929`"
!!! Info "Replace `__YOUR_SSH_KEY__` with your personal key, like `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILoMI0NC5eT9pHlQExrvR5ASV3iW9+BXwhfchq0smXUJ jon@jon-desktop`"
These steps will allow you to update your machine later.
### Step 2: Detect Drivers
You can also create additional machines using the cli:
Generate the `hardware-configuration.nix` file for your machine by executing the following command:
```
$ clan machines create <machinename>
```
```bash
clan machines update-hardware-config [MACHINE_NAME] [HOSTNAME]
```
replace `[MACHINE_NAME]` with the name of the machine i.e. `jon` and `[HOSTNAME]` with the `ip_address` or `hostname` of the machine within the network. i.e. `<IP>`
!!! Example
```bash
clan machines update-hardware-config jon
```
This command connects to the ip configured in the previous step, runs `nixos-generate-config` to detect hardware configurations (excluding filesystems), and writes them to `machines/jon/hardware-configuration.nix`.
### Step 3: Custom Disk Formatting
### Step 2: Custom Disk Formatting
In `./modules/disko.nix`, a simple `ext4` disk partitioning scheme is defined for the Disko module. For more complex disk partitioning setups,
refer to the [Disko templates](https://github.com/nix-community/disko-templates) or [Disko examples](https://github.com/nix-community/disko/tree/master/example).
### Step 4: Custom Configuration
### (Optional): Renaming Machine
Modify `./machines/jon/configuration.nix` to personalize the system settings according to your requirements.
If you wish to name your machine to something else, do the following steps:
For renaming jon to your own machine name, you can use the following command:
```
mv ./machines/jon/configuration.nix ./machines/newname/configuration.nix
git mv ./machines/jon ./machines/newname
```
Than rename `jon` to your preferred name in `machines` in `flake.nix` as well as the import line:
```diff
- imports = [ ./machines/jon/configuration.nix ];
+ imports = [ ./machines/__NEW_NAME__/configuration.nix ];
```
!!! Info "Replace `__NEW_NAME__` with the name of the machine"
Note that our clan lives inside a git repository.
Only files that have been added with `git add` are recognized by `nix`.
So for every file that you add or rename you also need to run:
@@ -196,22 +151,11 @@ So for every file that you add or rename you also need to run:
git add ./path/to/my/file
```
For renaming jon to your own machine name, you can use the following command:
```
git mv ./machines/jon ./machines/newname
```
### (Optional): Removing a Machine
If you only want to setup a single machine at this point, you can delete `sara` from `flake.nix` as well as from the machines directory:
```
git rm ./machines/sara
git rm -rf ./machines/sara
```
---
## What's next?
- [Secrets & Facts](secrets.md): Setting up secrets with sops-nix
---

View File

@@ -1,14 +1,7 @@
# Deploy Machine
# Deploy your Clan
Integrating a new machine into your Clan environment is an easy yet flexible process, allowing for a straight forward management of multiple NixOS configurations.
Now that you have created a new machine, we will walk through how to install it.
We'll walk you through adding a new computer to your Clan.
## Installing a New Machine
Clan CLI, in conjunction with [nixos-anywhere](https://github.com/nix-community/nixos-anywhere), provides a seamless method for installing NixOS on various machines.
This process involves preparing a suitable hardware and disk partitioning configuration and ensuring the target machine is accessible via SSH.
### Step 0. Prerequisites
@@ -25,7 +18,7 @@ This process involves preparing a suitable hardware and disk partitioning config
2. Boot the target machine and connect it to a network that makes it reachable from your setup computer.
=== "**Remote Machines**"
=== "**Cloud VMs**"
- [x] **Two Computers**: You need one computer that you're getting ready (we'll call this the Target Computer) and another one to set it up from (we'll call this the Setup Computer). Make sure both can talk to each other over the network using SSH.
- [x] **Machine configuration**: See our basic [configuration guide](./configure.md)
@@ -108,32 +101,27 @@ This process involves preparing a suitable hardware and disk partitioning config
For easy sharing of deployment information via QR code, we highly recommend using [KDE Connect](https://apps.kde.org/de/kdeconnect/).
There are two ways to deploy your machine:
=== "**Password Auth**"
Run the following command to login over SSH with password authentication
```bash
clan machines install [MACHINE] --target-host <IP> --update-hardware-config nixos-facter
```
=== "**QR Code Auth**"
Using the JSON contents of the QR Code:
```terminal
clan machines install [MACHINE] --json "[JSON]" --update-hardware-config nixos-facter
```
OR using a picture containing the QR code
```terminal
clan machines install [MACHINE] --png [PATH] --update-hardware-config nixos-facter
```
1. **SSH with Password Authentication**
Run the following command to install using SSH:
```bash
clan machines install [MACHINE] --target-host <IP>
```
2. **Scanning a QR Code for Installation Details**
You can input the information by following one of these methods:
- **Using a JSON String or File Path:**
Provide the path to a JSON string or input the string directly:
```terminal
clan machines install [MACHINE] --json [JSON]
```
- **Using an Image Containing the QR Code:**
Provide the path to an image file containing the relevant QR code:
```terminal
clan machines install [MACHINE] --png [PATH]
```
=== "**SSH access**"
=== "**Cloud VM**"
Replace `<target_host>` with the **target computers' ip address**:
```bash
clan machines install [MACHINE] --target-host <target_host>
clan machines install [MACHINE] --target-host <target_host> --update-hardware-config nixos-facter
```
@@ -215,12 +203,4 @@ buildClan {
This is useful for machines that are not always online or are not part of the regular update cycle.
---
## What's next ?
- [**Disk Encryption**](./disk-encryption.md): Configure disk encryption with remote decryption
- [**Mesh VPN**](./mesh-vpn.md): Configuring a secure mesh network.
---

View File

@@ -14,7 +14,7 @@ lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT
=== "**Single Disk**"
Below is the configuration for `disko.nix`
```nix hl_lines="17 48"
```nix hl_lines="13 53"
--8<-- "docs/code-examples/disko-single-disk.nix"
```
@@ -22,7 +22,7 @@ lsblk --output NAME,ID-LINK,FSTYPE,SIZE,MOUNTPOINT
=== "**Raid 1**"
Below is the configuration for `disko.nix`
```nix hl_lines="17 48 49"
```nix hl_lines="13 53 54"
--8<-- "docs/code-examples/disko-raid.nix"
```
@@ -49,7 +49,8 @@ Replace `kernelModules` with the ethernet module loaded one on your target machi
port = 7172;
authorizedKeys = [ "<yourkey>" ];
hostKeys = [
"/var/lib/initrd-ssh-key"
"/var/lib/initrd_host_ed25519_key"
"/var/lib/initrd_host_rsa_key"
];
};
};
@@ -73,7 +74,7 @@ Before starting the installation process, ensure that the SSH public key is copi
ssh-copy-id -o PreferredAuthentications=password -o PubkeyAuthentication=no root@nixos-installer.local
```
### Step 1.5: Prepare Secret Key and Clear Disk Data
### Step 1.5: Prepare Secret Key and Partition Disks
1. Access the installer using SSH:
@@ -90,13 +91,13 @@ nano /tmp/secret.key
3. Discard the old disk partition data:
```bash
blkdiscard /dev/disk/by-id/nvme-eui.002538b931b59865
blkdiscard /dev/disk/by-id/<installdisk>
```
4. Run the `clan` machine installation with the following command:
4. Run `clan` machines install, only running kexec and disko, with the following command:
```bash
clan machines install gchq-local --target-host root@nixos-installer --yes --no-reboot
clan machines install gchq-local --target-host root@nixos-installer --phases kexec,disko
```
### Step 2: ZFS Pool Import and System Installation
@@ -107,14 +108,10 @@ clan machines install gchq-local --target-host root@nixos-installer --yes --no-r
ssh root@nixos-installer.local
```
2. Perform the following commands on the remote installation environment:
2. Run the following command on the remote installation environment:
```bash
zpool import zroot
zfs set keylocation=prompt zroot/root
zfs load-key zroot/root
zfs set mountpoint=/mnt zroot/root/nixos
mount /dev/nvme0n1p2 /mnt/boot
```
3. Disconnect from the SSH session:
@@ -123,43 +120,36 @@ mount /dev/nvme0n1p2 /mnt/boot
CTRL+D
```
4. Securely copy your local `initrd_rsa_key` to the installer's `/mnt` directory:
4. Locally generate ssh host keys. You only need to generate ones for the algorithms you're using in `authorizedKeys`.
```bash
scp ~/.ssh/initrd_rsa_key root@nixos-installer.local:/mnt/var/lib/initrd-ssh-key
ssh-keygen -q -N "" -t ed25519 -f ./initrd_host_ed25519_key
ssh-keygen -q -N "" -t rsa -b 4096 -f ./initrd_host_rsa_key
```
5. SSH back into the installer:
5. Securely copy your local initrd ssh host keys to the installer's `/mnt` directory:
```bash
ssh root@nixos-installer.local
scp ./initrd_host* root@nixos-installer.local:/mnt/var/lib/
```
6. Navigate to the `/mnt` directory, enter the `nixos-enter` environment, and then exit:
6. Install nixos to the mounted partitions
```bash
cd /mnt
nixos-enter
realpath /run/current-system
exit
clan machines install gchq-local --target-host root@nixos-installer --phases install
```
7. Run the `nixos-install` command with the appropriate system path `<SYS_PATH>`:
```bash
nixos-install --no-root-passwd --no-channel-copy --root /mnt --system <SYS_PATH>
```
8. After the installation process, unmount `/mnt/boot`, change the ZFS mountpoint, and reboot the system:
7. After the installation process, unmount `/mnt/boot`, change the ZFS mountpoints and unmount all the ZFS volumes by exporting the zpool:
```bash
umount /mnt/boot
cd /
zfs set mountpoint=/ zroot/root/nixos
reboot
zfs set -u mountpoint=/ zroot/root/nixos
zfs set -u mountpoint=/tmp zroot/root/tmp
zfs set -u mountpoint=/home zroot/root/home
zpool export zroot
```
9. Perform a hard reboot of the machine and remove the USB stick.
8. Perform a reboot of the machine and remove the USB installer.
### Step 3: Accessing the Initial Ramdisk (initrd) Environment
@@ -172,7 +162,7 @@ ssh -p 7172 root@192.168.178.141
2. Run the `systemd-tty-ask-password-agent` utility to query a password:
```bash
systemd-tty-ask-password-agent --query
systemd-tty-ask-password-agent
```
After completing these steps, your NixOS should be successfully installed and ready for use.

View File

@@ -1,6 +1,9 @@
# :material-clock-fast: Getting Started
Create your own clan with these initial steps and manage a fleet of machines with one single testable git repository!
Ready to create your own clan and manage a fleet of machines? Follow these simple steps to get started.
By the end of this guide, you'll have a fresh NixOS configuration ready to push to one or more machines. You'll create a new git repository and a flake, and all you need is at least one machine to push to. This is the easiest way to begin, and we recommend you to copy your existing configuration into this new setup!
### Prerequisites
@@ -39,7 +42,7 @@ Create your own clan with these initial steps and manage a fleet of machines wit
Add the Clan CLI into your development workflow:
```bash
nix shell git+https://git.clan.lol/clan/clan-core#clan-cli
nix shell git+https://git.clan.lol/clan/clan-core#clan-cli --refresh
```
You can find reference documentation for the `clan` cli program [here](../reference/cli/index.md).
@@ -51,6 +54,8 @@ clan --help
### Step 2: Initialize Your Project
If you want to migrate an existing project, follow this [guide](https://docs.clan.lol/manual/migration-guide/).
Set the foundation of your Clan project by initializing it as follows:
```bash
@@ -87,6 +92,21 @@ This should yield the following:
5 directories, 9 files
```
??? info "Recommended way of sourcing the `clan` cli tool"
The default template also adds the `clan` cli tool to the development shell.
Meaning you can get the exact version you need directly from the folder
you are in right now.
In the `my-clan` directory run the following command:
```
nix develop
```
That way you will have the tool available in the shell environment.
We also recommend setting up [direnv](https://direnv.net/) for your shell, for a more convenient
experience.
```bash
clan machines list
```
@@ -100,10 +120,3 @@ sara
You just successfully bootstrapped your first clan directory.
---
### What's Next?
- [**Installer**](./installer.md): Setting up new computers remotely is easy with an USB stick.
---

View File

@@ -1,11 +1,16 @@
# Installer
# Clan Installer Image for Physical Machines
Our installer image simplifies the process of performing remote installations.
To install Clan on physical machines, you need to use our custom installer image. This is necessary for proper installation and operation.
Follow our step-by-step guide to create and transfer this image onto a bootable USB drive.
!!! note "Using a Cloud VM?"
If you're using a cloud provider's virtual machine (VM), you can skip this section and go directly to the [Configure Machines](configure.md) step. In this scenario, we automatically use [nixos-anywhere](https://github.com/nix-community/nixos-anywhere) to replace the kernel during runtime.
??? info "Why nixos-anywhere Doesn't Work on Physical Hardware?"
nixos-anywhere relies on [kexec](https://wiki.archlinux.org/title/Kexec) to replace the running kernel with our custom one. This method often has compatibility issues with real hardware, especially systems with dedicated graphics cards like laptops and servers, leading to crashes and black screens.
??? info "Reasons for a Custom Install Image"
Our custom install images are built to include essential tools like [nixos-facter](https://github.com/nix-community/nixos-facter) and support for [ZFS](https://wiki.archlinux.org/title/ZFS). They're also optimized to run on systems with as little as 1 GB of RAM, ensuring efficient performance even on lower-end hardware.
!!! info
If you already have a NixOS machine you can ssh into (in the cloud for example) you can skip this chapter and go directly to [Configure Machines](configure.md).
### Step 0. Prerequisites
@@ -40,9 +45,9 @@ Follow our step-by-step guide to create and transfer this image onto a bootable
sudo umount /dev/sdb1
```
=== "**Linux OS**"
### Step 2. Flash Custom Installer
### Step 2. Create a Custom Installer
Using clan flash enables the inclusion of ssh public keys and wifi access points.
Using clan flash enables the inclusion of ssh public keys into the image.
It also allows to set language and keymap in the installer image.
```bash
@@ -61,7 +66,8 @@ sudo umount /dev/sdb1
The `clan flash` utility will erase the disk. Make sure to specify the correct device
- **SSH-Pubkey Option**:
- **SSH-Pubkey Option**
To add an ssh public key into the installer image append the option:
```
--ssh-pubkey <pubkey_path>
@@ -69,19 +75,21 @@ sudo umount /dev/sdb1
If you do not have an ssh key yet, you can generate one with `ssh-keygen -t ed25519` command.
This ssh key will be installed into the root user.
- **Connect to the installer
- **Connect to the installer**
On boot, the installer will display on-screen the IP address it received from the network.
If you need to configure Wi-Fi first, refer to the next section.
If Multicast-DNS (Avahi) is enabled on your own machine, you can also access the installer using the `flash-installer.local` address.
- **List Keymaps**:
- **List Keymaps**
You can get a list of all keymaps with the following command:
```
clan flash list keymaps
```
- **List Languages**:
- **List Languages**
You can get a list of all languages with the following command:
```
clan flash list languages
@@ -194,10 +202,3 @@ Press ++ctrl+d++ to exit `IWD`.
You're all set up
---
## What's next?
- [Configure Machines](configure.md): Customize machine configuration
---

View File

@@ -1,4 +1,3 @@
# Mesh VPN
This guide provides detailed instructions for configuring
[ZeroTier VPN](https://zerotier.com) within Clan. Follow the
@@ -19,89 +18,128 @@ Clan
If you select multiple network technologies at the same time. e.g. (zerotier + yggdrassil)
You must choose one of them as primary network and the machines are always connected via the primary network.
## 1. Set-Up the VPN Controller
The VPN controller is initially essential for providing configuration to new
peers. Once addresses are allocated, the controller's continuous operation is not essential.
1. **Designate a Machine**: Label a machine as the VPN controller in the clan,
referred to as `<CONTROLLER>` henceforth in this guide.
2. **Add Configuration**: Input the following configuration to the NixOS
configuration of the controller machine:
```nix
clan.core.networking.zerotier.controller = {
enable = true;
public = true;
};
```
3. **Update the Controller Machine**: Execute the following:
```bash
clan machines update <CONTROLLER>
```
Your machine is now operational as the VPN controller.
## 2. Add Machines to the VPN
To introduce a new machine to the VPN, adhere to the following steps:
1. **Update Configuration**: On the new machine, incorporate the following to its
configuration, substituting `<CONTROLLER>` with the controller machine name:
```nix
{ config, ... }: {
clan.core.networking.zerotier.networkId = builtins.readFile (config.clan.core.settings.directory + "/machines/<CONTROLLER>/facts/zerotier-network-id");
}
```
1. **Update the New Machine**: Execute:
```bash
$ clan machines update <NEW_MACHINE>
```
Replace `<NEW_MACHINE>` with the designated new machine name.
!!! Note "For Private Networks"
1. **Retrieve Zerotier Metadata**
=== "From the repo"
**Retrieve the ZeroTier IP**: In the clan repo, execute:
```console
$ clan facts list <NEW_MACHINE> | jq -r '.["zerotier-ip"]'
```
The returned address is the Zerotier IP address of the machine.
=== "On the new machine"
**Retrieve the ZeroTier ID**: On the `new_machine`, execute:
```bash
$ sudo zerotier-cli info
```
Example Output:
```{.console, .no-copy}
200 info d2c71971db 1.12.1 OFFLINE
```
, where `d2c71971db` is the ZeroTier ID.
This guide shows you how to configure `zerotier` either through `NixOS Options` directly, or Clan's `Inventory` System.
2. **Authorize the New Machine on the Controller**: On the controller machine,
execute:
=== "**Inventory**"
## 1. Choose the Controller
=== "with ZerotierIP"
```bash
$ sudo zerotier-members allow --member-ip <IP>
```
Substitute `<IP>` with the ZeroTier IP obtained previously.
=== "with ZerotierID"
```bash
$ sudo zerotier-members allow <ID>
```
Substitute `<ID>` with the ZeroTier ID obtained previously.
The controller is the initial entrypoint for new machines into the vpn.
It will sign the id's of new machines.
Once id's are signed, the controller's continuous operation is not essential.
A good controller choice is nevertheless a machine that can always be reached for updates - so that new peers can be added to the network.
2. **Verify Connection**: On the `new_machine`, re-execute:
```bash
$ sudo zerotier-cli info
```
The status should now be "ONLINE":
```{.console, .no-copy}
200 info d2c71971db 1.12.1 ONLINE
```
For the purpose of this guide we have two machines:
- The `controller` machine, which will be the zerotier controller.
- The `new_machine` machine, which is the machine we want to add to the vpn network.
## 2. Configure the Inventory
```nix
clan.inventory = {
services.zerotier.default = {
roles.controller.machines = [
"controller"
];
roles.peer.machines = [
"new_machine"
];
};
};
```
## 3. Apply the Configuration
Update the `controller` machine:
```bash
clan machines update controller
```
=== "**NixOS Options**"
## 1. Set-Up the VPN Controller
The VPN controller is initially essential for providing configuration to new
peers. Once addresses are allocated, the controller's continuous operation is not essential.
1. **Designate a Machine**: Label a machine as the VPN controller in the clan,
referred to as `<CONTROLLER>` henceforth in this guide.
2. **Add Configuration**: Input the following configuration to the NixOS
configuration of the controller machine:
```nix
clan.core.networking.zerotier.controller = {
enable = true;
public = true;
};
```
3. **Update the Controller Machine**: Execute the following:
```bash
clan machines update <CONTROLLER>
```
Your machine is now operational as the VPN controller.
## 2. Add Machines to the VPN
To introduce a new machine to the VPN, adhere to the following steps:
1. **Update Configuration**: On the new machine, incorporate the following to its
configuration, substituting `<CONTROLLER>` with the controller machine name:
```nix
{ config, ... }: {
clan.core.networking.zerotier.networkId = builtins.readFile (config.clan.core.settings.directory + "/machines/<CONTROLLER>/facts/zerotier-network-id");
}
```
1. **Update the New Machine**: Execute:
```bash
$ clan machines update <NEW_MACHINE>
```
Replace `<NEW_MACHINE>` with the designated new machine name.
!!! Note "For Private Networks"
1. **Retrieve Zerotier Metadata**
=== "From the repo"
**Retrieve the ZeroTier IP**: In the clan repo, execute:
```console
$ clan facts list <NEW_MACHINE> | jq -r '.["zerotier-ip"]'
```
The returned address is the Zerotier IP address of the machine.
=== "On the new machine"
**Retrieve the ZeroTier ID**: On the `new_machine`, execute:
```bash
$ sudo zerotier-cli info
```
Example Output:
```{.console, .no-copy}
200 info d2c71971db 1.12.1 OFFLINE
```
, where `d2c71971db` is the ZeroTier ID.
2. **Authorize the New Machine on the Controller**: On the controller machine,
execute:
=== "with ZerotierIP"
```bash
$ sudo zerotier-members allow --member-ip <IP>
```
Substitute `<IP>` with the ZeroTier IP obtained previously.
=== "with ZerotierID"
```bash
$ sudo zerotier-members allow <ID>
```
Substitute `<ID>` with the ZeroTier ID obtained previously.
2. **Verify Connection**: On the `new_machine`, re-execute:
```bash
$ sudo zerotier-cli info
```
The status should now be "ONLINE":
```{.console, .no-copy}
200 info d2c71971db 1.12.1 ONLINE
```
!!! success "Congratulations!"
The new machine is now part of the VPN, and the ZeroTier

View File

@@ -1,8 +1,8 @@
# Secrets / Facts
Clan enables encryption of secrets (such as passwords & keys) ensuring security and ease-of-use among users.
Clan utilizes the [sops](https://github.com/getsops/sops) format and integrates with [sops-nix](https://github.com/Mic92/sops-nix) on NixOS machines.
By default Clan utilizes the [sops](https://github.com/getsops/sops) format and integrates with [sops-nix](https://github.com/Mic92/sops-nix) on NixOS machines.
Clan can also be configured to be used with other secret store [backends](https://docs.clan.lol/reference/clan-core/vars/#clan.core.vars.settings.secretStore).
This guide will walk you through:
@@ -40,7 +40,7 @@ Also add your age public key to the repository with 'clan secrets users add YOUR
### Add Your Public Key
```bash
clan secrets users add $USER <your_public_key>
clan secrets users add $USER --age-key <your_public_key>
```
It's best to choose the same username as on your Setup/Admin Machine that you use to control the deployment with.
@@ -54,38 +54,3 @@ sops/
└── key.json
```
If you followed the quickstart tutorial all necessary secrets are initialized at this point.
### Generate Facts and Vars
Typically, this step is handled automatically when a machine is deployed. However, to enable the use of `nix flake check` with your configuration, it must be completed manually beforehand.
Currently, generating all the necessary facts requires two separate commands. This is due to the coexistence of two parallel secret management solutions: the older, stable version (`clan secrets` and `clan facts`) and the newer, experimental version (`clan vars`).
To generate both facts and vars, execute the following commands:
```sh
clan facts generate && clan vars generate
```
### Check Configuration
Validate your configuration by running:
```bash
nix flake check
```
This command helps ensure that your system configuration is correct and free from errors.
!!! Tip
You can integrate this step into your [Continuous Integration](https://en.wikipedia.org/wiki/Continuous_integration) workflow to ensure that only valid Nix configurations are merged into your codebase.
## What's next?
- [Deployment](deploy.md): How to remotely deploy your machine
- Full [Secrets](../manual/secrets.md) guide If you want to know more about how to save and share passwords in your clan

View File

@@ -4,13 +4,13 @@ hide:
- toc
---
# :material-home: Welcome to **Clan**'s awesome documentation
# :material-home: Welcome to **Clan**'s documentation
[Getting Started](./getting-started/index.md){ .md-button }
## What's inside
## Tutorials
This documentation is structured into the following sections
**Learning-oriented adventures with a hands-on experience.**
<div class="grid cards" markdown>
@@ -19,25 +19,69 @@ This documentation is structured into the following sections
---
Create your own clan and get everything
running in a couple of minutes.
running in minutes
[:octicons-arrow-right-24: Getting started](./getting-started/index.md)
- :material-sign-direction:{ .lg .middle } __Guides__
- :fontawesome-solid-user-group:{ .lg .middle } __Authoring Modules__
---
Instructions and explanations for practical Implementations ordered by Topic.
Create clanModules that can be reused by the community.
[:octicons-arrow-right-24: Authoring clanModules](./clanmodules/index.md)
</div>
## :material-book: Guides
**How-to Guides for achieving a certain goal or solving a specific issue.**
<div class="grid cards" markdown>
- [Autoincludes](./manual/adding-machines.md)
---
Learn how Clan automatically includes machines and Nix files.
- [Vars Backend](./manual/vars-backend.md)
---
Learn how to manage secrets with facts.
- [Inventory](./manual/inventory.md)
---
Clan's declaration format for running **services** on one or multiple **machines**.
- [Flake-parts](./manual/flake-parts.md)
---
Use clan with [https://flake.parts/]()
- [Contribute](./contributing/contribute.md)
---
Discover how to set up a development environment to contribute to Clan!
</div>
## API Reference
**Reference API Documentation**
<div class="grid cards" markdown>
- [Reference Overview](./reference/index.md)
---
Learn how to interface with Clan programmatically
[:octicons-arrow-right-24: Guides](./manual/index.md)
- :material-api:{ .lg .middle } __Reference__
---
Detailed Specification of Functions and APIs.
[:octicons-arrow-right-24: Reference](./reference/index.md)
</div>

View File

@@ -1,4 +1,3 @@
# Adding Machines
Clan has two general methods of adding machines:
@@ -18,6 +17,8 @@ Every folder `machines/{machineName}` will be registered automatically as a Clan
- [x] `machines/{machineName}/facter.json` Automatically configured, for further information see [nixos-facter](https://clan.lol/blog/nixos-facter/)
- [x] `machines/{machineName}/disko.nix` Automatically loaded, for further information see the [disko docs](https://github.com/nix-community/disko/blob/master/docs/quickstart.md).
## Manual declaration
Machines can also be added manually under `buildClan`, `clan.*` in flake-parts or via [`inventory`](../manual/inventory.md).

View File

@@ -1,5 +1,3 @@
# Disk Templates
!!! Danger ":fontawesome-solid-road-barrier: Under Construction :fontawesome-solid-road-barrier:"
Currently under construction use with caution

View File

@@ -1,4 +1,3 @@
# Clan with `flake-parts`
Clan supports integration with [flake.parts](https://flake.parts/) a tool which allows composing nixos modules in a modular way.

View File

@@ -1,66 +0,0 @@
# :material-book: Guides
Instructions and explanations for practical Implementations ordered by Topics.
## Tutorials
**Learning-oriented adventures with a hands-on experience.**
<div class="grid cards" markdown>
- :material-clock-fast:{ .lg .middle } __Set up in 15 minutes__
---
Create your own clan and get everything
running in minutes
[:octicons-arrow-right-24: Getting started](../getting-started/index.md)
- :fontawesome-solid-user-group:{ .lg .middle } __Authoring Modules__
---
Create clanModules that can be reused by the community.
[:octicons-arrow-right-24: Authoring clanModules](../clanmodules/index.md)
</div>
## Guides
**How-to Guides for achieving a certain goal or solving a specific issue.**
<div class="grid cards" markdown>
- [Machines](./adding-machines.md)
---
Learn how Clan automatically includes machines and Nix files.
- [Secrets](./secrets.md)
---
Learn how to manage secrets.
- [Inventory](./inventory.md)
---
Clan's declaration format for running **services** on one or multiple **machines**.
- [Flake-parts](./flake-parts.md)
---
Use clan with [https://flake-parts.dev]()
- [Contribute](./contribute.md)
---
Discover how to set up a development environment to contribute to Clan!
</div>

View File

@@ -1,10 +1,15 @@
# Inventory
`Inventory` is an abstract service layer for consistently configuring distributed services across machine boundaries.
See [Inventory API Documentation](../reference/nix-api/inventory.md)
## Concept
This guide will walk you through setting up a backup service, where the inventory becomes useful.
Its concept is slightly different to what NixOS veterans might be used to. The inventory is a service definition on a higher level, not a machine configuration. This allows you to define a consistent and coherent service.
The inventory logic will automatically derive the modules and configurations to enable on each machine in your `clan` based on its `role`. This makes it super easy to setup distributed `services` such as Backups, Networking, traditional cloud services, or peer-to-peer based applications.
The following tutorial will walk through setting up a Backup service where the terms `Service` and `Role` will become more clear.
See also: [Inventory API Documentation](../reference/nix-api/inventory.md)
!!! example "Experimental status"
The inventory implementation is not considered stable yet.
@@ -18,17 +23,13 @@ This guide will walk you through setting up a backup service, where the inventor
## Services
The inventory defines `services`. Membership of `machines` is defined via roles exclusively.
The inventory defines `services`. Membership of `machines` is defined via `roles` exclusively.
See the each [module documentation](../reference/clanModules/index.md) for available roles.
!!! Note
It is possible to use any [clanModule](../reference/clanModules/index.md) in the inventory and add machines via
`roles.default.*`
See each [modules documentation](../reference/clanModules/index.md) for its available roles.
### Adding services to machines
A module can be added to one or multiple machines via `Roles`. clan's `Role` interface provide sane defaults for a module this allows the module author to reduce the configuration overhead to a minimum.
A service can be added to one or multiple machines via `Roles`. clan's `Role` interface provide sane defaults for a module this allows the module author to reduce the configuration overhead to a minimum.
Each service can still be customized and configured according to the modules options.

View File

@@ -0,0 +1,171 @@
# Migrate existing NixOS configurations
This guide will help you migrate your existing Nix configurations into Clan.
!!! Warning
Migrating instead of starting new can be trickier and might lead to bugs or
unexpected issues. We recommend following the [Getting Started](../getting-started/index.md) guide first. Once you have a working setup, you can easily transfer your Nix configurations over.
## Back up your existing configuration!
Before you start, it is strongly recommended to back up your existing
configuration in any form you see fit. If you use version control to manage
your configuration changes, it is also a good idea to follow the migration
guide in a separte branch until everything works as expected.
## Starting Point
We assume you are already using NixOS flakes to manage your configuration. If
not, migrate to a flake-based setup following the official [NixOS
documentation](https://nix.dev/manual/nix/2.25/command-ref/new-cli/nix3-flake.html).
The snippet below shows a common Nix flake. For this example we will assume you
have have two hosts: **berlin** and **cologne**.
```nix
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs, ... }: {
nixosConfigurations = {
berlin = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [./machines/berlin/configuration.nix];
};
cologne = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [./machines/cologne/configuration.nix];
};
};
};
}
```
## Add clan-core Input
Add `clan-core` to your flake as input. It will provide everything we need to
manage your configurations with clan.
```nix
inputs.clan-core = {
url = "git+https://git.clan.lol/clan/clan-core";
# Don't do this if your machines are on nixpkgs stable.
inputs.nixpkgs.follows = "nixpkgs";
};
```
## Update Outputs
To be able to access our newly added dependency, it has to be added to the
output parameters.
```diff
- outputs = { self, nixpkgs, ... }:
+ outputs = { self, nixpkgs, clan-core }:
```
The existing `nixosConfigurations` output of your flake will be created by
clan. In addition, a new `clanInternals` output will be added. Since both of
these are provided by the output of `lib.buildClan`, a common syntax is to use a
`let...in` statement to create your clan and access it's parameters in the flake
outputs.
For the provide flake example, your flake should now look like this:
```nix
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs, ... }:
let
clan = clan-core.lib.buildClan {
self = self; # this needs to point at the repository root
specialArgs = {};
inventory.meta.name = "NEEDS_TO_BE_UNIQUE"; # TODO: Changeme
machines = {
berlin = {
nixpkgs.hostPlatform = "x86_64-linux";
imports = [ ./machines/berlin/configuration.nix ];
};
cologne = {
nixpkgs.hostPlatform = "x86_64-linux";
imports = [ ./machines/cologne/configuration.nix ];
};
};
};
in
{
nixosConfigurations = clan.nixosConfigurations;
inherit (clan) clanInternals;
};
}
```
Et voilà! Your existing hosts are now part of a clan. Existing Nix tooling
should still work as normal. To check that you didn't make any errors, run `nix
flake show` and verify both hosts are still recognized as if nothing had
changed. You should also see the new `clanInternals` output.
```
nix flake show
git+file:///my-nixos-config
├───clanInternals: unknown
└───nixosConfigurations
├───berlin: NixOS configuration
└───cologne: NixOS configuration
```
Of course you can also rebuild your configuration using `nixos-rebuild` and
veryify everything still works.
## Add Clan CLI devShell
At this point Clan is set up, but you can't use the CLI yet. To do so, it is
recommended to expose it via a `devShell` in your flake. It is also possible to
install it any other way you would install a package in Nix, but using a
developtment shell ensures the CLI's version will always be in sync with your
configuration.
A minimal example is provided below, add it to your flake outputs.
```nix
devShells."x86_64-linux".default = nixpkgs.legacyPackages."x86_64-linux".mkShell {
packages = [ clan-core.packages."x86_64-linux".clan-cli ];
};
```
To use the CLI, execute `nix develop` in the directory of your flake. The
resulting shell, provides you with the `clan` CLI tool. Since you will be using
it every time you interact with Clan, it is recommended to set up
[direnv](https://direnv.net/).
Verify everything works as expected by running `clan machines list`.
```
nix develop
[user@host:~/my-nixos-config]$ clan machines list
berlin
cologne
```
## Specify Targets
Clan needs to know where it can reach your hosts. For each of your hosts, set
`clan.core.networking.targetHost` to its adress or hostname.
```nix
# machines/berlin/configuration.nix
{
clan.core.networking.targetHost = "123.4.56.78";
}
```
## Next Steps
You are now fully set up. Use the CLI to manage your hosts or proceed to
configure further services. At this point you should be able to run commands
like `clan machines update berlin` to deploy a host.

View File

@@ -0,0 +1,20 @@
This guide will help you navigate the codebase and locate key files:
```bash
$ tree -L 1
.
├── checks # Contains NixOS and VM tests
├── clanModules # Clan modules available for end-user import
├── docs # Source files for docs.clan.lol, generated with MkDocs
├── flakeModules
├── lib # User-exposed Clan Nix functions like buildClan and inventory
├── machines
├── nixosModules # Internal Clan Nix functions, e.g., clanCore
├── pkgs # Clan applications and packaged dependencies
├── formatter.nix # Configuration for nix-treefmt, manages `nix fmt`
├── scripts
├── sops
├── templates # Template files for creating a new Clan
└── vars
```

View File

@@ -0,0 +1,151 @@
!!! Note
Vars is the new secret backend that will soon replace the Facts backend
Defining a linux user's password via the nixos configuration previously required running `mkpasswd ...` and then copying the hash back into the nix configuration.
In this example, we will guide you through automating that interaction using clan `vars`.
For a more general explanation of what clan vars are and how it works, see the intro of the [Reference Documentation for vars](https://docs.clan.lol/reference/clan-core/vars/)
This guide assumes
- clan is set up already (see [Getting Started](../getting-started/index.md))
- a machine has been added to the clan (see [Adding Machines](./adding-machines.md))
This section will walk you through the following steps:
1. declare a `generator` in the machine's nixos configuration
2. inspect the status via the clan cli
3. generate the vars
4. observer the changes
5. update the machine
6. share the root password between machines
7. change the password
## Declare the generator
In this example, a `vars` `generator` is used to:
- prompt the user for the password
- run the required `mkpasswd` command to generate the hash
- store the hash in a file
- expose the file path to the nixos configuration
Create a new nix file `root-password.nix` with the following content and import it into your `configuration.nix`
```nix
{config, pkgs, ...}: {
clan.core.vars.generators.root-password = {
# prompt the user for a password
# (`password-input` being an arbitrary name)
prompts.password-input.description = "the root user's password";
prompts.password-input.type = "hidden";
# don't store the prompted password itself
prompts.password-input.persist = false;
# define an output file for storing the hash
files.password-hash.secret = false;
# define the logic for generating the hash
script = ''
cat $prompts/password-input | mkpasswd -m sha-512 > $out/password-hash
'';
# the tools required by the script
runtimeInputs = [ pkgs.mkpasswd ];
};
# ensure users are immutable (otherwise the following config might be ignored)
users.mutableUsers = false;
# set the root password to the file containing the hash
users.users.root.hashedPasswordFile =
# clan will make sure, this path exists
config.clan.core.vars.generators.root-password.files.password-hash.path;
}
```
## Inspect the status
Executing `clan vars list`, you should see the following:
```shellSession
$ clan vars list my_machine
root-password/password-hash: <not set>
```
...indicating that the value `password-hash` for the generator `root-password` is not set yet.
## Generate the values
This step is not strictly necessary, as deploying the machine via `clan machines update` would trigger the generator as well.
To run the generator, execute `clan vars generate` for your machine
```shellSession
$ clan vars generate my_machine
Enter the value for root-password/password-input (hidden):
```
After entering the value, the updated status is reported:
```shellSession
Updated var root-password/password-hash
old: <not set>
new: $6$RMats/YMeypFtcYX$DUi...
```
## Observe the changes
With the last step, a new file was created in your repository:
`vars/per-machine/my-machine/root-password/password-hash/value`
If the repository is a git repository, a commit was created automatically:
```shellSession
$ git log -n1
commit ... (HEAD -> master)
Author: ...
Date: ...
Update vars via generator root-password for machine grmpf-nix
```
## Update the machine
```shell
clan machines update my_machine
```
## Share root password between machines
If we just imported the `root-password.nix` from above into more machines, clan would ask for a new password for each additional machine.
If the root password instead should only be entered once and shared across all machines, the generator defined above needs to be declared as `shared`, by adding `share = true` to it:
```nix
{config, pkgs, ...}: {
clan.vars.generators.root-password = {
share = true;
# ...
}
}
```
Importing that shared generator into each machine, will ensure that the password is only asked once the first machine gets updated and then re-used for all subsequent machines.
## Change the root password
Changing the password can be done via this command.
Replace `my-machine` with your machine.
If the password is shared, just pick any machine that has the generator declared.
```shellSession
$ clan vars generate my-machine --generator root-password --regenerate
...
Enter the value for root-password/password-input (hidden):
Input received. Processing...
...
Updated var root-password/password-hash
old: $6$tb27m6EOdff.X9TM$19N...
new: $6$OyoQtDVzeemgh8EQ$zRK...
```
## Further Reading
- [Reference Documentation for `clan.core.vars` nixos options](../reference/clan-core/vars.md)
- [Reference Documentation for the `clan vars` cli command](../reference/cli/vars.md)

View File

@@ -1 +0,0 @@
/nix/store/8y5h98wk5p94mv1wyb2c4gkrr7bswd19-asciinema-player.css

View File

@@ -1 +0,0 @@
/nix/store/w0i3f9qzn9n6jmfnfgiw5wnab2f9ssdw-asciinema-player.min.js

View File

@@ -15,3 +15,8 @@
.md-header img {
filter: invert(100%) brightness(100%);
}
.md-nav__title,
.md-nav__item.md-nav__item--section > label > span {
color: var(--md-typeset-a-color);
}

47
flake.lock generated
View File

@@ -7,11 +7,11 @@
]
},
"locked": {
"lastModified": 1735468753,
"narHash": "sha256-2dt1nOe9zf9pDkf5Kn7FUFyPRo581s0n90jxYXJ94l0=",
"lastModified": 1741786315,
"narHash": "sha256-VT65AE2syHVj6v/DGB496bqBnu1PXrrzwlw07/Zpllc=",
"owner": "nix-community",
"repo": "disko",
"rev": "84a5b93637cc16cbfcc61b6e1684d626df61eb21",
"rev": "0d8c6ad4a43906d14abd5c60e0ffe7b587b213de",
"type": "github"
},
"original": {
@@ -27,11 +27,11 @@
]
},
"locked": {
"lastModified": 1735774679,
"narHash": "sha256-soePLBazJk0qQdDVhdbM98vYdssfs3WFedcq+raipRI=",
"lastModified": 1741352980,
"narHash": "sha256-+u2UunDA4Cl5Fci3m7S643HzKmIDAe+fiXrLqYsR2fs=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "f2f7418ce0ab4a5309a4596161d154cfc877af66",
"rev": "f4330d22f1c5d2ba72d3d22df5597d123fdb60a9",
"type": "github"
},
"original": {
@@ -42,11 +42,11 @@
},
"nixos-facter-modules": {
"locked": {
"lastModified": 1734596637,
"narHash": "sha256-MRqwVAe3gsb88u4ME1UidmZFVCx+FEnoob0zkpO9DMY=",
"lastModified": 1738752252,
"narHash": "sha256-/nA3tDdp/2g0FBy8966ppC2WDoyXtUWaHkZWL+N3ZKc=",
"owner": "numtide",
"repo": "nixos-facter-modules",
"rev": "536472754982bf03079b4b4e0261838a760587c0",
"rev": "60f8b8f3f99667de6a493a44375e5506bf0c48b1",
"type": "github"
},
"original": {
@@ -57,18 +57,15 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1734435836,
"narHash": "sha256-kMBQ5PRiFLagltK0sH+08aiNt3zGERC2297iB6vrvlU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "4989a246d7a390a859852baddb1013f825435cee",
"type": "github"
"lastModified": 315532800,
"narHash": "sha256-+bxPXRQiQ0SsjR8syBcc8X+S8WGllNM+Qreu5Td7gnI=",
"rev": "1750f3c1c89488e2ffdd47cab9d05454dddfb734",
"type": "tarball",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-25.05pre773343.1750f3c1c894/nixexprs.tar.xz"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
"type": "tarball",
"url": "https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz"
}
},
"root": {
@@ -89,11 +86,11 @@
]
},
"locked": {
"lastModified": 1736064798,
"narHash": "sha256-xJRN0FmX9QJ6+w8eIIIxzBU1AyQcLKJ1M/Gp6lnSD20=",
"lastModified": 1742700801,
"narHash": "sha256-ZGlpUDsuBdeZeTNgoMv+aw0ByXT2J3wkYw9kJwkAS4M=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "5dc08f9cc77f03b43aacffdfbc8316807773c930",
"rev": "67566fe68a8bed2a7b1175fdfb0697ed22ae8852",
"type": "github"
},
"original": {
@@ -124,11 +121,11 @@
]
},
"locked": {
"lastModified": 1736115332,
"narHash": "sha256-FBG9d7e0BTFfxVdw4b5EmNll2Mv7hfRc54hbB4LrKko=",
"lastModified": 1742982148,
"narHash": "sha256-aRA6LSxjlbMI6MmMzi/M5WH/ynd8pK+vACD9za3MKLQ=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "1788ca5acd4b542b923d4757d4cfe4183cc6a92d",
"rev": "61c88349bf6dff49fa52d7dfc39b21026c2a8881",
"type": "github"
},
"original": {

View File

@@ -2,7 +2,7 @@
description = "clan.lol base operating system";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
nixpkgs.url = "https://nixos.org/channels/nixpkgs-unstable/nixexprs.tar.xz";
flake-parts.url = "github:hercules-ci/flake-parts";
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
@@ -24,36 +24,50 @@
outputs =
inputs@{
flake-parts,
nixpkgs,
self,
systems,
...
}:
let
inherit (nixpkgs.lib)
filter
optional
pathExists
;
in
flake-parts.lib.mkFlake { inherit inputs; } (
{ ... }:
{
clan = {
meta.name = "clan-core";
directory = self;
};
systems = import systems;
imports = [
./checks/flake-module.nix
./clanModules/flake-module.nix
./flakeModules/flake-module.nix
(import ./flakeModules/clan.nix inputs.self)
./devShell.nix
# TODO: migrate this @davHau
# ./docs/flake-module
./docs/nix/flake-module.nix
./lib/flake-module.nix
./nixosModules/flake-module.nix
./nixosModules/clanCore/vars/flake-module.nix
./pkgs/flake-module.nix
./templates/flake-module.nix
imports =
# only importing existing paths allows to minimize the flake for test
# by removing files
filter pathExists [
./checks/flake-module.nix
./clanModules/flake-module.nix
./devShell.nix
./docs/nix/flake-module.nix
./flakeModules/flake-module.nix
./flakeModules/demo_iso.nix
./lib/filter-clan-core/flake-module.nix
./lib/flake-module.nix
./nixosModules/clanCore/vars/flake-module.nix
./nixosModules/flake-module.nix
./pkgs/flake-module.nix
./templates/flake-module.nix
]
++ [
(if pathExists ./flakeModules/clan.nix then import ./flakeModules/clan.nix inputs.self else { })
]
# Make treefmt-nix optional
# This only works if you set inputs.clan-core.inputs.treefmt-nix.follows
# to a non-empty input that doesn't export a flakeModule
] ++ inputs.nixpkgs.lib.optional (inputs.treefmt-nix ? flakeModule) ./formatter.nix;
++ optional (pathExists ./formatter.nix && inputs.treefmt-nix ? flakeModule) ./formatter.nix;
}
);
}

View File

@@ -27,9 +27,13 @@ in
};
options.flake = flake-parts-lib.mkSubmoduleOptions {
clan = lib.mkOption { type = types.raw; };
clanInternals = lib.mkOption { type = types.raw; };
};
config = {
flake.clan = {
inherit (config.clan.clanInternals) templates;
};
flake.clanInternals = config.clan.clanInternals;
flake.nixosConfigurations = config.clan.nixosConfigurations;
};

101
flakeModules/demo_iso.nix Normal file
View File

@@ -0,0 +1,101 @@
{ self, ... }:
let
pkgs = self.inputs.nixpkgs.legacyPackages.x86_64-linux;
demoModule = {
imports = [
"${self.clanModules.mycelium}/roles/peer.nix"
# TODO do we need this? maybe not
(
{ modulesPath, ... }:
{
imports = [ "${modulesPath}/installer/cd-dvd/iso-image.nix" ];
}
)
];
};
clan_welcome = pkgs.writeShellApplication {
name = "clan_welcome";
runtimeInputs = [
pkgs.gum
pkgs.gitMinimal
pkgs.retry
self.packages.${pkgs.system}.clan-cli
];
text = ''
set -efu
gum confirm '
Welcome to Clan, a NixOS-based operating system for the CLAN project.
This installer can be used to try out clan on your machine, for that reason we setup a cooperative environment to play and hack together :)
' || exit 1
until retry -t 5 ping -c 1 -W 1 git.clan.lol &> /dev/null; do
# TODO make this nicer
nmtui
done
if ! test -e ~/clan-core; then
# git clone https://git.clan.lol/clan/clan-core.git ~/clan-core
cp -rv ${self} clan-core
fi
cd clan-core
clan machines morph demo-template --i-will-be-fired-for-using-this
exit
'';
};
morphModule = {
imports = [
(
{ modulesPath, ... }:
{
imports = [ "${modulesPath}/image/images.nix" ];
}
)
];
image.modules.iso.isoImage.squashfsCompression = "zstd -Xcompression-level 1";
networking.networkmanager.enable = true;
services.getty.autologinUser = "root";
programs.bash.interactiveShellInit = ''
if [[ "$(tty)" =~ /dev/(tty1|hvc0|ttyS0)$ ]]; then
# workaround for https://github.com/NixOS/nixpkgs/issues/219239
systemctl restart systemd-vconsole-setup.service
reset
${clan_welcome}/bin/clan_welcome
fi
'';
};
in
{
clan.templates.machine.demo-template = {
description = "Demo machine for the CLAN project";
# path = pkgs.runCommand "demo-template" {} ''
# mkdir -p $out
# echo '{ self, ... }: { imports = [ self.nixosModules.demoModule ]; }' > $out/configuration.nix
# '';
path = ./demo_template;
};
flake.nixosModules = { inherit morphModule demoModule; };
perSystem =
{ system, lib, ... }:
{
packages =
lib.mkIf
(lib.any (x: x == system) [
"x86_64-linux"
"aarch64-linux"
])
{
demo-iso =
(self.inputs.nixpkgs.lib.nixosSystem {
modules = [
{ nixpkgs.hostPlatform = system; }
morphModule
];
}).config.system.build.images.iso;
};
};
}

View File

@@ -0,0 +1,38 @@
{ pkgs, config, ... }:
{
fileSystems."/".device = "nodev";
boot.loader.grub.device = "nodev";
clan.core.vars.settings.secretStore = "fs";
clan.core.vars.generators.mycelium = {
files."key" = { };
files."ip".secret = false;
files."pubkey".secret = false;
runtimeInputs = [
pkgs.mycelium
pkgs.coreutils
pkgs.jq
];
script = ''
timeout 5 mycelium --key-file "$out"/key || :
mycelium inspect --key-file "$out"/key --json | jq -r .publicKey > "$out"/pubkey
mycelium inspect --key-file "$out"/key --json | jq -r .address > "$out"/ip
'';
};
services.mycelium = {
enable = true;
addHostedPublicNodes = true;
openFirewall = true;
keyFile = config.clan.core.vars.generators.mycelium.files.key.path;
};
services.getty.autologinUser = "root";
programs.bash.interactiveShellInit = ''
if [[ "$(tty)" =~ /dev/(tty1|hvc0|ttyS0)$ ]]; then
# workaround for https://github.com/NixOS/nixpkgs/issues/219239
systemctl restart systemd-vconsole-setup.service
reset
your mycelium IP is: $(cat /var/lib/mycelium/ip)
fi
'';
}

View File

@@ -92,13 +92,12 @@
treefmt.programs.mypy.directories =
{
"clan-cli" = {
extraPythonPackages = self'.packages.clan-cli.testDependencies;
directory = "pkgs/clan-cli";
extraPythonPackages = (self'.packages.clan-cli.devshellPyDeps pkgs.python3Packages);
};
"clan-app" = {
directory = "pkgs/clan-app";
extraPythonPackages =
(self'.packages.clan-app.externalTestDeps or [ ]) ++ self'.packages.clan-cli.testDependencies;
extraPythonPackages = (self'.packages.clan-app.devshellPyDeps pkgs.python3Packages);
extraPythonPaths = [ "../clan-cli" ];
};
}
@@ -107,8 +106,9 @@
{
"clan-vm-manager" = {
directory = "pkgs/clan-vm-manager";
extraPythonPackages =
self'.packages.clan-vm-manager.externalTestDeps ++ self'.packages.clan-cli.testDependencies;
extraPythonPackages = self'.packages.clan-vm-manager.externalTestDeps ++ [
(pkgs.python3.withPackages (ps: self'.packages.clan-cli.devshellPyDeps ps))
];
extraPythonPaths = [ "../clan-cli" ];
};
}

View File

@@ -56,7 +56,7 @@
"machines": {
"test-inventory-machine": {
"config": {
"packages": ["zed-editor"]
"packages": ["hello"]
},
"extraModules": []
}

View File

@@ -0,0 +1,23 @@
{
lib,
self,
...
}:
let
# Returns an attrset with inputs that have the attribute `clanModules`
inputsWithClanModules = lib.filterAttrs (
_name: value: builtins.hasAttr "clanModules" value
) self.inputs;
flattenedClanModules = lib.foldl' (
acc: input:
lib.mkMerge [
acc
input.clanModules
]
) { } (lib.attrValues inputsWithClanModules);
in
{
inventory.modules = flattenedClanModules;
}

View File

@@ -8,7 +8,8 @@
}:
{
## Inputs
directory, # The directory containing the machines subdirectory # allows to include machine-specific modules i.e. machines.${name} = { ... }
self ? lib.warn "Argument: 'self' must be set when using 'buildClan'." null, # Reference to the current flake
# allows to include machine-specific modules i.e. machines.${name} = { ... }
# A map from arch to pkgs, if specified this nixpkgs will be only imported once for each system.
# This improves performance, but all nipxkgs.* options will be ignored.
# deadnix: skip
@@ -23,11 +24,12 @@ let
inherit
lib
nixpkgs
specialArgs
clan-core
self
;
self = directory;
inherit specialArgs;
};
rest = builtins.removeAttrs attrs [ "specialArgs" ];
in
eval {

View File

@@ -2,8 +2,8 @@
lib,
nixpkgs,
clan-core,
specialArgs ? { },
self,
specialArgs ? { },
}:
# Returns a function that takes self, which should point to the directory of the flake
module:
@@ -14,6 +14,8 @@ module:
modules = [
./interface.nix
module
{ inherit specialArgs; }
{
inherit specialArgs;
}
];
}).config

View File

@@ -20,12 +20,11 @@ in
jsonDocs = import ./eval-docs.nix {
inherit pkgs lib;
};
in
{
legacyPackages.clan-internals-docs = jsonDocs.optionsJSON;
# Run: nix-unit --extra-experimental-features flakes --flake .#legacyPackages.x86_64-linux.evalTests
# Run: nix-unit --extra-experimental-features flakes --flake .#legacyPackages.x86_64-linux.evalTests-build-clan
legacyPackages.evalTests-build-clan = import ./tests.nix {
inherit lib;
inherit (inputs) nixpkgs;
@@ -39,7 +38,20 @@ in
nix-unit --eval-store "$HOME" \
--extra-experimental-features flakes \
${inputOverrides} \
--flake ${self}#legacyPackages.${system}.evalTests-build-clan
--flake ${
self.filter {
include = [
"flakeModules"
"inventory.json"
"lib/build-clan"
"lib/default.nix"
"lib/flake-module.nix"
"lib/inventory"
"machines"
"nixosModules"
];
}
}#legacyPackages.${system}.evalTests-build-clan
touch $out
'';

View File

@@ -8,10 +8,26 @@ let
in
{
options = {
# Required options
directory = lib.mkOption {
type = types.path;
self = lib.mkOption {
type = types.raw;
default = self;
defaultText = "Reference to the current flake";
description = ''
This is used to import external clan modules.
'';
};
directory = lib.mkOption {
type = types.coercedTo lib.types.raw (
v:
if lib.isAttrs v then
lib.warn "It appears you set 'clan.directory = self'. Instead set 'clan.self = self'. 'clan.directory' expects a path" v
else if v == null then
throw "Please set either clan.self or clan.directory"
else
builtins.toString v
) lib.types.path;
default = builtins.toString self;
defaultText = "Root directory of the flake";
description = ''
The directory containing the clan.
@@ -53,6 +69,15 @@ in
```
'';
};
templates = lib.mkOption {
type = types.submodule { imports = [ ./templates/interface.nix ]; };
default = { };
description = ''
Define Clan templates.
'';
};
inventory = lib.mkOption {
type = types.submodule { imports = [ ../inventory/build-inventory/interface.nix ]; };
description = ''
@@ -96,11 +121,11 @@ in
type = types.lazyAttrsOf types.raw;
default = { };
};
# flake.clanInternals
clanInternals = lib.mkOption {
# Hide from documentation. Exposes internals to the cli.
visible = false;
# type = types.raw;
# ClanInternals
type = types.submodule {
options = {
@@ -108,15 +133,20 @@ in
# We don't specify the type here, for better performance.
inventory = lib.mkOption { type = lib.types.raw; };
inventoryValuesPrios = lib.mkOption { type = lib.types.raw; };
# all exported clan templates from this clan
templates = lib.mkOption { type = lib.types.raw; };
# all exported clan modules from this clan
modules = lib.mkOption { type = lib.types.raw; };
# all inventory module schemas
moduleSchemas = lib.mkOption { type = lib.types.raw; };
inventoryFile = lib.mkOption { type = lib.types.raw; };
# The machine 'imports' generated by the inventory per machine
serviceConfigs = lib.mkOption { type = lib.types.raw; };
inventoryClass = lib.mkOption { type = lib.types.raw; };
# clan-core's modules
clanModules = lib.mkOption { type = lib.types.raw; };
source = lib.mkOption { type = lib.types.raw; };
meta = lib.mkOption { type = lib.types.raw; };
lib = lib.mkOption { type = lib.types.raw; };
all-machines-json = lib.mkOption { type = lib.types.raw; };
machines = lib.mkOption { type = lib.types.raw; };
machinesFunc = lib.mkOption { type = lib.types.raw; };

View File

@@ -1,3 +1,4 @@
# NixOS module
{
config,
clan-core,
@@ -41,10 +42,9 @@ let
# map from machine name to service configuration
# { ${machineName} :: Config }
serviceConfigs = (
inventoryClass = (
buildInventory {
inherit inventory;
inherit directory;
inherit inventory directory;
}
);
@@ -76,7 +76,7 @@ let
(machines.${name} or { })
# Inherit the inventory assertions ?
# { inherit (mergedInventory) assertions; }
{ imports = serviceConfigs.${name} or [ ]; }
{ imports = inventoryClass.machines.${name}.machineImports or [ ]; }
(
{
# Settings
@@ -96,12 +96,6 @@ let
networking.hostName = lib.mkDefault name;
# speeds up nix commands by using the nixpkgs from the host system (especially useful in VMs)
nix.registry.nixpkgs.to = lib.mkDefault {
type = "path";
path = lib.mkDefault nixpkgs;
};
# For vars we need to override the system so we run vars
# generators on the machine that runs `clan vars generate`. If a
# users is using the `pkgsForSystem`, we don't set
@@ -167,9 +161,11 @@ let
(builtins.fromJSON (builtins.readFile inventoryFile))
else
{ };
in
{
imports = [
./auto-imports.nix
# Merge the inventory file
{
inventory = _: {
@@ -181,7 +177,7 @@ in
{
inventory.machines = lib.optionalAttrs (builtins.pathExists "${directory}/machines") (
builtins.mapAttrs (_n: _v: { }) (
(lib.filterAttrs (_: t: t == "directory") (builtins.readDir "${directory}/machines"))
lib.filterAttrs (_: t: t == "directory") (builtins.readDir "${directory}/machines")
)
);
}
@@ -189,7 +185,9 @@ in
inventory.machines = lib.mapAttrs (_n: _: { }) config.machines;
}
# Merge the meta attributes from the buildClan function
{ inventory.modules = clan-core.clanModules; }
{
inventory.modules = clan-core.clanModules;
}
# config.inventory.meta <- config.meta
{ inventory.meta = config.meta; }
# Set default for computed tags
@@ -200,7 +198,7 @@ in
clanInternals = {
moduleSchemas = clan-core.lib.modules.getModulesSchema config.inventory.modules;
inherit serviceConfigs;
inherit inventoryClass;
inherit (clan-core) clanModules;
inherit inventoryFile;
inventoryValuesPrios =
@@ -208,8 +206,14 @@ in
builtins.removeAttrs (clan-core.lib.values.getPrios { options = inventory.options; })
# tags are freeformType which is not supported yet.
[ "tags" ];
modules = config.modules;
templates = config.templates;
inventory = config.inventory;
meta = config.inventory.meta;
lib = {
inherit (clan-core.lib) select;
};
source = "${clan-core}";

View File

@@ -0,0 +1,57 @@
{
lib,
...
}:
let
inherit (lib) types;
templateType = types.submodule (
{ name, ... }:
{
options.description = lib.mkOption {
type = types.str;
default = name;
description = ''
The name of the template.
'';
};
options.path = lib.mkOption {
type = types.path;
description = ''
Holds the path to the clan template.
'';
};
}
);
in
{
options = {
# clan.templates.clan
clan = lib.mkOption {
type = types.attrsOf templateType;
default = { };
description = ''
Holds the different clan templates.
'';
};
# clan.templates.disko
disko = lib.mkOption {
type = types.attrsOf templateType;
default = { };
description = ''
Holds different disko templates.
'';
};
# clan.templates.machine
machine = lib.mkOption {
type = types.attrsOf templateType;
default = { };
description = ''
Holds the different machine templates.
'';
};
};
}

View File

@@ -10,24 +10,52 @@ let
inherit lib nixpkgs clan-core;
self = ./.;
};
# Shallowly force all attribute values to be evaluated.
shallowForceAllAttributes = lib.foldlAttrs (
_acc: _name: value:
lib.seq value true
) true;
in
#######
{
test_only_required =
test_missing_self =
let
config = evalClan {
config = buildClan {
meta.name = "test";
imports = [ ./module.nix ];
};
in
{
expr = config.inventory ? meta;
expr = shallowForceAllAttributes config;
expectedError = {
type = "ThrownError";
msg = "A definition for option `directory' is not of type `absolute path*";
};
};
test_only_required =
let
config = evalClan {
self = {
inputs = { };
outPath = ./.;
};
meta.name = "test";
imports = [ ./module.nix ];
};
in
{
expr = shallowForceAllAttributes config;
expected = true;
};
test_all_simple =
let
config = evalClan {
self = {
inputs = { };
};
directory = ./.;
machines = { };
inventory = {
@@ -43,6 +71,10 @@ in
test_outputs_clanInternals =
let
config = evalClan {
self = {
inputs = { };
};
directory = ./.;
imports = [
# What the user needs to specif
{
@@ -68,6 +100,9 @@ in
test_fn_simple =
let
result = buildClan {
self = {
inputs = { };
};
directory = ./.;
meta.name = "test";
};
@@ -84,6 +119,9 @@ in
test_fn_extensiv_meta =
let
result = buildClan {
self = {
inputs = { };
};
directory = ./.;
meta.name = "test";
meta.description = "test";
@@ -104,6 +142,9 @@ in
test_fn_clan_core =
let
result = buildClan {
self = {
inputs = { };
};
directory = ../../.;
meta.name = "test-clan-core";
};
@@ -119,6 +160,9 @@ in
test_buildClan_all_machines =
let
result = buildClan {
self = {
inputs = { };
};
directory = ./.;
meta.name = "test";
inventory.machines.machine1.meta.name = "machine1";
@@ -138,6 +182,9 @@ in
test_buildClan_specialArgs =
let
result = buildClan {
self = {
inputs = { };
};
directory = ./.;
meta.name = "test";
specialArgs.foo = "dream2nix";

View File

@@ -21,4 +21,5 @@ in
inherit lib;
self = clan-core;
};
select = import ./select.nix;
}

View File

@@ -6,11 +6,14 @@
let
baseModule = {
imports = (import (pkgs.path + "/nixos/modules/module-list.nix")) ++ [
{
nixpkgs.pkgs = pkgs;
clan.core.name = "dummy";
system.stateVersion = lib.version;
}
(
{ config, ... }:
{
nixpkgs.pkgs = pkgs;
clan.core.name = "dummy";
system.stateVersion = config.system.nixos.release;
}
)
];
};

View File

@@ -0,0 +1,18 @@
{ self, ... }:
let
nixFilter = import ./nix-filter.nix;
in
{
flake.filter =
{
include ? [ ],
exclude ? [ ],
}:
nixFilter.filter {
inherit exclude;
include = include ++ [
"flake.nix"
];
root = self;
};
}

Some files were not shown because too many files have changed in this diff Show More