git.delta.rocks / fleet / refs/commits / 3ddf3ff6da5e

difftreelog

fix explicit systemctl

kzonlluxYaroslav Bolyukin2026-04-22parent: #70a291c.patch.diff

4 files changed

addeddocs/index.adocdiffbeforeafterboth
--- /dev/null
+++ b/docs/index.adoc
@@ -0,0 +1,78 @@
+
+= 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;
+  };
+}
+----
addeddocs/migration.adocdiffbeforeafterboth
--- /dev/null
+++ b/docs/migration.adoc
@@ -0,0 +1,42 @@
+
+= 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`.
modifieddocs/secrets.adocdiffbeforeafterboth
--- a/docs/secrets.adoc
+++ b/docs/secrets.adoc
@@ -1,4 +1,6 @@
 = Fleet Secrets Management System
+:slug: secrets
+:order: 1
 
 == Overview
 
modifiedmodules/nixos/online.nixdiffbeforeafterboth
before · modules/nixos/online.nix
1{2  config,3  lib,4  ...5}:6let7  inherit (lib.options) mkOption;8  inherit (lib.modules) mkIf mkDefault;9  inherit (lib.types)10    attrsOf11    str12    submodule13    either14    listOf15    lines16    bool17    ;18  inherit (lib.attrsets) mapAttrs;19  inherit (lib.trivial) isString;20in21{22  options.system.onlineActivationScripts = mkOption {23    default = { };24    type = attrsOf (25      either str (submodule {26        options = {27          deps = mkOption {28            type = listOf str;29            default = [ ];30          };31          text = mkOption {32            type = lines;33          };34          supportsDryActivation = mkOption {35            type = bool;36            default = false;37          };38        };39      })40    );41    description = ''42      Same as activation scripts, but only ran on online activation (i.e when operator is actively running fleet deploy, and not on system restart)4344      Can be used to apply configuration such as ceph monitor maps, which is required to be up-to-date to correctly function,45      we should not apply outdated ceph monmap.46    '';4748    apply =49      set:50      mapAttrs (51        name: value:52        if isString value then53          {54            text = ''55              if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then56                ${value}57              fi58            '';59            deps = [ "onlineActivation" ];60          }61        else62          value63          // {64            deps = [ "onlineActivation" ] ++ value.deps;65            text = ''66              if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then67                ${value.text}68              fi69            '';70          }71      ) set;72  };7374  config = {75    systemd.targets.online-activation = {76      description = "Online activation target for deploy-time services";77    };7879    system.activationScripts = {80      onlineActivation = {81        text = ''82          if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then83            1>&2 echo "online activation; hello, fleet!"84            systemctl start online-activation.target85          fi86        '';87        supportsDryActivation = true;88      };89    }90    // config.system.onlineActivationScripts;9192    systemd.services = mkIf config.networking.networkmanager.enable {93      # If machine is managed by fleet, we should not restart NetworkManager during activation,94      # as it will disrupt the activation process. Furthermore, NetworkManager is not declarative,95      # so even if user wants to update his network settings - disabled NetworkManager restart96      # will not affect that.97      NetworkManager.restartIfChanged = mkDefault false;98    };99  };100}
after · modules/nixos/online.nix
1{2  config,3  lib,4  ...5}:6let7  inherit (lib.options) mkOption;8  inherit (lib.modules) mkIf mkDefault;9  inherit (lib.types)10    attrsOf11    str12    submodule13    either14    listOf15    lines16    bool17    ;18  inherit (lib.attrsets) mapAttrs;19  inherit (lib.trivial) isString;20  inherit (lib.meta) getExe';21in22{23  options.system.onlineActivationScripts = mkOption {24    default = { };25    type = attrsOf (26      either str (submodule {27        options = {28          deps = mkOption {29            type = listOf str;30            default = [ ];31          };32          text = mkOption {33            type = lines;34          };35          supportsDryActivation = mkOption {36            type = bool;37            default = false;38          };39        };40      })41    );42    description = ''43      Same as activation scripts, but only ran on online activation (i.e when operator is actively running fleet deploy, and not on system restart)4445      Can be used to apply configuration such as ceph monitor maps, which is required to be up-to-date to correctly function,46      we should not apply outdated ceph monmap.47    '';4849    apply =50      set:51      mapAttrs (52        name: value:53        if isString value then54          {55            text = ''56              if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then57                ${value}58              fi59            '';60            deps = [ "onlineActivation" ];61          }62        else63          value64          // {65            deps = [ "onlineActivation" ] ++ value.deps;66            text = ''67              if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then68                ${value.text}69              fi70            '';71          }72      ) set;73  };7475  config = {76    systemd.targets.online-activation = {77      description = "Online activation target for deploy-time services";78    };7980    system.activationScripts = {81      onlineActivation = {82        text = ''83          if [ ! -z ''${FLEET_ONLINE_ACTIVATION+x} ]; then84            1>&2 echo "online activation; hello, fleet!"85            ${getExe' config.systemd.package "systemctl"} start online-activation.target86          fi87        '';88        supportsDryActivation = true;89      };90    }91    // config.system.onlineActivationScripts;9293    systemd.services = mkIf config.networking.networkmanager.enable {94      # If machine is managed by fleet, we should not restart NetworkManager during activation,95      # as it will disrupt the activation process. Furthermore, NetworkManager is not declarative,96      # so even if user wants to update his network settings - disabled NetworkManager restart97      # will not affect that.98      NetworkManager.restartIfChanged = mkDefault false;99    };100  };101}