git.delta.rocks / jrsonnet / refs/commits / d2cec5d37894

difftreelog

refactor move definitions around

Yaroslav Bolyukin2024-08-17parent: #cc4ecd6.patch.diff
in: trunk

32 files changed

modifiedflake.lockdiffbeforeafterboth
--- a/flake.lock
+++ b/flake.lock
@@ -66,28 +66,11 @@
         "url": "https://github.com/NixOS/nixpkgs/archive/5daf0514482af3f97abaefc78a6606365c9108e2.tar.gz"
       }
     },
-    "nixpkgs-stable-for-tests": {
-      "locked": {
-        "lastModified": 1721548954,
-        "narHash": "sha256-7cCC8+Tdq1+3OPyc3+gVo9dzUNkNIQfwSDJ2HSi2u3o=",
-        "owner": "nixos",
-        "repo": "nixpkgs",
-        "rev": "63d37ccd2d178d54e7fb691d7ec76000740ea24a",
-        "type": "github"
-      },
-      "original": {
-        "owner": "nixos",
-        "ref": "nixos-24.05",
-        "repo": "nixpkgs",
-        "type": "github"
-      }
-    },
     "root": {
       "inputs": {
         "crane": "crane",
         "flake-parts": "flake-parts",
         "nixpkgs": "nixpkgs",
-        "nixpkgs-stable-for-tests": "nixpkgs-stable-for-tests",
         "rust-overlay": "rust-overlay"
       }
     },
modifiedflake.nixdiffbeforeafterboth
--- a/flake.nix
+++ b/flake.nix
@@ -3,7 +3,6 @@
 
   inputs = {
     nixpkgs.url = "github:nixos/nixpkgs/master";
-    nixpkgs-stable-for-tests.url = "github:nixos/nixpkgs/nixos-24.05";
     rust-overlay = {
       url = "github:oxalica/rust-overlay";
       inputs = {
@@ -33,9 +32,9 @@
           // {
             fleetConfiguration = throw "function-based interface is deprecated, use flake-parts syntax instead";
           };
-        flakeModules.default = (import ./lib/flakePart.nix {
+        flakeModules.default = import ./lib/flakePart.nix {
           inherit crane;
-        });
+        };
         flakeModule = flakeModules.default;
 
         # To be used with https://github.com/NixOS/nix/pull/8892
@@ -92,8 +91,7 @@
         };
         # Reference fleet package should be built with nightly rust, specified in rust-toolchain.toml.
         packages = lib.mkIf deployerSystem (let
-          packages = import ./pkgs {
-            inherit (pkgs) callPackage;
+          packages = pkgs.callPackages ./pkgs {
             inherit craneLib;
           };
         in
@@ -121,14 +119,7 @@
         # fleet-install-secrets will not be built normally, because they are not ran directly by user most of the time.
         # checks there build packages for default nixpkgs rustPlatform packages.
         checks = let
-          packages = import ./pkgs {
-            inherit (pkgs) callPackage;
-            craneLib = crane.mkLib pkgs;
-          };
-          packages-with-nixpkgs-stable = import ./pkgs {
-            inherit (pkgs) callPackage;
-            craneLib = crane.mkLib (import inputs.nixpkgs-stable-for-tests {inherit system;});
-          };
+          packages = pkgs.callPackages ./pkgs {};
           prefixAttrs = prefix: attrs:
             mapAttrs' (name: value: {
               name = "${prefix}${name}";
@@ -139,8 +130,7 @@
             attrs;
         in
           # `fleet` crate wants nightly rust, also little sense of supporting it on stable nixpkgs.
-          (prefixAttrs "nixpkgs-" (removeAttrs packages ["fleet"]))
-          // (prefixAttrs "nixpkgs-stable-" (removeAttrs packages-with-nixpkgs-stable ["fleet"]));
+          (prefixAttrs "nixpkgs-" (removeAttrs packages ["fleet"]));
         formatter = pkgs.alejandra;
       };
     };
modifiedlib/default.nixdiffbeforeafterboth
--- a/lib/default.nix
+++ b/lib/default.nix
@@ -4,7 +4,7 @@
   inherit (lib.options) mkOption mergeOneOption;
   inherit (lib.modules) mkOverride;
   inherit (lib.types) listOf submodule attrsOf mkOptionType;
-  inherit (lib.strings) optionalString;
+  inherit (lib.strings) optionalString hasPrefix removePrefix;
 in rec {
   types = {
     overlay = mkOptionType {
@@ -16,6 +16,7 @@
     listOfOverlay = listOf types.overlay;
 
     mkHostsType = module: attrsOf (submodule module);
+    mkDataType = module: submodule module;
   };
 
   options = {
@@ -23,6 +24,10 @@
       mkOption {
         type = types.mkHostsType module;
       };
+    mkDataOption = module:
+      mkOption {
+        type = types.mkDataType module;
+      };
   };
 
   inherit (options) mkHostsOption;
@@ -118,4 +123,18 @@
   };
 
   inherit (secrets) mkPassword mkEd25519 mkX25519 mkRsa mkBytes mkHexBytes mkBase64Bytes;
+
+  strings = let
+    plaintextPrefix = "<PLAINTEXT>";
+    plaintextNewlinePrefix = "<PLAINTEXT-NL>";
+  in {
+    decodeRawSecret = raw:
+      if hasPrefix plaintextPrefix raw
+      then removePrefix plaintextPrefix raw
+      else if hasPrefix plaintextNewlinePrefix raw
+      then removePrefix plaintextNewlinePrefix raw
+      else throw "decodeRawSecret only works with plaintext-encoded secret public parts, got ${raw}";
+  };
+
+  inherit (strings) decodeRawSecret;
 }
modifiedlib/flakePart.nixdiffbeforeafterboth
--- a/lib/flakePart.nix
+++ b/lib/flakePart.nix
@@ -7,6 +7,7 @@
   inherit (lib.options) mkOption;
   inherit (lib.attrsets) mapAttrs;
   inherit (lib.types) lazyAttrsOf deferredModule unspecified;
+  inherit (lib.strings) isPath;
   inherit (fleetLib.options) mkHostsOption;
 in {
   options.fleetModules = mkOption {
@@ -36,19 +37,25 @@
           bootstrapNixpkgs = bootstrapEval.config.nixpkgs.buildUsing;
           normalEval = bootstrapNixpkgs.lib.evalModules {
             modules =
-              (import ../modules/fleet/_modules.nix)
+              (import ../modules/module-list.nix)
               ++ [
-                data
                 module
                 {
                   options.hosts = mkHostsOption {
                     nixos.nixpkgs.overlays = [
-                      (final: prev: {
-                        # FIXME: make this name not conflicting
-                        craneLib = crane.mkLib prev;
-                      })
+                      (final: prev:
+                        import ../pkgs {
+                          inherit (prev) callPackage;
+                          craneLib = crane.mkLib prev;
+                        })
                     ];
                   };
+                  config = {
+                    data =
+                      if isPath data
+                      then import data
+                      else data;
+                  };
                 }
               ];
             specialArgs.fleetLib = import ../lib {
addedmodules/assertions.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/assertions.nix
@@ -0,0 +1,64 @@
+{
+  lib,
+  config,
+  ...
+}: let
+  inherit (lib.options) mkOption;
+  inherit (lib.types) listOf unspecified str;
+  inherit (lib.lists) map filter;
+
+  errors = mkOption {
+    type = listOf str;
+    internal = true;
+    description = ''
+      Similar to warnings, however build will fail if any error exists.
+    '';
+  };
+in {
+  options = {
+    assertions = mkOption {
+      type = listOf unspecified;
+      internal = true;
+      default = [];
+      example = [
+        {
+          assertion = false;
+          message = "you can't enable this for that reason";
+        }
+      ];
+      description = ''
+        This option allows modules to express conditions that must
+        hold for the evaluation of the system configuration to
+        succeed, along with associated error messages for the user.
+      '';
+    };
+
+    warnings = mkOption {
+      internal = true;
+      default = [];
+      type = listOf str;
+      example = ["The `foo' service is deprecated and will go away soon!"];
+      description = ''
+        This option allows modules to show warnings to users during
+        the evaluation of the system configuration.
+      '';
+    };
+
+    inherit errors;
+  };
+  config = {
+    errors =
+      map (v: v.message)
+      (filter (v: !v.assertion) config.assertions);
+
+    nixos = {config, ...}: {
+      _file = ./assertions.nix;
+      options = {
+        inherit errors;
+      };
+      config.errors =
+        map (v: v.message)
+        (filter (v: !v.assertion) config.assertions);
+    };
+  };
+}
deletedmodules/fleet/_modules.nixdiffbeforeafterboth
--- a/modules/fleet/_modules.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-[
-  ./assertions.nix
-  ./fleetLib.nix
-  ./hosts.nix
-  ./meta.nix
-  ./nixos.nix
-  ./nixpkgs.nix
-  ./secrets.nix
-]
deletedmodules/fleet/assertions.nixdiffbeforeafterboth
--- a/modules/fleet/assertions.nix
+++ /dev/null
@@ -1,49 +0,0 @@
-{
-  lib,
-  config,
-  ...
-}: let
-  inherit (lib.options) mkOption;
-  inherit (lib.types) listOf unspecified str;
-  inherit (lib.lists) map filter;
-in {
-  options = {
-    assertions = mkOption {
-      type = listOf unspecified;
-      internal = true;
-      default = [];
-      example = [
-        {
-          assertion = false;
-          message = "you can't enable this for that reason";
-        }
-      ];
-      description = ''
-        This option allows modules to express conditions that must
-        hold for the evaluation of the system configuration to
-        succeed, along with associated error messages for the user.
-      '';
-    };
-
-    warnings = mkOption {
-      internal = true;
-      default = [];
-      type = listOf str;
-      example = ["The `foo' service is deprecated and will go away soon!"];
-      description = ''
-        This option allows modules to show warnings to users during
-        the evaluation of the system configuration.
-      '';
-    };
-    errors = mkOption {
-      type = listOf str;
-      internal = true;
-      description = ''
-        Similar to warnings, however build will fail if any error exists.
-      '';
-    };
-  };
-  config.errors =
-    map (v: v.message)
-    (filter (v: !v.assertion) config.assertions);
-}
deletedmodules/fleet/fleetLib.nixdiffbeforeafterboth
--- a/modules/fleet/fleetLib.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  lib,
-  config,
-  ...
-}: {
-  _module.args.fleetLib = import ../../lib {
-    inherit lib;
-  };
-}
deletedmodules/fleet/hosts.nixdiffbeforeafterboth
--- a/modules/fleet/hosts.nix
+++ /dev/null
@@ -1,40 +0,0 @@
-{
-  lib,
-  fleetLib,
-  ...
-}: let
-  inherit (fleetLib.modules) mkFleetGeneratorDefault;
-  inherit (fleetLib.types) mkHostsType;
-  inherit (lib.options) mkOption;
-  inherit (lib.types) str listOf;
-in {
-  options = {
-    hosts = mkOption {
-      type = mkHostsType ({config, ...}: {
-        options = {
-          system = mkOption {
-            type = str;
-            description = "Type of the system.";
-          };
-          # TODO: This is part of fleet.nix, move it to separate toplevel data config option.
-          encryptionKey = mkOption {
-            type = str;
-            description = "Rage SSH encryption key for secrets.";
-          };
-          tags = mkOption {
-            type = listOf str;
-            description = "Host tag. In CLI, you can refer to all hosts having this tag using @tag syntax.";
-          };
-        };
-        config = {
-          nixos.networking.hostName = mkFleetGeneratorDefault config._module.args.name;
-          tags = ["all"];
-        };
-        _file = ./meta.nix;
-      });
-      default = {};
-      description = "Configurations of individual hosts";
-    };
-  };
-  _file = ./meta.nix;
-}
deletedmodules/fleet/meta.nixdiffbeforeafterboth
--- a/modules/fleet/meta.nix
+++ /dev/null
@@ -1,8 +0,0 @@
-{lib, ...}: let
-  inherit (lib.modules) mkRemovedOptionModule;
-in {
-  imports = [
-    (mkRemovedOptionModule ["fleetModules"] "replaced with imports.")
-    (mkRemovedOptionModule ["data"] "data is now provided by fleet itself, you can remove your import.")
-  ];
-}
deletedmodules/fleet/nixos.nixdiffbeforeafterboth
--- a/modules/fleet/nixos.nix
+++ /dev/null
@@ -1,55 +0,0 @@
-{
-  lib,
-  fleetLib,
-  config,
-  ...
-}: let
-  inherit (lib.attrsets) mapAttrs;
-  inherit (lib.options) mkOption;
-  inherit (lib.types) deferredModule deferredModuleWith;
-  inherit (lib.modules) mkRemovedOptionModule;
-  inherit (fleetLib.options) mkHostsOption;
-
-  _file = ./nixos.nix;
-in {
-  options = {
-    nixos = mkOption {
-      description = ''
-        Nixos configuration for all hosts.
-      '';
-      type = deferredModule;
-    };
-    hosts = mkHostsOption (hostArgs: {
-      inherit _file;
-      options = {
-        nixos = mkOption {
-          description = ''
-            Nixos configuration for the current host.
-          '';
-          type = deferredModuleWith {
-            staticModules = import ../../nixos/modules/module-list.nix;
-          };
-          apply = module:
-            config.nixpkgs.buildUsing.lib.nixosSystem {
-              inherit (hostArgs.config) system;
-              modules = [module];
-            };
-        };
-      };
-      config = {
-        # imports = [
-        #   (mkRemovedOptionModule ["nixosModules"] "replaced with hosts.*.nixos.imports.")
-        # ];
-        nixos = {
-          imports = [
-            config.nixos
-          ];
-          config._module.args.fleet = mapAttrs (_: value: value.nixos.config) config.hosts;
-        };
-      };
-    });
-  };
-  imports = [
-    (mkRemovedOptionModule ["nixosModules"] "replaced with nixos.imports.")
-  ];
-}
deletedmodules/fleet/nixpkgs.nixdiffbeforeafterboth
--- a/modules/fleet/nixpkgs.nix
+++ /dev/null
@@ -1,58 +0,0 @@
-{
-  lib,
-  fleetLib,
-  config,
-  ...
-}: let
-  inherit (lib.options) mkOption;
-  inherit (lib.types) path;
-  inherit (lib.modules) mkRemovedOptionModule;
-  inherit (fleetLib.options) mkHostsOption;
-  inherit (fleetLib.types) listOfOverlay;
-
-  _file = ./nixpkgs.lib;
-in {
-  options = {
-    nixpkgs = {
-      buildUsing = mkOption {
-        description = ''
-          Default nixpkgs to use for building the systems.
-        '';
-        type = path;
-      };
-      overlays = mkOption {
-        description = ''
-          Package overlays to apply for all the hosts, gets propagated into
-          `hosts.*.nixosModules.nixpkgs.overlays`.
-        '';
-        type = listOfOverlay;
-      };
-    };
-    hosts = mkHostsOption {
-      inherit _file;
-      options.nixpkgs.buildUsing = mkOption {
-        description = ''
-          Nixpkgs to use for building the system.
-
-          Note that this option is defined at the host level, not the nixosModules level,
-          nixosModules will be evaluated using this flake input.
-        '';
-        type = path;
-        default = config.nixpkgs.buildUsing;
-      };
-      # imports = [
-      # 	(mkRemovedOptionModule ["nixpkgs" "overlays"] "this option needs to be specified at nixosModules level")
-      # ];
-      config.nixos = {
-        inherit _file;
-        nixpkgs.overlays = config.nixpkgs.overlays;
-        imports = [
-          (mkRemovedOptionModule ["nixpkgs" "buildUsing"] "this option should be specified at the host level, not the nixosModules level")
-        ];
-      };
-    };
-  };
-  config.nixpkgs.overlays = [
-    (final: prev: import ../../pkgs {inherit (final) callPackage craneLib;})
-  ];
-}
deletedmodules/fleet/secrets.nixdiffbeforeafterboth
--- a/modules/fleet/secrets.nix
+++ /dev/null
@@ -1,210 +0,0 @@
-{
-  lib,
-  fleetLib,
-  config,
-  ...
-}: let
-  inherit (fleetLib.options) mkHostsOption;
-  inherit (lib.options) mkOption;
-  inherit (lib.types) lazyAttrsOf unspecified nullOr listOf str bool attrsOf submodule;
-  inherit (lib.lists) sort elem;
-  inherit (lib.attrsets) mapAttrsToList mapAttrs filterAttrs;
-  inherit (lib.strings) toJSON concatStringsSep;
-
-  sharedSecret = {config, ...}: {
-    freeformType = lazyAttrsOf unspecified;
-    options = {
-      expectedOwners = mkOption {
-        type = nullOr (listOf str);
-        description = ''
-          List of hosts to encrypt secret for. null if managed by user (= via owners field from fleet.nix)
-
-          Secrets would be decrypted and stored to /run/secrets/$\{name} on owners
-        '';
-        default = null;
-      };
-      # TODO: Aren't those options may be just desugared to data/expectedData?
-      regenerateOnOwnerAdded = mkOption {
-        type = bool;
-        description = ''
-          Is this secret owner-dependent, and needs to be regenerated on ownership set change, or it may be just reencrypted.
-
-          You want to have this option set to true, when this secret contains some reference to its owners, i.e x509 SANs.
-        '';
-      };
-      regenerateOnOwnerRemoved = mkOption {
-        default = config.regenerateOnOwnerAdded;
-        type = bool;
-        description = ''
-          Should this secret be removed on owner removal, or it may be just reencrypted
-
-          Most probably its value should be equal to regenerateOnOwnerAdded, override only if you know what are you doing.
-          Contrary to regenerateOnOwnerAdded, you may want to set this option to false, when host permissions are revoked
-          in some other way than by this secret ownership, I.e by firewall/etc.
-        '';
-      };
-      generator = mkOption {
-        type = nullOr unspecified;
-        description = "Derivation to evaluate for secret generation";
-        default = null;
-      };
-      createdAt = mkOption {
-        type = nullOr str;
-        description = "When this secret was (re)generated";
-        default = null;
-      };
-      expiresAt = mkOption {
-        type = nullOr str;
-        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";
-        default = null;
-      };
-
-      owners = mkOption {
-        type = listOf str;
-        description = ''
-          For which owners this secret is currently encrypted,
-          if not matches expectedOwners - then this secret is considered outdated, and
-          should be regenerated/reencrypted.
-
-          Imported from fleet.nix
-        '';
-        default = [];
-      };
-    };
-  };
-  hostSecret = {
-    freeformType = lazyAttrsOf unspecified;
-    options = {
-      createdAt = mkOption {
-        type = nullOr str;
-        default = null;
-      };
-      expiresAt = mkOption {
-        type = nullOr str;
-        default = null;
-      };
-    };
-  };
-  inherit (config) hostSecrets sharedSecrets;
-in {
-  options = {
-    version = mkOption {
-      type = str;
-      internal = true;
-    };
-    sharedSecrets = mkOption {
-      type = attrsOf (submodule sharedSecret);
-      default = {};
-      description = "Shared secrets";
-    };
-    hostSecrets = mkOption {
-      type = attrsOf (attrsOf (submodule hostSecret));
-      default = {};
-      description = "Host secrets. Imported from fleet.nix";
-      internal = true;
-    };
-    hosts = mkHostsOption ({config, ...}: {
-      nixos = {
-        secrets = let
-          host = config._module.args.name;
-          processSecret = v:
-            (removeAttrs v ["createdAt" "expiresAt" "expectedOwners" "owners" "regenerateOnOwnerAdded" "regenerateOnOwnerRemoved"])
-            // {
-              shared = true;
-            };
-        in
-          (
-            mapAttrs (_: processSecret)
-            (filterAttrs (_: v: elem host v.owners) sharedSecrets)
-          )
-          // (mapAttrs (_: processSecret) (hostSecrets.${host} or {}));
-        _file = ./secrets.nix;
-      };
-    });
-  };
-  config = {
-    assertions =
-      mapAttrsToList
-      (name: secret: {
-        assertion = secret.expectedOwners == null || sort (a: b: a < b) secret.owners == sort (a: b: a < b) secret.expectedOwners;
-        message = "Shared secret ${name} is expected to be encrypted for ${toJSON secret.expectedOwners}, but it is encrypted for ${toJSON secret.owners}. Run fleet secrets regenerate to fix";
-      })
-      config.sharedSecrets;
-    nixpkgs.overlays = [
-      (final: prev: {
-        mkSecretGenerators = {recipients}: rec {
-          # TODO: Merge both generators to one with consistent options syntax?
-          # Impure generator is built on local machine, then built closure is copied to remote machine,
-          # and then it is ran in inpure context, so that this generator may access HSMs and other things.
-          mkImpureSecretGenerator = {
-            script,
-            # If set - script will be run on remote machine, otherwise it will be run with fleet project in CWD
-            # (Some secrets-encryption-in-git/managed PKI solution is expected)
-            impureOn ? null,
-          }:
-            (prev.writeShellScript "impureGenerator.sh" ''
-              #!/bin/sh
-              set -eu
-
-              export GENERATOR_HELPER_IDENTITIES="${concatStringsSep "\n" recipients}";
-              export PATH=${final.fleet-generator-helper}/bin:$PATH
-
-              # TODO: Provide tempdir from outside, to make it securely erasurable as needed?
-              tmp=$(mktemp -d)
-              cd $tmp
-              # cd /var/empty
-
-              created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")
-
-              ${script}
-
-              if ! test -d $out; then
-                echo "impure generator script did not produce expected \$out output"
-                exit 1
-              fi
-
-              echo -n $created_at > $out/created_at
-              echo -n SUCCESS > $out/marker
-            '')
-            .overrideAttrs (old: {
-              passthru = {
-                inherit impureOn;
-                generatorKind = "impure";
-              };
-            });
-          # Pure generators are disabled for now
-          mkSecretGenerator = {script}: mkImpureSecretGenerator {inherit script;};
-
-          # TODO: Implement consistent naming
-          # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...
-          # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.
-          # mkSecretGenerator = {script}:
-          #   (prev.writeShellScript "generator.sh" ''
-          #     #!/bin/sh
-          #     set -eu
-          #     # TODO: make nix daemon build secret, not just the script.
-          #     cd /var/empty
-          #
-          #     created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")
-          #
-          #     ${script}
-          #     if ! test -d $out; then
-          #       echo "impure generator script did not produce expected \$out output"
-          #       exit 1
-          #     fi
-          #
-          #     echo -n $created_at > $out/created_at
-          #     echo -n SUCCESS > $out/marker
-          #   '')
-          #   .overrideAttrs (old: {
-          #     passthru = {
-          #       generatorKind = "pure";
-          #     };
-          #     # TODO: make nix daemon build secret, not just the script.
-          #     # __impure = true;
-          #   });
-        };
-      })
-    ];
-  };
-}
addedmodules/fleetLib.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/fleetLib.nix
@@ -0,0 +1,9 @@
+{
+  lib,
+  config,
+  ...
+}: {
+  _module.args.fleetLib = import ../../lib {
+    inherit lib;
+  };
+}
addedmodules/hosts.nixdiffbeforeafterboth

no changes

addedmodules/meta.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/meta.nix
@@ -0,0 +1,7 @@
+{lib, ...}: let
+  inherit (lib.modules) mkRemovedOptionModule;
+in {
+  imports = [
+    (mkRemovedOptionModule ["fleetModules"] "replaced with imports.")
+  ];
+}
addedmodules/module-list.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/module-list.nix
@@ -0,0 +1,10 @@
+[
+  ./assertions.nix
+  ./fleetLib.nix
+  ./hosts.nix
+  ./meta.nix
+  ./nixos.nix
+  ./nixpkgs.nix
+  ./secrets.nix
+  ./secrets-data.nix
+]
addedmodules/nixos.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/nixos.nix
@@ -0,0 +1,62 @@
+{
+  lib,
+  fleetLib,
+  config,
+  ...
+}: let
+  inherit (lib.attrsets) mapAttrs;
+  inherit (lib.options) mkOption;
+  inherit (lib.types) deferredModule;
+  inherit (lib.modules) mkRemovedOptionModule;
+  inherit (fleetLib.options) mkHostsOption;
+
+  _file = ./nixos.nix;
+in {
+  options = {
+    nixos = mkOption {
+      description = ''
+        Nixos configuration for all hosts.
+      '';
+      type = deferredModule;
+    };
+    hosts = mkHostsOption (hostArgs: {
+      inherit _file;
+      options = {
+        nixos = mkOption {
+          description = ''
+            Nixos configuration for the current host.
+          '';
+          type = deferredModule;
+          apply = module:
+            config.nixpkgs.buildUsing.lib.nixosSystem {
+              inherit (hostArgs.config) system;
+              modules = [
+                (module // {key = "attr<host.nixos>";})
+                (config.nixos // {key = "attr<fleet.nixos>";})
+              ];
+              specialArgs = {
+                inherit fleetLib;
+              };
+            };
+        };
+      };
+      config = {
+        # imports = [
+        #   (mkRemovedOptionModule ["nixosModules"] "replaced with hosts.*.nixos.imports.")
+        # ];
+        nixos = {
+          config._module.args = {
+            nixosHosts = mapAttrs (_: value: value.nixos.config) config.hosts;
+            hosts = config.hosts;
+            host = hostArgs.config;
+          };
+        };
+      };
+    });
+  };
+  imports = [
+    (mkRemovedOptionModule ["nixosModules"] "replaced with nixos.imports.")
+  ];
+  config.nixos.imports =
+    import ./nixos/module-list.nix;
+}
addedmodules/nixos/meta.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/nixos/meta.nix
@@ -0,0 +1,24 @@
+{
+  lib,
+  pkgs,
+  ...
+}: let
+  inherit (lib.options) mkOption;
+  inherit (lib.modules) mkRemovedOptionModule;
+in {
+  options = {
+    # TODO: Give a real name.
+    # Previously it was nixpkgs.resolvedPkgs, which was erroreously merged with nixpkgs override attribute.
+    _resolvedPkgs = mkOption {
+      type = lib.types.pkgs // {description = "nixpkgs.pkgs";};
+      description = "Value of pkgs";
+    };
+  };
+  imports = [
+    (mkRemovedOptionModule ["tags"] "tags are now defined at the host level, not the nixos system level for fast filtering without evaluating unnecessary hosts.")
+    (mkRemovedOptionModule ["network"] "network is now defined at the host level, not the nixos system level")
+  ];
+  config = {
+    _resolvedPkgs = pkgs;
+  };
+}
addedmodules/nixos/module-list.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/nixos/module-list.nix
@@ -0,0 +1,6 @@
+[
+  ./meta.nix
+  ./secrets.nix
+  ./rollback.nix
+  ./nix-sign.nix
+]
addedmodules/nixos/nix-sign.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/nixos/nix-sign.nix
@@ -0,0 +1,21 @@
+# Required for nix copy in build_systems.rs
+{
+  lib,
+  config,
+  ...
+}: let
+  inherit (lib.modules) mkIf;
+  hasPersistentHostname = config.networking.hostName != "";
+in {
+  # https://github.com/NixOS/nix/issues/3023
+  systemd.services.generate-nix-cache-key = mkIf hasPersistentHostname {
+    wantedBy = ["multi-user.target"];
+    serviceConfig.Type = "oneshot";
+    path = [config.nix.package];
+    script = ''
+      [[ -f /etc/nix/private-key ]] && exit
+      nix-store --generate-binary-cache-key ${config.networking.hostName}-1 /etc/nix/private-key /etc/nix/public-key
+    '';
+  };
+  nix.settings.secret-key-files = mkIf hasPersistentHostname "/etc/nix/private-key";
+}
addedmodules/nixos/rollback.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/nixos/rollback.nix
@@ -0,0 +1,48 @@
+# Tied to build_systems.rs
+{config, ...}: {
+  # TODO: Make it work with systemd-initrd approach.
+  # In this case we can't just switch generation and re-run activation script, since the root filesystem might not be
+  # mounted yet. We need to explicitly remove the last generation, and this needs deeper integration with systemd/grub/
+  # whatever user uses. boot.json also might help here.
+
+  systemd.services.rollback-watchdog = {
+    description = "Rollback watchdog";
+    script = ''
+      set -eux
+      if [ -f /etc/fleet_rollback_marker ]; then
+        echo "found the rollback marker, switching to older generation"
+        target=$(cat /etc/fleet_rollback_marker)
+        echo "rolling back profile"
+        nix profile rollback --profile /nix/var/nix/profiles/system --to "$target"
+        echo "executing activation script"
+        "/nix/var/nix/profiles/system-$target-link/bin/switch-to-configuration" switch || true
+        echo "removing rollback marker"
+        rm -f /etc/fleet_rollback_marker
+      else
+        echo "rollback marker was removed, upgrade is succeeded"
+      fi
+    '';
+    path = [
+      # Should have nix-command support
+      config.nix.package
+    ];
+    serviceConfig.Type = "exec";
+    unitConfig = {
+      X-StopOnRemoval = false;
+      X-RestartIfChanged = false;
+      X-StopIfChanged = false;
+    };
+  };
+
+  systemd.timers.rollback-watchdog = {
+    description = "Timer for rollback watchdog";
+    wantedBy = ["timers.target"];
+    timerConfig = {
+      OnActiveSec = "3min";
+      RemainAfterElapse = false;
+    };
+    unitConfig = {
+      ConditionPathExists = "/etc/fleet_rollback_marker";
+    };
+  };
+}
addedmodules/nixos/secrets.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/nixos/secrets.nix
@@ -0,0 +1,155 @@
+{
+  lib,
+  fleetLib,
+  config,
+  pkgs,
+  ...
+}: let
+  inherit (builtins) hashString;
+  inherit (lib.stringsWithDeps) stringAfter;
+  inherit (lib.options) mkOption;
+  inherit (lib.lists) optional;
+  inherit (lib.attrsets) mapAttrs;
+  inherit (lib.modules) mkIf;
+  inherit (lib.types) submodule str attrsOf nullOr unspecified lazyAttrsOf;
+  inherit (fleetLib.strings) decodeRawSecret;
+
+  sysConfig = config;
+  secretPartType = secretName:
+    submodule ({config, ...}: let
+      partName = config._module.args.name;
+    in {
+      options = {
+        raw = mkOption {
+          type = str;
+          internal = true;
+          description = "Encoded & Encrypted secret part data, passed from fleet.nix";
+        };
+        hash = mkOption {
+          type = str;
+          description = "Hash of secret in encoded format";
+        };
+        path = mkOption {
+          type = str;
+          description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";
+        };
+        stablePath = mkOption {
+          type = str;
+          description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";
+        };
+        data = mkOption {
+          type = str;
+          description = "Secret public data (only available for plaintext)";
+        };
+      };
+      config = {
+        hash = hashString "sha1" config.raw;
+        data = decodeRawSecret config.raw;
+        path = "/run/secrets/${secretName}/${config.hash}-${partName}";
+        stablePath = "/run/secrets/${secretName}/${partName}";
+      };
+    });
+  secretType = submodule ({config, ...}: let
+    secretName = config._module.args.name;
+  in {
+    freeformType = lazyAttrsOf (secretPartType secretName);
+    options = {
+      shared = mkOption {
+        description = "Is this secret owned by this machine, or propagated from shared secrets";
+        default = false;
+      };
+
+      generator = mkOption {
+        type = nullOr unspecified;
+        description = "Derivation to evaluate for secret generation";
+        default = null;
+      };
+      mode = mkOption {
+        type = str;
+        description = "Secret mode";
+        default = "0440";
+      };
+      owner = mkOption {
+        type = str;
+        description = "Owner of the secret";
+        default = "root";
+      };
+      group = mkOption {
+        type = str;
+        description = "Group of the secret";
+        default = sysConfig.users.users.${config.owner}.group;
+      };
+    };
+  });
+  processPart = part: {
+    inherit (part) raw path stablePath;
+  };
+  processSecret = secret:
+    {
+      inherit (secret) group mode owner;
+    }
+    // (mapAttrs (_: processPart) (removeAttrs secret [
+      "shared"
+      "generator"
+      "mode"
+      "group"
+      "owner"
+    ]));
+  secretsFile = pkgs.writeTextFile {
+    name = "secrets.json";
+    text =
+      builtins.toJSON (mapAttrs (_: processSecret)
+        config.secrets);
+  };
+  useSysusers = (config.systemd ? sysusers && config.systemd.sysusers.enable) || (config ? userborn && config.userborn.enable);
+in {
+  options = {
+    secrets = mkOption {
+      type = attrsOf secretType;
+      default = {};
+      description = "Host-local secrets";
+    };
+  };
+  config = {
+    environment.systemPackages = [pkgs.fleet-install-secrets];
+
+    systemd.services.fleet-install-secrets = mkIf useSysusers {
+      wantedBy = ["sysinit.target"];
+      after = ["systemd-sysusers.service"];
+      restartTriggers = [
+        secretsFile
+      ];
+      aliases = [
+        "sops-install-secrets"
+        "agenix-install-secrets"
+      ];
+
+      unitConfig.DefaultDependencies = false;
+
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExit = true;
+        ExecStart = "${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}";
+      };
+    };
+    system.activationScripts.decryptSecrets =
+      mkIf (!useSysusers)
+      (
+        stringAfter (
+          [
+            # secrets are owned by user/group, thus we need to refer to those
+            "users"
+            "groups"
+            "specialfs"
+          ]
+          # nixos-impermanence compatibility: secrets are encrypted by host-key,
+          # but with impermanence we expect that the host-key is installed by
+          # persist-file activation script.
+          ++ (optional (config.system.activationScripts ? "persist-files") "persist-files")
+        ) ''
+          1>&2 echo "setting up secrets"
+          ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}
+        ''
+      );
+  };
+}
addedmodules/nixpkgs.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/nixpkgs.nix
@@ -0,0 +1,55 @@
+{
+  lib,
+  fleetLib,
+  config,
+  ...
+}: let
+  inherit (lib.options) mkOption;
+  inherit (lib.types) path;
+  inherit (lib.modules) mkRemovedOptionModule;
+  inherit (fleetLib.options) mkHostsOption;
+  inherit (fleetLib.types) listOfOverlay;
+
+  _file = ./nixpkgs.lib;
+in {
+  options = {
+    nixpkgs = {
+      buildUsing = mkOption {
+        description = ''
+          Default nixpkgs to use for building the systems.
+        '';
+        type = path;
+      };
+      overlays = mkOption {
+        description = ''
+          Package overlays to apply for all the hosts, gets propagated into
+          `hosts.*.nixosModules.nixpkgs.overlays`.
+        '';
+        type = listOfOverlay;
+      };
+    };
+    hosts = mkHostsOption {
+      inherit _file;
+      options.nixpkgs.buildUsing = mkOption {
+        description = ''
+          Nixpkgs to use for building the system.
+
+          Note that this option is defined at the host level, not the nixosModules level,
+          nixosModules will be evaluated using this flake input.
+        '';
+        type = path;
+        default = config.nixpkgs.buildUsing;
+      };
+      # imports = [
+      # 	(mkRemovedOptionModule ["nixpkgs" "overlays"] "this option needs to be specified at nixosModules level")
+      # ];
+      config.nixos = {
+        inherit _file;
+        nixpkgs.overlays = config.nixpkgs.overlays;
+        imports = [
+          (mkRemovedOptionModule ["nixpkgs" "buildUsing"] "this option should be specified at the host level, not the nixosModules level")
+        ];
+      };
+    };
+  };
+}
addedmodules/secrets-data.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/secrets-data.nix
@@ -0,0 +1,105 @@
+{
+  lib,
+  fleetLib,
+  config,
+  ...
+}: let
+  inherit (fleetLib.options) mkDataOption;
+  inherit (lib.options) mkOption;
+  inherit (lib.types) lazyAttrsOf nullOr listOf str attrsOf submodule bool;
+  inherit (lib.attrsets) mapAttrsToList mapAttrs catAttrs filterAttrs genAttrs;
+  inherit (lib.lists) sort unique concatLists;
+  inherit (lib.strings) toJSON;
+
+  secretDataValue = {
+    options = {
+      raw = mkOption {
+        type = nullOr str;
+        description = "Encrypted + encoded secret data";
+        default = null;
+      };
+    };
+  };
+
+  sharedSecretData = {
+    freeformType = attrsOf (submodule secretDataValue);
+    options = {
+      createdAt = mkOption {
+        type = str;
+        description = "When this secret was (re)generated";
+        default = null;
+      };
+      expiresAt = mkOption {
+        type = nullOr str;
+        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";
+        default = null;
+      };
+
+      owners = mkOption {
+        type = listOf str;
+        description = ''
+          For which owners this secret is currently encrypted,
+          if not matches expectedOwners - then this secret is considered outdated, and
+          should be regenerated/reencrypted.
+
+          Imported from fleet.nix
+        '';
+        default = [];
+      };
+    };
+  };
+
+  hostSecretData = {
+    freeformType = attrsOf (submodule secretDataValue);
+    options = {
+      createdAt = mkOption {
+        type = str;
+        description = "When this secret was (re)generated";
+        default = null;
+      };
+      expiresAt = mkOption {
+        type = nullOr str;
+        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";
+        default = null;
+      };
+      shared = mkOption {
+        type = bool;
+        description = "On which date this secret will expire, someone should regenerate this secret before it expires.";
+        default = false;
+      };
+    };
+  };
+in {
+  options.data = mkDataOption ({config, ...}: {
+    options = {
+      sharedSecrets = mkOption {
+        type = attrsOf (submodule sharedSecretData);
+        default = {};
+        description = "Stored shared secret data.";
+      };
+      hostSecrets = mkOption {
+        type = attrsOf (attrsOf (submodule hostSecretData));
+        default = {};
+        description = "Host secrets.";
+        internal = true;
+      };
+    };
+    config.hostSecrets = let
+      hostsWithSharedSecrets = unique (concatLists (mapAttrsToList (_: s: s.owners) config.sharedSecrets));
+      secretsHavingHost = host: filterAttrs (_: secret: lib.elem host secret.owners) config.sharedSecrets;
+      toHostSecret = _: secret: (removeAttrs secret ["owners"]) // {shared = true;};
+    in
+      genAttrs hostsWithSharedSecrets (host: mapAttrs toHostSecret (secretsHavingHost host));
+  });
+  config = {
+    assertions =
+      mapAttrsToList
+      (name: secret: {
+        assertion = secret.expectedOwners == null || sort (a: b: a < b) config.data.sharedSecrets.${name}.owners == sort (a: b: a < b) secret.expectedOwners;
+        message = "Shared secret ${name} is expected to be encrypted for ${toJSON secret.expectedOwners}, but it is encrypted for ${toJSON config.data.sharedSecrets.${name}.owners}. Run fleet secrets regenerate to fix";
+      })
+      config.sharedSecrets;
+    sharedSecrets =
+      mapAttrs (_: _: {}) config.data.sharedSecrets;
+  };
+}
addedmodules/secrets.nixdiffbeforeafterboth
--- /dev/null
+++ b/modules/secrets.nix
@@ -0,0 +1,134 @@
+{lib, config, ...}: let
+  inherit (lib.options) mkOption;
+  inherit (lib.types) unspecified nullOr listOf str bool attrsOf submodule;
+  inherit (lib.strings) concatStringsSep;
+  inherit (lib.attrsets) mapAttrs;
+
+  sharedSecret = {config, ...}: {
+    options = {
+      expectedOwners = mkOption {
+        type = nullOr (listOf str);
+        description = ''
+          List of hosts to encrypt secret for. null if managed by user (= via owners field from fleet.nix)
+
+          Secrets would be decrypted and stored to /run/secrets/$\{name} on owners
+        '';
+        default = null;
+      };
+      # TODO: Aren't those options may be just desugared to data/expectedData?
+      regenerateOnOwnerAdded = mkOption {
+        type = bool;
+        description = ''
+          Is this secret owner-dependent, and needs to be regenerated on ownership set change, or it may be just reencrypted.
+
+          You want to have this option set to true, when this secret contains some reference to its owners, i.e x509 SANs.
+        '';
+      };
+      regenerateOnOwnerRemoved = mkOption {
+        default = config.regenerateOnOwnerAdded;
+        type = bool;
+        description = ''
+          Should this secret be removed on owner removal, or it may be just reencrypted
+
+          Most probably its value should be equal to regenerateOnOwnerAdded, override only if you know what are you doing.
+          Contrary to regenerateOnOwnerAdded, you may want to set this option to false, when host permissions are revoked
+          in some other way than by this secret ownership, I.e by firewall/etc.
+        '';
+      };
+      generator = mkOption {
+        type = nullOr unspecified;
+        description = "Derivation to evaluate for secret generation";
+        default = null;
+      };
+    };
+  };
+in {
+  options = {
+    sharedSecrets = mkOption {
+      type = attrsOf (submodule sharedSecret);
+      default = {};
+      description = "Shared secrets";
+    };
+  };
+  config = {
+    hosts = mapAttrs (_: secretMap: {
+      nixos.secrets = mapAttrs (_: s: removeAttrs s ["createdAt" "expiresAt"]) secretMap;
+    }) config.data.hostSecrets;
+    nixpkgs.overlays = [
+      (final: prev: {
+        mkSecretGenerators = {recipients}: rec {
+          # TODO: Merge both generators to one with consistent options syntax?
+          # Impure generator is built on local machine, then built closure is copied to remote machine,
+          # and then it is ran in inpure context, so that this generator may access HSMs and other things.
+          mkImpureSecretGenerator = {
+            script,
+            # If set - script will be run on remote machine, otherwise it will be run with fleet project in CWD
+            # (Some secrets-encryption-in-git/managed PKI solution is expected)
+            impureOn ? null,
+          }:
+            (prev.writeShellScript "impureGenerator.sh" ''
+              #!/bin/sh
+              set -eu
+
+              export GENERATOR_HELPER_IDENTITIES="${concatStringsSep "\n" recipients}";
+              export PATH=${final.fleet-generator-helper}/bin:$PATH
+
+              # TODO: Provide tempdir from outside, to make it securely erasurable as needed?
+              tmp=$(mktemp -d)
+              cd $tmp
+              # cd /var/empty
+
+              created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")
+
+              ${script}
+
+              if ! test -d $out; then
+                echo "impure generator script did not produce expected \$out output"
+                exit 1
+              fi
+
+              echo -n $created_at > $out/created_at
+              echo -n SUCCESS > $out/marker
+            '')
+            .overrideAttrs (old: {
+              passthru = {
+                inherit impureOn;
+                generatorKind = "impure";
+              };
+            });
+          # Pure generators are disabled for now
+          mkSecretGenerator = {script}: mkImpureSecretGenerator {inherit script;};
+
+          # TODO: Implement consistent naming
+          # Pure secret generator is supposed to be run entirely by nix, using `__impure` derivation type...
+          # But for now, it is ran the same way as `impureSecretGenerator`, but on the local machine.
+          # mkSecretGenerator = {script}:
+          #   (prev.writeShellScript "generator.sh" ''
+          #     #!/bin/sh
+          #     set -eu
+          #     # TODO: make nix daemon build secret, not just the script.
+          #     cd /var/empty
+          #
+          #     created_at=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")
+          #
+          #     ${script}
+          #     if ! test -d $out; then
+          #       echo "impure generator script did not produce expected \$out output"
+          #       exit 1
+          #     fi
+          #
+          #     echo -n $created_at > $out/created_at
+          #     echo -n SUCCESS > $out/marker
+          #   '')
+          #   .overrideAttrs (old: {
+          #     passthru = {
+          #       generatorKind = "pure";
+          #     };
+          #     # TODO: make nix daemon build secret, not just the script.
+          #     # __impure = true;
+          #   });
+        };
+      })
+    ];
+  };
+}
deletednixos/assertions.nixdiffbeforeafterboth
--- a/nixos/assertions.nix
+++ /dev/null
@@ -1,24 +0,0 @@
-# Similar module exists for fleet, however it also defines assertions and warnings,
-# which are already defined for nixos.
-{
-  lib,
-  config,
-  ...
-}: let
-  inherit (lib.options) mkOption;
-  inherit (lib.lists) map filter;
-  inherit (lib.types) listOf str;
-in {
-  options = {
-    errors = mkOption {
-      type = listOf str;
-      internal = true;
-      description = ''
-        Similar to warnings, however build will fail if any error exists.
-      '';
-    };
-  };
-  config.errors =
-    map (v: v.message)
-    (filter (v: !v.assertion) config.assertions);
-}
deletednixos/meta.nixdiffbeforeafterboth
--- a/nixos/meta.nix
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  lib,
-  pkgs,
-  ...
-}: let
-  inherit (lib.options) mkOption;
-  inherit (lib.types) listOf str submodule;
-  inherit (lib.modules) mkRemovedOptionModule;
-in {
-  options = {
-    # TODO: Give a real name.
-    # Previously it was nixpkgs.resolvedPkgs, which was erroreously merged with nixpkgs override attribute.
-    _resolvedPkgs = mkOption {
-      type = lib.types.pkgs // {description = "nixpkgs.pkgs";};
-      description = "Value of pkgs";
-    };
-    network = mkOption {
-      type = submodule {
-        options = {
-          internalIps = mkOption {
-            type = listOf str;
-            description = "Internal ips";
-            default = [];
-          };
-          externalIps = mkOption {
-            type = listOf str;
-            description = "External ips";
-            default = [];
-          };
-        };
-      };
-      description = "Network definition of host";
-    };
-  };
-  imports = [
-    (mkRemovedOptionModule ["tags"] "tags are now defined at the host level, not the nixos system level for fast filtering without evaluating unnecessary hosts.")
-  ];
-  config = {
-    network = {};
-    _resolvedPkgs = pkgs;
-  };
-}
deletednixos/modules/module-list.nixdiffbeforeafterboth
--- a/nixos/modules/module-list.nix
+++ /dev/null
@@ -1,7 +0,0 @@
-[
-  ../assertions.nix
-  ../meta.nix
-  ../secrets.nix
-  ../rollback.nix
-  ../nix-sign.nix
-]
deletednixos/nix-sign.nixdiffbeforeafterboth
--- a/nixos/nix-sign.nix
+++ /dev/null
@@ -1,19 +0,0 @@
-# Required for nix copy in build_systems.rs
-{lib, config, ...}:
-let
-  inherit (lib.modules) mkIf;
-  hasPersistentHostname = config.networking.hostName != "";
-in
-{
-  # https://github.com/NixOS/nix/issues/3023
-  systemd.services.generate-nix-cache-key = mkIf hasPersistentHostname {
-    wantedBy = ["multi-user.target"];
-    serviceConfig.Type = "oneshot";
-    path = [config.nix.package];
-    script = ''
-      [[ -f /etc/nix/private-key ]] && exit
-      nix-store --generate-binary-cache-key ${config.networking.hostName}-1 /etc/nix/private-key /etc/nix/public-key
-    '';
-  };
-  nix.settings.secret-key-files = mkIf hasPersistentHostname "/etc/nix/private-key";
-}
deletednixos/rollback.nixdiffbeforeafterboth
--- a/nixos/rollback.nix
+++ /dev/null
@@ -1,48 +0,0 @@
-# Tied to build_systems.rs
-{config, ...}: {
-  # TODO: Make it work with systemd-initrd approach.
-  # In this case we can't just switch generation and re-run activation script, since the root filesystem might not be
-  # mounted yet. We need to explicitly remove the last generation, and this needs deeper integration with systemd/grub/
-  # whatever user uses. boot.json also might help here.
-
-  systemd.services.rollback-watchdog = {
-    description = "Rollback watchdog";
-    script = ''
-      set -eux
-      if [ -f /etc/fleet_rollback_marker ]; then
-        echo "found the rollback marker, switching to older generation"
-        target=$(cat /etc/fleet_rollback_marker)
-        echo "rolling back profile"
-        nix profile rollback --profile /nix/var/nix/profiles/system --to "$target"
-        echo "executing activation script"
-        "/nix/var/nix/profiles/system-$target-link/bin/switch-to-configuration" switch || true
-        echo "removing rollback marker"
-        rm -f /etc/fleet_rollback_marker
-      else
-        echo "rollback marker was removed, upgrade is succeeded"
-      fi
-    '';
-    path = [
-      # Should have nix-command support
-      config.nix.package
-    ];
-    serviceConfig.Type = "exec";
-    unitConfig = {
-      X-StopOnRemoval = false;
-      X-RestartIfChanged = false;
-      X-StopIfChanged = false;
-    };
-  };
-
-  systemd.timers.rollback-watchdog = {
-    description = "Timer for rollback watchdog";
-    wantedBy = ["timers.target"];
-    timerConfig = {
-      OnActiveSec = "3min";
-      RemainAfterElapse = false;
-    };
-    unitConfig = {
-      ConditionPathExists = "/etc/fleet_rollback_marker";
-    };
-  };
-}
deletednixos/secrets.nixdiffbeforeafterboth
--- a/nixos/secrets.nix
+++ /dev/null
@@ -1,168 +0,0 @@
-{
-  lib,
-  config,
-  pkgs,
-  ...
-}: let
-  inherit (lib.strings) hasPrefix removePrefix;
-  inherit (lib.stringsWithDeps) stringAfter;
-  inherit (lib.options) mkOption;
-  inherit (lib.lists) optional;
-  inherit (lib.attrsets) mapAttrs;
-  inherit (lib.modules) mkOptionDefault mkIf;
-  inherit (lib.types) submodule str attrsOf nullOr unspecified lazyAttrsOf;
-  plaintextPrefix = "<PLAINTEXT>";
-  plaintextNewlinePrefix = "<PLAINTEXT-NL>";
-
-  sysConfig = config;
-  secretPartType = secretName:
-    submodule ({config, ...}: {
-      options = {
-        raw = mkOption {
-          description = "Secret in fleet-specific undocumented format, do not use. Import from fleet.nix";
-          internal = true;
-        };
-        hash = mkOption {
-          type = str;
-          description = "Hash of secret in encoded format";
-        };
-        path = mkOption {
-          type = str;
-          description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";
-        };
-        stablePath = mkOption {
-          type = str;
-          description = "Path to secret part, incorporating data hash (thus it will be updated on secret change)";
-        };
-        data = mkOption {
-          type = str;
-          description = "Secret public data (only available for plaintext)";
-        };
-      };
-      config = let
-        partName = config._module.args.name;
-      in {
-        hash = mkOptionDefault (builtins.hashString "sha1" config.raw);
-        data = mkOptionDefault (
-          if hasPrefix plaintextPrefix config.raw
-          then removePrefix plaintextPrefix config.raw
-          else if hasPrefix plaintextNewlinePrefix config.raw
-          then removePrefix plaintextNewlinePrefix config.raw
-          else throw "secret.part.data attribute only works for public plaintext secret parts, got ${config.raw}"
-        );
-        path = mkOptionDefault "/run/secrets/${secretName}/${config.hash}-${partName}";
-        stablePath = mkOptionDefault "/run/secrets/${secretName}/${partName}";
-      };
-    });
-  secretType = submodule ({config, ...}: let
-    secretName = config._module.args.name;
-  in {
-    freeformType = lazyAttrsOf (secretPartType secretName);
-    options = {
-      shared = mkOption {
-        description = "Is this secret owned by this machine, or propagated from shared secrets";
-        default = false;
-      };
-      expectedOwners = mkOption {
-        type = nullOr unspecified;
-        default = null;
-        internal = true;
-      };
-
-      generator = mkOption {
-        type = nullOr unspecified;
-        description = "Derivation to evaluate for secret generation";
-        default = null;
-      };
-      mode = mkOption {
-        type = str;
-        description = "Secret mode";
-        default = "0440";
-      };
-      owner = mkOption {
-        type = str;
-        description = "Owner of the secret";
-        default = "root";
-      };
-      group = mkOption {
-        type = str;
-        description = "Group of the secret";
-        default = sysConfig.users.users.${config.owner}.group;
-      };
-    };
-  });
-  processPart = part: {
-    inherit (part) raw path stablePath;
-  };
-  processSecret = secret:
-    {
-      inherit (secret) group mode owner;
-    }
-    // (mapAttrs (_: processPart) (removeAttrs secret [
-      "shared"
-      "generator"
-      "mode"
-      "group"
-      "owner"
-
-      # FIXME: Some of those removed attributes shouldn't be here, but there is some error in passing shared secrets from fleet to nixos.
-      "expectedOwners"
-    ]));
-  secretsFile = pkgs.writeTextFile {
-    name = "secrets.json";
-    text =
-      builtins.toJSON (mapAttrs (_: processSecret)
-        config.secrets);
-  };
-  useSysusers = (config.systemd ? sysusers && config.systemd.sysusers.enable) || (config ? userborn && config.userborn.enable);
-in {
-  options = {
-    secrets = mkOption {
-      type = attrsOf secretType;
-      default = {};
-      description = "Host-local secrets";
-    };
-  };
-  config = {
-    environment.systemPackages = [pkgs.fleet-install-secrets];
-
-    systemd.services.fleet-install-secrets = mkIf useSysusers {
-      wantedBy = ["sysinit.target"];
-      after = ["systemd-sysusers.service"];
-      restartTriggers = [
-        secretsFile
-      ];
-      aliases = [
-        "sops-install-secrets"
-        "agenix-install-secrets"
-      ];
-
-      unitConfig.DefaultDependencies = false;
-
-      serviceConfig = {
-        Type = "oneshot";
-        RemainAfterExit = true;
-        ExecStart = "${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}";
-      };
-    };
-    system.activationScripts.decryptSecrets =
-      mkIf (!useSysusers)
-      (
-        stringAfter (
-          [
-            # secrets are owned by user/group, thus we need to refer to those
-            "users"
-            "groups"
-            "specialfs"
-          ]
-          # nixos-impermanence compatibility: secrets are encrypted by host-key,
-          # but with impermanence we expect that the host-key is installed by
-          # persist-file activation script.
-          ++ (optional (config.system.activationScripts ? "persist-files") "persist-files")
-        ) ''
-          1>&2 echo "setting up secrets"
-          ${pkgs.fleet-install-secrets}/bin/fleet-install-secrets install ${secretsFile}
-        ''
-      );
-  };
-}