difftreelog
docs prepare for delta.rocks
Some of the docs were generated by Claude Opus, but they still should be correct. Wireguard example and explanation is based on mesh example written by me:
16 files changed
README.adocdiffbeforeafterboth--- a/README.adoc
+++ b/README.adoc
@@ -125,12 +125,12 @@
};
services.gitlab = let secrets = config.secrets; in {
enable = true;
- initialRootPasswordFile = secrets.gitlab-initial-root.secretPath;
+ initialRootPasswordFile = secrets.gitlab-initial-root.secret.path;
secrets = {
- secretFile = secrets.gitlab-secret.secretPath;
- otpFile = secrets.gitlab-otp.secretPath;
- dbFile = secrets.gitlab-db.secretPath;
- jwsFile = secrets.gitlab-jws.secretPath;
+ secretFile = secrets.gitlab-secret.secret.path;
+ otpFile = secrets.gitlab-otp.secret.path;
+ dbFile = secrets.gitlab-db.secret.path;
+ jwsFile = secrets.gitlab-jws.secret.path;
};
};
}
@@ -200,7 +200,7 @@
set -eu
export OPENSSL_CONF=${openssl-conf}
# Yay, using secrets to generate secrets!
- HSM_PIN=$(cat ${config.secrets.hsm-pin.secretPath})
+ HSM_PIN=$(cat ${config.secrets.hsm-pin.secret.path})
exec ${pkgs.openssl}/bin/openssl "$@" -keyform=engine -CAkeyform=engine -engine=pkcs11 -passin=pass:"$HSM_PIN"
'';
})
@@ -208,7 +208,7 @@
name = "hsmt";
text = ''
set -eu
- HSM_PIN=$(cat ${config.secrets.hsm-pin.secretPath})
+ HSM_PIN=$(cat ${config.secrets.hsm-pin.secret.path})
exec ${pkgs.opensc}/bin/pkcs11-tool -l --pin="$HSM_PIN" "$@"
'';
})
docs/examples/_section.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/examples/_section.adoc
@@ -0,0 +1,2 @@
+= Examples
+:order: 2
docs/examples/wireguard.adocdiffbeforeafterbothno changes
docs/features/_section.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/features/_section.adoc
@@ -0,0 +1,2 @@
+= Features
+:order: 1
docs/features/modules.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/features/modules.adoc
@@ -0,0 +1,51 @@
+= Multi-host Modules
+:order: 0
+
+Fleet modules configure multiple hosts simultaneously. Unlike standard NixOS modules which configure a single machine, fleet modules have access to all hosts in the cluster.
+
+== Basic Module
+
+[source,nix]
+----
+# wireguard/default.nix
+{ config, ... }: {
+ hosts = builtins.mapAttrs (name: host: {
+ nixos.networking.wireguard.interfaces.wg0 = {
+ ips = [ host.config.wireguardIp ];
+ peers = builtins.filter (p: p.name != name)
+ (builtins.attrValues config.hosts);
+ };
+ }) config.hosts;
+}
+----
+
+== Using Modules
+
+Modules are imported in the `fleetConfigurations` block:
+
+[source,nix]
+----
+fleetConfigurations.default = {
+ imports = [
+ ./wireguard
+ ./monitoring
+ ];
+
+ hosts.node-1 = { ... };
+ hosts.node-2 = { ... };
+};
+----
+
+== Multi-instance Modules
+
+Modules can be parameterized and imported multiple times:
+
+[source,nix]
+----
+fleetConfigurations.default = {
+ imports = [
+ (import ./kubernetes { hosts = ["cp-1" "cp-2"]; })
+ (import ./kubernetes { hosts = ["cp-3" "cp-4"]; })
+ ];
+};
+----
docs/features/rollback.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/features/rollback.adoc
@@ -0,0 +1,29 @@
+
+= Automatic Rollback
+:order: 2
+
+Fleet automatically rolls back deployments that fail, preventing bricked machines.
+
+== How It Works
+
+When deploying a new system configuration:
+
+1. Fleet activates the new configuration
+2. A health check verifies the system booted successfully
+3. If the check fails, the previous configuration is restored
+
+Rollback works as long as the system passes the initrd stage. Be careful with changes to root filesystem mounts — those are harder to recover from.
+
+== Deployment Process
+
+[source,shell]
+----
+# Deploy to all hosts
+fleet deploy
+
+# Deploy to specific host
+fleet deploy web-1
+
+# Deploy without rollback (not recommended)
+fleet deploy --no-rollback
+----
docs/features/secrets.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/features/secrets.adoc
@@ -0,0 +1,30 @@
+= Fleet Secrets Management System
+:order: 1
+
+== Overview
+
+Secret management system is a built-in way to deploy secrets to remote hosts, similar to agenix and other systems.
+
+Secrets are encrypted using system's host ssh key (/etc/ssh/ssh_host_ed25519_key), which is not required to build the
+remote system/add secret to fleet configuration, fleet users are encrypting secrets using received public key instead,
+they don't need the root access to receive the public encryption key.
+
+== Example
+
+[source,nix]
+----
+{
+ secrets = {
+ "my-secret" = {
+ expectedOwners = [ "host1" "host2" ];
+ regenerateOnOwnerAdded = true;
+ generator = {mkImpureSecretGenerator}:
+ mkImpureSecretGenerator {
+ script = ''
+ echo "secret content" | gh private -o $out/secret
+ '';
+ };
+ };
+ }
+}
+----
docs/getting-started/_section.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/getting-started/_section.adoc
@@ -0,0 +1,2 @@
+= Getting Started
+:order: 0
docs/getting-started/hosts.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/getting-started/hosts.adoc
@@ -0,0 +1,58 @@
+
+= Configuring Hosts
+:order: 1
+
+Each host in a fleet configuration represents a machine in your cluster.
+
+== Defining Hosts
+
+[source,nix]
+----
+fleetConfigurations.default = {
+ hosts.web-1 = {
+ system = "x86_64-linux";
+ nixos = {
+ imports = [
+ ./web-1/hardware-configuration.nix
+ ./web-1/configuration.nix
+ ];
+ };
+ };
+
+ hosts.web-2 = {
+ system = "x86_64-linux";
+ nixos = {
+ imports = [
+ ./web-2/hardware-configuration.nix
+ ./web-2/configuration.nix
+ ];
+ };
+ };
+};
+----
+
+== Host Systems
+
+Every host must specify a `system` attribute. Supported systems:
+
+- `x86_64-linux`
+- `aarch64-linux`
+- `armv7l-linux`
+- `armv6l-linux`
+
+== Inline NixOS Configuration
+
+NixOS configuration can be specified inline:
+
+[source,nix]
+----
+hosts.monitoring = {
+ system = "x86_64-linux";
+ nixos = {
+ imports = [ ./monitoring/hardware-configuration.nix ];
+ services.prometheus.enable = true;
+ services.grafana.enable = true;
+ networking.firewall.allowedTCPPorts = [ 3000 9090 ];
+ };
+};
+----
docs/getting-started/index.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/getting-started/index.adoc
@@ -0,0 +1,77 @@
+
+= Fleet
+:order: 0
+
+An NixOS cluster deployment tool.
+
+== Advantages over existing configuration systems (NixOps/Morph)
+
+- Modules can configure multiple hosts at once (i.e. for wireguard/kubernetes installation)
+- Secrets can be securely stored in Git (no one except target hosts can decrypt them), automatically regenerated, reencrypted, etc.
+- Automatic rollback on deployment failure, which will work as long as system is passing initrd stage
+
+== Flake example
+
+[source,nix]
+----
+{
+ description = "My cluster configuration";
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs";
+ fleet = {
+ url = "github:CertainLach/fleet";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ };
+ outputs = inputs:
+ inputs.flake-parts.lib.mkFlake {inherit inputs;} {
+ imports = [inputs.fleet.flakeModules.default];
+
+ fleetConfigurations.default = {
+ nixos = {
+ # Shared NixOS configuration for all hosts
+ };
+
+ imports = [
+ ./wireguard
+ ];
+
+ hosts.controlplane-1 = {
+ system = "x86_64-linux";
+ nixos = {
+ imports = [
+ ./controlplane-1/hardware-configuration.nix
+ ./controlplane-1/configuration.nix
+ ];
+ };
+ };
+ };
+ };
+}
+----
+
+== Secret generator example
+
+[source,nix]
+----
+{config, ...}: {
+ secrets = {
+ gitlab-initial-root = {
+ generator = {mkPassword}: mkPassword {};
+ owner = "gitlab";
+ group = "gitlab";
+ };
+ gitlab-secret = {
+ generator = {mkPassword}: mkPassword {};
+ owner = "gitlab";
+ group = "gitlab";
+ };
+ };
+ services.gitlab = {
+ enable = true;
+ initialRootPasswordFile = config.secrets.gitlab-initial-root.secret.path;
+ secrets.secretFile = config.secrets.gitlab-secret.secret.path;
+ };
+}
+----
docs/index.adocdiffbeforeafterboth--- a/docs/index.adoc
+++ /dev/null
@@ -1,78 +0,0 @@
-
-= Fleet
-:slug: index
-:order: 0
-
-An NixOS cluster deployment tool.
-
-== Advantages over existing configuration systems (NixOps/Morph)
-
-- Modules can configure multiple hosts at once (i.e. for wireguard/kubernetes installation)
-- Secrets can be securely stored in Git (no one except target hosts can decrypt them), automatically regenerated, reencrypted, etc.
-- Automatic rollback on deployment failure, which will work as long as system is passing initrd stage
-
-== Flake example
-
-[source,nix]
-----
-{
- description = "My cluster configuration";
- inputs = {
- nixpkgs.url = "github:nixos/nixpkgs";
- fleet = {
- url = "github:CertainLach/fleet";
- inputs.nixpkgs.follows = "nixpkgs";
- };
- flake-parts.url = "github:hercules-ci/flake-parts";
- };
- outputs = inputs:
- inputs.flake-parts.lib.mkFlake {inherit inputs;} {
- imports = [inputs.fleet.flakeModules.default];
-
- fleetConfigurations.default = {
- nixos = {
- # Shared NixOS configuration for all hosts
- };
-
- imports = [
- ./wireguard
- ];
-
- hosts.controlplane-1 = {
- system = "x86_64-linux";
- nixos = {
- imports = [
- ./controlplane-1/hardware-configuration.nix
- ./controlplane-1/configuration.nix
- ];
- };
- };
- };
- };
-}
-----
-
-== Secret generator example
-
-[source,nix]
-----
-{config, ...}: {
- secrets = {
- gitlab-initial-root = {
- generator = {mkPassword}: mkPassword {};
- owner = "gitlab";
- group = "gitlab";
- };
- gitlab-secret = {
- generator = {mkPassword}: mkPassword {};
- owner = "gitlab";
- group = "gitlab";
- };
- };
- services.gitlab = {
- enable = true;
- initialRootPasswordFile = config.secrets.gitlab-initial-root.secretPath;
- secrets.secretFile = config.secrets.gitlab-secret.secretPath;
- };
-}
-----
docs/migration.adocdiffbeforeafterboth--- a/docs/migration.adoc
+++ /dev/null
@@ -1,42 +0,0 @@
-
-= Migration Guide
-:slug: migration
-:order: 2
-
-== fleet.nix <unset> => 0.1.0
-
-Add version field::
-Set it to 0.1.0; This field specifies which version of fleet do you use for cluster management, breaking changes will also break this value to make sure you read this guide.
-
-Move every secret part::
-Before it was only public and private, now it can be any number of parts.
-
-In your fleet.nix file, look at every record like this:
-[source,nix]
-----
-gitlab-initial-root = {
- createdAt = "2024-03-01T15:54:32.983358495Z";
- public = "example";
- secret = "vp%d6wO#0#D2.../dgCA+v4Gf:YG";
-};
-----
-
-And modify it as following:
-[source,nix]
-----
-gitlab-initial-root = {
- createdAt = "2024-03-01T15:54:32.983358495Z";
- public.raw = "<PLAINTEXT>example";
- secret.raw = ''
- <ENCRYPTED><Z85-ENCODED>
- vp%d6wO#0#D2.../dgCA+v4Gf:YG
- '';
-};
-----
-
-Default encoding was also changed from `Z85` to `base64`. This conversion will be done by fleet automatically.
-
-Update references to secrets in fleet/nixos configurations::
-Instead of `config.secrets.secret-name.secretPath` use `config.secrets.secret-name.secret.path`,
-instead of `config.secrets.secret-name.stableSecretPath` use `config.secrets.secret-name.secret.stablePath`,
-instead of `config.secrets.secret-name.public` use `config.secrets.secret-name.public.data`.
docs/reference/_section.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/reference/_section.adoc
@@ -0,0 +1,2 @@
+= Reference
+:order: 2
docs/reference/migration.adocdiffbeforeafterboth--- /dev/null
+++ b/docs/reference/migration.adoc
@@ -0,0 +1,41 @@
+
+= Migration Guide
+:order: 2
+
+== fleet.nix <unset> => 0.1.0
+
+Add version field::
+Set it to 0.1.0; This field specifies which version of fleet do you use for cluster management, breaking changes will also break this value to make sure you read this guide.
+
+Move every secret part::
+Before it was only public and private, now it can be any number of parts.
+
+In your fleet.nix file, look at every record like this:
+[source,nix]
+----
+gitlab-initial-root = {
+ createdAt = "2024-03-01T15:54:32.983358495Z";
+ public = "example";
+ secret = "vp%d6wO#0#D2.../dgCA+v4Gf:YG";
+};
+----
+
+And modify it as following:
+[source,nix]
+----
+gitlab-initial-root = {
+ createdAt = "2024-03-01T15:54:32.983358495Z";
+ public.raw = "<PLAINTEXT>example";
+ secret.raw = ''
+ <ENCRYPTED><Z85-ENCODED>
+ vp%d6wO#0#D2.../dgCA+v4Gf:YG
+ '';
+};
+----
+
+Default encoding was also changed from `Z85` to `base64`. This conversion will be done by fleet automatically.
+
+Update references to secrets in fleet/nixos configurations::
+Instead of `config.secrets.secret-name.secretPath` use `config.secrets.secret-name.secret.path`,
+instead of `config.secrets.secret-name.stableSecretPath` use `config.secrets.secret-name.secret.stablePath`,
+instead of `config.secrets.secret-name.public` use `config.secrets.secret-name.public.data`.
docs/secrets.adocdiffbeforeafterboth--- a/docs/secrets.adoc
+++ /dev/null
@@ -1,37 +0,0 @@
-= Fleet Secrets Management System
-:slug: secrets
-:order: 1
-
-== Overview
-
-Secret management system is a built-in way to deploy secrets to remote systems, similar to agenix and other similar systems.
-
-Secrets are encrypted using system's host ssh key (/etc/ssh/ssh_host_ed25519_key), which is not required to build the
-remote system/add secret to fleet configuration, fleet users are encrypting secrets using received public key instead,
-they don't need the root access to receive the public encryption key.
-
-== Example
-
-[source,nix]
-----
-{
- fleet.secrets = {
- "my-secret" = {
- expectedOwners = [ "host1" "host2" ];
- regenerateOnOwnerAdded = true;
- generator = {mkImpureSecretGenerator}:
- mkImpureSecretGenerator {
- script = ''
- echo "secret content" | gh private -o $out/secret
- '';
- };
- };
- }
-}
-----
-
-== Limitations and Future Improvements
-
-- Pure secret generators are currently disabled
-- Support for other secret management systems (e.g systemd-creds has planned asymmetric encryption support)
-
lib/default.nixdiffbeforeafterboth--- a/lib/default.nix
+++ b/lib/default.nix
@@ -160,7 +160,6 @@
mkImpureSecretGenerator,
}:
mkImpureSecretGenerator {
- # TODO: Escape prompt/part (preferrably just use env) to prevent shell injection
script = ''
mkdir $out
${kdePackages.kdialog}/bin/kdialog --inputbox "${prompt}" | gh private -o $out/${part}