From abd133c244e9c9f9be8a66bd4a2e1a98e4090270 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 16:21:40 -0700 Subject: [PATCH 01/31] make devosSystem construct a proper nixos builder Get `self` and `inputs` during construction, and rely on specialArgs.channel for nixos flake --- lib/devos/devosSystem.nix | 63 ++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/lib/devos/devosSystem.nix b/lib/devos/devosSystem.nix index 00c9e3e6..c48f68a5 100644 --- a/lib/devos/devosSystem.nix +++ b/lib/devos/devosSystem.nix @@ -1,31 +1,40 @@ { lib }: -{ self, nixos, inputs, modules, ... } @ allArgs: -let args = builtins.removeAttrs allArgs [ "self" "nixos" "inputs" ]; in -lib.nixosSystem (args // { - modules = - let - moduleList = builtins.attrValues modules; +# dependencies to return a builder +{ self, inputs }: - fullHostConfig = (lib.nixosSystem (args // { modules = moduleList; })).config; +{ modules, specialArgs, ... } @ args: +let inherit (specialArgs.channel.input.lib) nixosSystem; in +nixosSystem + (args // { + modules = + let + fullHostConfig = (nixosSystem (args // { inherit modules; })).config; - isoConfig = (lib.nixosSystem - (args // { - modules = moduleList ++ [ - (lib.modules.iso { inherit self nixos inputs fullHostConfig; }) - ]; - })).config; - hmConfig = (lib.nixosSystem - (args // { - modules = moduleList ++ [ - (lib.modules.hmConfig) - ]; - })).config; - in - moduleList ++ [{ - system.build = { - iso = isoConfig.system.build.isoImage; - homes = hmConfig.home-manager.users; - }; - }]; -}) + isoConfig = (nixosSystem + (args // { + modules = modules ++ [ + (lib.modules.iso { inherit self inputs fullHostConfig; }) + ]; + })).config; + + hmConfig = (nixosSystem + (args // { + modules = modules ++ [ + (lib.modules.hmConfig) + ]; + })).config; + in + modules ++ [{ + system.build = { + iso = isoConfig.system.build.isoImage; + homes = hmConfig.home-manager.users; + }; + lib = { + inherit specialArgs; + testModule = { + imports = modules; + }; + }; + }]; + }) From 59383e871f882cb1a72c64392bdb48220db1367c Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 16:22:33 -0700 Subject: [PATCH 02/31] modules: drop any logic already done by fup this includes creating multiPkgs, and dropping options already set by fup --- lib/modules.nix | 46 ++++++++++------------------------------------ 1 file changed, 10 insertions(+), 36 deletions(-) diff --git a/lib/modules.nix b/lib/modules.nix index 7024f13f..2cd965ff 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -1,28 +1,16 @@ { lib }: { - modOverrides = { overrides }: - { config, overrideModulesPath, ... }: - let - inherit (overrides) modules disabledModules; - in - { - disabledModules = modules ++ disabledModules; - imports = map - (path: "${overrideModulesPath}/${path}") - modules; - }; - - hmDefaults = { userSuites, extern, homeModules }: { + hmDefaults = { suites, modules }: { home-manager = { useGlobalPkgs = true; useUserPackages = true; - extraSpecialArgs = extern.userSpecialArgs // { suites = userSuites; }; - sharedModules = extern.userModules ++ (builtins.attrValues homeModules); + extraSpecialArgs = { inherit suites; }; + sharedModules = modules; }; }; - globalDefaults = { self, nixos, inputs, multiPkgs }: + globalDefaults = { self, inputs }: let experimentalFeatures = [ "flakes" @@ -31,27 +19,22 @@ "ca-derivations" ]; in - { config, pkgs, ... }: { + { channel, config, pkgs, ... }: { users.mutableUsers = lib.mkDefault false; hardware.enableRedistributableFirmware = lib.mkDefault true; nix.nixPath = [ - "nixpkgs=${nixos}" + "nixpkgs=${channel.input}" "nixos-config=${self}/lib/compat/nixos" "home-manager=${inputs.home}" ]; - nixpkgs.pkgs = lib.mkDefault multiPkgs.${config.nixpkgs.system}; - nix.registry = { devos.flake = self; - nixos.flake = nixos; - override.flake = inputs.override; + nixos.flake = channel.input; }; - nix.package = pkgs.nixFlakes; - nix.extraOptions = '' experimental-features = ${lib.concatStringsSep " " experimentalFeatures @@ -61,19 +44,10 @@ system.configurationRevision = lib.mkIf (self ? rev) self.rev; }; - cachix = { self }: - let rootCachix = "${self}/cachix.nix"; in - if builtins.pathExists rootCachix - then rootCachix - else { }; + isoConfig = { self, inputs, fullHostConfig }: + { config, modulesPath, suites, ... }: { - flakeModules = { self, extern }: { imports = builtins.attrValues self.nixosModules ++ extern.modules; }; - - isoConfig = { self, nixos, inputs, fullHostConfig }: - { config, suites, ... }: { - - imports = let modpath = "nixos/modules"; in - [ "${nixos}/${modpath}/installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ]; + imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal-new-kernel.nix" ]; # avoid unwanted systemd service startups # all strings in disabledModules get appended to modulesPath # so convert each to list which can be coerced to string From ba01aa7db7419a3e301f5f9251eff358d88c7e17 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 10:52:26 -0700 Subject: [PATCH 03/31] mkSuites: generalize for one profile/suite pair --- lib/devos/mkSuites.nix | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/devos/mkSuites.nix b/lib/devos/mkSuites.nix index 66a36ea1..45d8a10f 100644 --- a/lib/devos/mkSuites.nix +++ b/lib/devos/mkSuites.nix @@ -1,20 +1,20 @@ { lib }: -{ users, profiles, userProfiles, suites } @ args: +{ suites, profiles } @ args: let inherit (lib) os; - definedSuites = suites { - inherit (args) users profiles userProfiles; - }; + profileSet = lib.genAttrs' profiles (path: { + name = baseNameOf path; + value = os.mkProfileAttrs (toString path); + }); - allProfiles = lib.collectProfiles profiles; - - allUsers = lib.collectProfiles users; - - createSuites = _: suites: lib.mapAttrs (_: v: os.profileMap v) suites // { - inherit allProfiles allUsers; - }; + definedSuites = suites profileSet; + allProfiles = lib.collectProfiles profileSet; in -lib.mapAttrs createSuites definedSuites +lib.mapAttrs (_: v: os.profileMap v) definedSuites // { + inherit allProfiles; +} + + From 3986cc441b86cb7873c99eb2252df4b080976f76 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 16:36:48 -0700 Subject: [PATCH 04/31] pkgs-lib: don't system space functions have each function take pkgs as an argument, so a nixpkgs isn't created just for pkgs-lib and they support more systems --- lib/flake.nix | 2 +- lib/pkgs-lib/default.nix | 17 +++++------------ lib/pkgs-lib/shell/default.nix | 25 ++++++++++++++----------- lib/pkgs-lib/tests/default.nix | 25 ++++++++++++++----------- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/lib/flake.nix b/lib/flake.nix index 15d87197..393c9d6a 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -40,7 +40,7 @@ pkgs-lib = import ./pkgs-lib { lib = nixpkgs.lib // self; - inherit nixpkgs deploy devshell; + inherit deploy devshell; }; inherit (attrs) diff --git a/lib/pkgs-lib/default.nix b/lib/pkgs-lib/default.nix index 1cadc2fe..bcaee771 100644 --- a/lib/pkgs-lib/default.nix +++ b/lib/pkgs-lib/default.nix @@ -1,13 +1,6 @@ -{ lib, nixpkgs, deploy, devshell }: +{ lib, deploy, devshell }: +{ + tests = import ./tests { inherit lib deploy; }; + shell = import ./shell { inherit lib devshell deploy; }; +} -lib.genAttrs - lib.defaultSystems - (system: - let - pkgs = import nixpkgs { inherit system; }; - in - { - tests = import ./tests { inherit lib deploy nixpkgs pkgs system; }; - shell = import ./shell { inherit lib devshell deploy nixpkgs system; }; - } - ) diff --git a/lib/pkgs-lib/shell/default.nix b/lib/pkgs-lib/shell/default.nix index 0146ca22..5b73b54c 100644 --- a/lib/pkgs-lib/shell/default.nix +++ b/lib/pkgs-lib/shell/default.nix @@ -1,27 +1,30 @@ -{ lib, nixpkgs, devshell, deploy, system }: +{ lib, devshell, deploy }: + +{ pkgs }: let overlays = [ - devshell.overlay (final: prev: { deploy-rs = deploy.packages.${prev.system}.deploy-rs; }) - ]; - pkgs = import nixpkgs { inherit system overlays; config = { }; }; + pkgs' = import pkgs.path { + inherit (pkgs) system; + inherit overlays; + }; - flk = pkgs.callPackage ./flk.nix { }; + flk = pkgs'.callPackage ./flk.nix { }; installPkgs = (lib.nixosSystem { - inherit system; + inherit (pkgs') system; modules = [ ]; }).config.system.build; in -pkgs.devshell.mkShell { - imports = [ (pkgs.devshell.importTOML ./devshell.toml) ]; +pkgs'.devshell.mkShell { + imports = [ (pkgs'.devshell.importTOML ./devshell.toml) ]; packages = with installPkgs; [ nixos-install @@ -33,13 +36,13 @@ pkgs.devshell.mkShell { pre-commit.text = lib.fileContents ./pre-commit.sh; }; - commands = with pkgs; [ + commands = with pkgs'; [ { package = flk; } { name = "nix"; - help = pkgs.nixFlakes.meta.description; + help = pkgs'.nixFlakes.meta.description; command = '' - ${pkgs.nixFlakes}/bin/nix --experimental-features "nix-command flakes ca-references" "${"\${@}"}" + ${pkgs'.nixFlakes}/bin/nix --experimental-features "nix-command flakes ca-references" "${"\${@}"}" ''; } ] diff --git a/lib/pkgs-lib/tests/default.nix b/lib/pkgs-lib/tests/default.nix index b3e60624..854332fe 100644 --- a/lib/pkgs-lib/tests/default.nix +++ b/lib/pkgs-lib/tests/default.nix @@ -1,25 +1,28 @@ -{ lib, nixpkgs, pkgs, deploy, system }: +{ lib, deploy }: let - mkChecks = { hosts, nodes, homes ? { } }: + mkChecks = { pkgs, hosts, nodes, homes ? { } }: let deployHosts = lib.filterAttrs - (n: _: hosts.${n}.config.nixpkgs.system == system) + (n: _: hosts.${n}.config.nixpkgs.system == pkgs.system) nodes; - deployChecks = deploy.lib.${system}.deployChecks { nodes = deployHosts; }; + deployChecks = deploy.lib.${pkgs.system}.deployChecks { nodes = deployHosts; }; tests = lib.optionalAttrs (deployHosts != { }) { - profilesTest = profilesTest (hosts.${(builtins.head (builtins.attrNames deployHosts))}); + profilesTest = profilesTest { + inherit pkgs; + host = hosts.${(builtins.head (builtins.attrNames deployHosts))}; + }; } // lib.mapAttrs (n: v: v.activationPackage) homes; in lib.recursiveUpdate tests deployChecks; - mkTest = host: + mkTest = { pkgs, host }: let nixosTesting = - (import "${nixpkgs}/nixos/lib/testing-python.nix" { - inherit system; + (import "${toString pkgs.path}/nixos/lib/testing-python.nix" { + inherit (pkgs) system; inherit (host.config.lib) specialArgs; inherit pkgs; extraConfigurations = [ @@ -40,15 +43,15 @@ let in nixosTesting.makeTest calledTest; - profilesTest = host: mkTest host { + profilesTest = args@{ host, ... }: mkTest args { name = "profiles"; machine = { suites, ... }: { - imports = suites.allProfiles ++ suites.allUsers; + imports = suites.allProfiles; }; testScript = '' - machine.systemctl("is-system-running --wait") + ${host.config.networking.hostName}.systemctl("is-system-running --wait") ''; }; in From ceef51425e222c85eab4c4053426f08ba880ebe3 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 16:46:02 -0700 Subject: [PATCH 05/31] init unifyOverlays: to pass channels to overlays Only to those with three arguments --- lib/flake.nix | 2 +- lib/lists.nix | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/flake.nix b/lib/flake.nix index 393c9d6a..862570c0 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -50,7 +50,7 @@ pathsToImportedAttrs concatAttrs filterPackages; - inherit (lists) pathsIn collectProfiles; + inherit (lists) pathsIn collectProfiles unifyOverlays; inherit (strings) rgxToString; inherit modules; } diff --git a/lib/lists.nix b/lib/lists.nix index c20a4d7b..5e9c57b2 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -16,4 +16,6 @@ fullPath = name: "${toString dir}/${name}"; in map fullPath (lib.attrNames (lib.safeReadDir dir)); + + unifyOverlays = channels: map (o: if builtins.isFunction (o null null) then o channels else o); } From 377381de51b4dcbf5aea1ee7f80abd12abd63d47 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 11:34:24 -0700 Subject: [PATCH 06/31] export pathsIn in lib and update devos input --- flake.lock | 2 +- lib/flake.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flake.lock b/flake.lock index 1c95e54a..014caf82 100644 --- a/flake.lock +++ b/flake.lock @@ -81,7 +81,7 @@ "utils": "utils_2" }, "locked": { - "narHash": "sha256-t14TKUtw83dZ2mbqjRpeUvdAx4zpe/ySr5KhPhB1JMU=", + "narHash": "sha256-JBTc4NiKuJ99+u8ey+1gQezW5pihAnfnyupBmdj4zUk=", "path": "./lib", "type": "path" }, diff --git a/lib/flake.nix b/lib/flake.nix index 862570c0..65c0e20c 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -61,7 +61,7 @@ { lib = utils.lib // { inherit (lib) - mkFlake; + mkFlake pathsIn; }; } From 3bb26330b457c32aee5249c8c114517466044a5b Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 16:46:59 -0700 Subject: [PATCH 07/31] switch to flake-utils-plus staging for rebase --- flake.lock | 35 +++++++++++++++++++++++++++-------- lib/flake.lock | 33 ++++++++++++++++++++++++++------- lib/flake.nix | 2 +- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/flake.lock b/flake.lock index 014caf82..b862c3f7 100644 --- a/flake.lock +++ b/flake.lock @@ -81,7 +81,7 @@ "utils": "utils_2" }, "locked": { - "narHash": "sha256-JBTc4NiKuJ99+u8ey+1gQezW5pihAnfnyupBmdj4zUk=", + "narHash": "sha256-y0IZEAqpQpdGhxfc6REAT2PY2nEbikusUlXCRv264vI=", "path": "./lib", "type": "path" }, @@ -138,6 +138,21 @@ "type": "github" } }, + "flake-utils": { + "locked": { + "lastModified": 1619345332, + "narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "home": { "inputs": { "nixpkgs": [ @@ -336,17 +351,21 @@ } }, "utils_2": { + "inputs": { + "flake-utils": "flake-utils" + }, "locked": { - "lastModified": 1618868421, - "narHash": "sha256-vyoJhLV6cJ8/tWz+l9HZLIkb9Rd9esE7p+0RL6zDR6Y=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "eed214942bcfb3a8cc09eb3b28ca7d7221e44a94", + "lastModified": 1619438935, + "narHash": "sha256-B8OGqX9QBMW5G8DYTRdY0cb62ETaV0YxBayCZMiaVqQ=", + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "rev": "80b53eeda3102bb5aed31ec818c6485e35caffc3", "type": "github" }, "original": { - "owner": "numtide", - "repo": "flake-utils", + "owner": "gytis-ivaskevicius", + "ref": "staging", + "repo": "flake-utils-plus", "type": "github" } } diff --git a/lib/flake.lock b/lib/flake.lock index f70c491f..6942e2a8 100644 --- a/lib/flake.lock +++ b/lib/flake.lock @@ -52,6 +52,21 @@ "type": "github" } }, + "flake-utils": { + "locked": { + "lastModified": 1619345332, + "narHash": "sha256-qHnQkEp1uklKTpx3MvKtY6xzgcqXDsz5nLilbbuL+3A=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "2ebf2558e5bf978c7fb8ea927dfaed8fefab2e28", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "naersk": { "inputs": { "nixpkgs": [ @@ -127,17 +142,21 @@ } }, "utils_2": { + "inputs": { + "flake-utils": "flake-utils" + }, "locked": { - "lastModified": 1618868421, - "narHash": "sha256-vyoJhLV6cJ8/tWz+l9HZLIkb9Rd9esE7p+0RL6zDR6Y=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "eed214942bcfb3a8cc09eb3b28ca7d7221e44a94", + "lastModified": 1619438935, + "narHash": "sha256-B8OGqX9QBMW5G8DYTRdY0cb62ETaV0YxBayCZMiaVqQ=", + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "rev": "80b53eeda3102bb5aed31ec818c6485e35caffc3", "type": "github" }, "original": { - "owner": "numtide", - "repo": "flake-utils", + "owner": "gytis-ivaskevicius", + "ref": "staging", + "repo": "flake-utils-plus", "type": "github" } } diff --git a/lib/flake.nix b/lib/flake.nix index 65c0e20c..9025477a 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -5,7 +5,7 @@ { deploy.url = "github:serokell/deploy-rs"; devshell.url = "github:numtide/devshell"; - utils.url = "github:numtide/flake-utils"; + utils.url = "github:gytis-ivaskevicius/flake-utils-plus/staging"; }; outputs = inputs@{ self, nixpkgs, deploy, devshell, utils, ... }: From f8315a293c4585f89aef4f5815f94ceac7f28fd9 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 16:52:02 -0700 Subject: [PATCH 08/31] evalArgs: general api improvements drop default channel, it is confusing and complicates api don't take nixos input, using channels is better manually pass names for outputs to improve documentation --- lib/mkFlake/evalArgs.nix | 124 ++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/lib/mkFlake/evalArgs.nix b/lib/mkFlake/evalArgs.nix index cb90f614..5884dcfb 100644 --- a/lib/mkFlake/evalArgs.nix +++ b/lib/mkFlake/evalArgs.nix @@ -1,11 +1,12 @@ { lib }: -{ nixos, args }: +{ args }: let argOpts = with lib; { config, ... }: let inherit (lib) os; + cfg = config; inherit (config) self; maybeImport = obj: @@ -33,23 +34,19 @@ let # To simplify apply keys and improve type checking pathTo = elemType: with types; coercedTo path maybeImport elemType; - # Accepts single item or a list - # apply keys end up with a list - # This should not be used if expecting a nested list - # all lists will get flattened by this - coercedListOf = elemType: - let coerceToList = x: flatten (singleton x); in - with types; coercedTo elemType coerceToList (listOf elemType); + pathToListOf = elemType: with types; pathTo (listOf elemType); - pathToListOf = x: pathTo (coercedListOf x); + coercedListOf = elemType: with types; + coercedTo elemType (x: flatten (singleton x)) (listOf elemType); /* Submodules needed for API containers */ - channelsModule = { + channelsModule = { name, ... }: { options = with types; { input = mkOption { type = flakeType; - default = nixos; + default = cfg.inputs.${name}; + defaultText = escape [ "<" ">" ] "inputs."; description = '' nixpkgs flake input to use for this channel ''; @@ -57,22 +54,15 @@ let overlays = mkOption { type = pathToListOf overlayType; default = [ ]; - description = '' + description = escape [ "<" ">" ] '' overlays to apply to this channel these will get exported under the 'overlays' flake output as / ''; }; - externalOverlays = mkOption { - type = pathToListOf overlayType; - default = [ ]; - description = '' - overlays to apply to the channel that don't get exported to the flake output - useful to include overlays from inputs - ''; - }; config = mkOption { type = pathTo attrs; default = { }; + apply = lib.recursiveUpdate cfg.channelsConfig; description = '' nixpkgs config for this channel ''; @@ -82,21 +72,21 @@ let hostModule = { options = with types; { + # anything null in hosts gets filtered out by mkFlake system = mkOption { - type = systemType; - default = "x86_64-linux"; + type = nullOr systemType; + default = null; description = '' system for this host ''; }; channelName = mkOption { - type = types.enum (builtins.attrValues config.channels); - default = "nixpkgs"; + type = nullOr (types.enum (builtins.attrNames config.channels)); + default = null; description = '' Channel this host should follow ''; }; - }; }; @@ -105,7 +95,7 @@ let externalModulesModule = { options = { externalModules = mkOption { - type = pathToListOf moduleType; + type = with types; listOf moduleType; default = [ ]; description = '' The configuration for this host @@ -117,7 +107,7 @@ let modulesModule = { options = { modules = mkOption { - type = pathToListOf moduleType; + type = with types; coercedListOf moduleType; default = [ ]; description = '' modules to include @@ -126,13 +116,34 @@ let }; }; + exportModulesModule = name: { + options = { + modules = mkOption { + type = with types; pathToListOf + # check if the path evaluates to a proper module + # but this must be a path for the export to work + (addCheck path (x: moduleType.check (import x))); + default = [ ]; + description = '' + modules to include in all hosts and export to ${name}Modules output + ''; + }; + }; + }; + + + # Home-manager's configs get exported automatically from nixos.hosts # So there is no need for a host options in the home namespace # This is only needed for nixos - includeHostsModule = { name, ... }: { + includeHostsModule = name: { options = with types; { hostDefaults = mkOption { - type = submodule [ hostModule externalModulesModule modulesModule ]; + type = submodule [ + hostModule + externalModulesModule + (exportModulesModule name) + ]; default = { }; description = '' Defaults for all hosts. @@ -152,15 +163,11 @@ let }; # profiles and suites - which are profile collections - profilesModule = { name, ... }: { + profilesModule = { config, ... }: { options = with types; { profiles = mkOption { - type = coercedListOf path; + type = listOf path; default = [ ]; - apply = list: - # Merge a list of profiles to one set - let profileList = map (x: os.mkProfileAttrs (toString x)) list; in - foldl (a: b: a // b) { } profileList; description = "path to profiles folder that can be collected into suites"; }; suites = mkOption { @@ -185,6 +192,13 @@ let type = flakeType; description = "The flake to create the devos outputs for"; }; + inputs = mkOption { + type = attrsOf flakeType; + description = '' + inputs for this flake + used to set channel defaults and create registry + ''; + }; supportedSystems = mkOption { type = listOf str; default = lib.defaultSystems; @@ -192,31 +206,33 @@ let The systems supported by this flake ''; }; - channels = - let - default = { - nixpkgs = { - input = nixos; - }; - }; - in - mkOption { - type = attrsOf (submodule channelsModule); - inherit default; - apply = x: default // x; - description = '' - nixpkgs channels to create - ''; - }; - os = mkOption { - type = submodule [ includeHostsModule profilesModule ]; + channelsConfig = mkOption { + type = pathTo attrs; + default = { }; + description = '' + nixpkgs config for all channels + ''; + }; + channels = mkOption { + type = attrsOf (submodule channelsModule); + default = { }; + description = '' + nixpkgs channels to create + ''; + }; + nixos = mkOption { + type = submodule [ (includeHostsModule "nixos") profilesModule ]; default = { }; description = '' hosts, modules, suites, and profiles for nixos ''; }; home = mkOption { - type = submodule [ profilesModule modulesModule ]; + type = submodule [ + profilesModule + (exportModulesModule "home") + externalModulesModule + ]; default = { }; description = '' hosts, modules, suites, and profiles for home-manager From dceac02b36f418bc91f09760b3861dbee1c03848 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Sun, 25 Apr 2021 16:50:01 -0700 Subject: [PATCH 09/31] implement mkFlake for new api and rebase on fup --- lib/flake.nix | 3 +- lib/mkFlake/default.nix | 121 ++++++++++++++++----------- lib/mkFlake/evalOldArgs.nix | 162 ------------------------------------ 3 files changed, 72 insertions(+), 214 deletions(-) delete mode 100644 lib/mkFlake/evalOldArgs.nix diff --git a/lib/flake.nix b/lib/flake.nix index 9025477a..17e069c2 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -35,7 +35,6 @@ inherit deploy; }; evalArgs = import ./mkFlake/evalArgs.nix { lib = nixpkgs.lib // self; }; - evalOldArgs = import ./mkFlake/evalOldArgs.nix { lib = nixpkgs.lib // self; }; }; pkgs-lib = import ./pkgs-lib { @@ -83,7 +82,7 @@ mkFlakeDoc = pkgs.writeText "mkFlakeOptions.md" ( pkgs.nixosOptionsDoc { - inherit (lib.mkFlake.evalArgs { nixos = "nixos"; args = { }; }) options; + inherit (lib.mkFlake.evalArgs { args = { }; }) options; } ).optionsMDDoc; }; diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index d086283a..3d285c73 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -1,64 +1,85 @@ { lib, deploy }: let inherit (lib) os; + inherit (builtins) mapAttrs attrNames attrValues head isFunction; in -_: { self, inputs, nixos, ... } @ args: +_: { self, inputs, ... } @ args: let - cfg = ( - lib.mkFlake.evalOldArgs - { inherit self inputs args; } - ).config; - - multiPkgs = os.mkPkgs - { - inherit self inputs nixos; - inherit (cfg) extern overrides; - }; - - outputs = { - nixosConfigurations = os.mkHosts - { - inherit self inputs nixos multiPkgs; - inherit (cfg) extern suites overrides; - dir = cfg.hosts; - }; - - homeConfigurations = os.mkHomeConfigurations self.nixosConfigurations; - - nixosModules = cfg.modules; - - homeModules = cfg.userModules; - - overlay = cfg.packages; - inherit (cfg) overlays; - - deploy.nodes = os.mkNodes deploy self.nixosConfigurations; + config = lib.mkFlake.evalArgs { + args = lib.mkMerge [ args { _module.check = false; } ]; }; - systemOutputs = lib.eachDefaultSystem (system: - let - pkgs = multiPkgs.${system}; - pkgs-lib = lib.pkgs-lib.${system}; - # all packages that are defined in ./pkgs - legacyPackages = os.mkPackages { - inherit pkgs; - inherit (self) overlay overlays; - }; - in - { - checks = pkgs-lib.tests.mkChecks { + cfg = config.config; + + otherArguments = removeAttrs args (attrNames config.options); + + defaultModules = with lib.modules; [ + (hmDefaults { + inherit (cfg.home) suites; + modules = cfg.home.modules ++ cfg.home.externalModules; + }) + (globalDefaults { + inherit self inputs; + }) + ]; + + getDefaultChannel = channels: channels.${cfg.nixos.hostDefaults.channelName}; +in +lib.systemFlake (lib.recursiveUpdate + otherArguments + { + inherit self inputs; + inherit (cfg) channelsConfig supportedSystems; + + mkFlakeConfig = config; + + channels = mapAttrs + (name: channel: + channel // { + # pass channels if "overlay" has three arguments + overlaysBuilder = channels: lib.unifyOverlays channels channel.overlays; + } + ) cfg.channels; + + # the host arguments cannot exist for fup hostDefaults to work + # so evalArgs sets them to null by default and the null args are filtered out here + hosts = mapAttrs (_: host: lib.filterAttrs (_: arg: arg != null) host) cfg.nixos.hosts; + + hostDefaults = { + specialArgs.suites = cfg.nixos.suites; + modules = cfg.nixos.hostDefaults.modules + ++ cfg.nixos.hostDefaults.externalModules + ++ defaultModules; + builder = os.devosSystem { inherit self inputs; }; + inherit (cfg.nixos.hostDefaults) + channelName + system; + }; + + nixosModules = lib.exporter.modulesFromList cfg.nixos.hostDefaults.modules; + + homeModules = lib.exporter.modulesFromList cfg.home.modules; + homeConfigurations = os.mkHomeConfigurations self.nixosConfigurations; + + deploy.nodes = os.mkNodes deploy self.nixosConfigurations; + + overlays = lib.exporter.overlaysFromChannelsExporter { inherit (self) pkgs inputs; }; + + packagesBuilder = lib.builder.packagesFromOverlaysBuilderConstructor self.overlays; + + checksBuilder = channels: + lib.pkgs-lib.tests.mkChecks { + pkgs = getDefaultChannel channels; inherit (self.deploy) nodes; hosts = self.nixosConfigurations; homes = self.homeConfigurations; }; - inherit legacyPackages; - packages = lib.filterPackages system legacyPackages; - - devShell = pkgs-lib.shell; - }); -in -outputs // systemOutputs - + devShellBuilder = channels: + lib.pkgs-lib.shell { + pkgs = getDefaultChannel channels; + }; + } +) diff --git a/lib/mkFlake/evalOldArgs.nix b/lib/mkFlake/evalOldArgs.nix deleted file mode 100644 index c319d43a..00000000 --- a/lib/mkFlake/evalOldArgs.nix +++ /dev/null @@ -1,162 +0,0 @@ -{ lib }: - -{ self, inputs, args }: -let - argOpts = with lib; { config, options, ... }: - let - inherit (lib) os; - - inherit (config) self; - - inputAttrs = with types; functionTo attrs; - moduleType = with types; anything // { - inherit (submodule { }) check; - description = "valid module"; - }; - in - { - options = with types; { - self = mkOption { - type = addCheck attrs lib.isStorePath; - description = "The flake to create the devos outputs for"; - }; - nixos = mkOption { - type = addCheck attrs lib.isStorePath; - description = "The default nixpkgs channel of the devos"; - }; - inputs = mkOption { - type = addCheck attrs lib.isStorePath; - description = "All inptus of the devos"; - }; - hosts = mkOption { - type = path; - default = "${self}/hosts"; - defaultText = "\${self}/hosts"; - apply = toString; - description = '' - Path to directory containing host configurations that will be exported - to the 'nixosConfigurations' output. - ''; - }; - packages = mkOption { - # functionTo changes arg names which breaks flake check - type = types.anything // { - check = builtins.isFunction; - description = "Nixpkgs overlay"; - }; - default = (final: prev: { }); - defaultText = "(final: prev: {})"; - description = '' - Overlay for custom packages that will be included in treewide 'pkgs'. - This should follow the standard nixpkgs overlay format - two argument function - that returns an attrset. - These packages will be exported to the 'packages' and 'legacyPackages' outputs. - ''; - }; - modules = mkOption { - type = listOf moduleType; - default = [ ]; - apply = lib.pathsToImportedAttrs; - description = '' - list of modules to include in confgurations and export in 'nixosModules' output - ''; - }; - userModules = mkOption { - type = listOf moduleType; - default = [ ]; - apply = lib.pathsToImportedAttrs; - description = '' - list of modules to include in home-manager configurations and export in - 'homeModules' output - ''; - }; - profiles = mkOption { - type = path; - default = "${self}/profiles"; - defaultText = "\${self}/profiles"; - apply = x: os.mkProfileAttrs (toString x); - description = "path to profiles folder that can be collected into suites"; - }; - userProfiles = mkOption { - type = path; - default = "${self}/users/profiles"; - defaultText = "\${self}/users/profiles"; - apply = x: os.mkProfileAttrs (toString x); - description = "path to user profiles folder that can be collected into userSuites"; - }; - suites = - let - defaults = { user = { }; system = { }; }; - in - mkOption { - type = inputAttrs; - default = { ... }: defaults; - defaultText = "{ user = {}; system = {}; }"; - apply = suites: defaults // os.mkSuites { - inherit suites; - inherit (config) profiles users userProfiles; - }; - description = '' - Function with inputs 'users' and 'profiles' that returns attribute set - with user and system suites. The former for Home Manager and the latter - for nixos configurations. - These can be accessed through the 'suites' specialArg in each config system. - ''; - }; - users = mkOption { - type = path; - default = "${self}/users"; - defaultText = "\${self}/users"; - apply = x: os.mkProfileAttrs (toString x); - description = '' - path to folder containing profiles that define system users - ''; - }; - extern = - let - defaults = { - modules = [ ]; - overlays = [ ]; - specialArgs = { }; - userModules = [ ]; - userSpecialArgs = { }; - }; - in - mkOption { - type = inputAttrs; - default = { ... }: defaults; - defaultText = '' - { modules = []; overlays = []; specialArgs = []; userModules = []; userSpecialArgs = []; } - ''; - # So unneeded extern attributes can safely be deleted - apply = x: defaults // (x { inputs = inputs // self.inputs; }); - description = '' - Function with argument 'inputs' that contains all devos and ''${self}'s inputs. - The function should return an attribute set with modules, overlays, and - specialArgs to be included across nixos and home manager configurations. - Only attributes that are used should be returned. - ''; - }; - overlays = mkOption { - type = path; - default = "${self}/overlays"; - defaultText = "\${self}/overlays"; - apply = x: lib.pathsToImportedAttrs (lib.pathsIn (toString x)); - description = '' - path to folder containing overlays which will be applied to pkgs and exported in - the 'overlays' output - ''; - }; - overrides = mkOption rec { - type = attrs; - default = { modules = [ ]; disabledModules = [ ]; packages = _: _: _: { }; }; - defaultText = "{ modules = []; disabledModules = []; packages = {}; }"; - apply = x: default // x; - description = "attrset of packages and modules that will be pulled from nixpkgs master"; - }; - }; - }; -in -lib.evalModules { - modules = [ argOpts args ]; -} From c3d8805ad607935f033c737391978100d772bca0 Mon Sep 17 00:00:00 2001 From: David Arnold Date: Wed, 21 Apr 2021 22:44:15 -0500 Subject: [PATCH 10/31] update devos template to use new api --- extern/default.nix | 25 -------------- extern/overrides.nix | 33 ------------------- flake.lock | 40 +++++++++++------------ flake.nix | 78 ++++++++++++++++++++++++++++++++------------ overrides.nix | 26 +++++++++++++++ 5 files changed, 103 insertions(+), 99 deletions(-) delete mode 100644 extern/default.nix delete mode 100644 extern/overrides.nix create mode 100644 overrides.nix diff --git a/extern/default.nix b/extern/default.nix deleted file mode 100644 index 19c1bae6..00000000 --- a/extern/default.nix +++ /dev/null @@ -1,25 +0,0 @@ -{ inputs }: with inputs; -{ - modules = [ - home.nixosModules.home-manager - ci-agent.nixosModules.agent-profile - ]; - - overlays = [ - nur.overlay - pkgs.overlay - ]; - - # passed to all nixos modules - specialArgs = { - overrideModulesPath = "${override}/nixos/modules"; - hardware = nixos-hardware.nixosModules; - }; - - # added to home-manager - userModules = [ - ]; - - # passed to all home-manager modules - userSpecialArgs = { }; -} diff --git a/extern/overrides.nix b/extern/overrides.nix deleted file mode 100644 index 78e6ee85..00000000 --- a/extern/overrides.nix +++ /dev/null @@ -1,33 +0,0 @@ -# override defaults to nixpkgs/master -{ - # modules to pull from override, stable version is automatically disabled - modules = [ ]; - - # if a modules name changed in override, add the old name here - disabledModules = [ ]; - - # packages pulled from override - packages = pkgs: final: prev: { - inherit (pkgs) - cachix - dhall - discord - element-desktop - manix - nixpkgs-fmt - qutebrowser - signal-desktop - starship; - - haskellPackages = prev.haskellPackages.override { - overrides = hfinal: hprev: - let version = prev.lib.replaceChars [ "." ] [ "" ] prev.ghc.version; - in - { - # same for haskell packages, matching ghc versions - inherit (pkgs.haskell.packages."ghc${version}") - haskell-language-server; - }; - }; - }; -} diff --git a/flake.lock b/flake.lock index b862c3f7..90ffa98d 100644 --- a/flake.lock +++ b/flake.lock @@ -12,7 +12,7 @@ "nixos" ], "nixos-unstable": [ - "override" + "latest" ], "pre-commit-hooks-nix": "pre-commit-hooks-nix" }, @@ -33,7 +33,7 @@ "darwin": { "inputs": { "nixpkgs": [ - "override" + "latest" ] }, "locked": { @@ -81,7 +81,7 @@ "utils": "utils_2" }, "locked": { - "narHash": "sha256-y0IZEAqpQpdGhxfc6REAT2PY2nEbikusUlXCRv264vI=", + "narHash": "sha256-MvrBYZG6sZqpa8mTg4RYeD9aezYbVppBnslRyH7qZys=", "path": "./lib", "type": "path" }, @@ -173,10 +173,24 @@ "type": "github" } }, + "latest": { + "locked": { + "lastModified": 1619400530, + "narHash": "sha256-7ZO7B+b9i1wFbHw62EFT+iwuBBpXeA/fcHlR63Z4J0w=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e8dc8adab655eb27957859c62bef11484b53f639", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, "naersk": { "inputs": { "nixpkgs": [ - "override" + "latest" ] }, "locked": { @@ -197,7 +211,7 @@ "naersk_2": { "inputs": { "nixpkgs": [ - "override" + "latest" ] }, "locked": { @@ -274,20 +288,6 @@ "type": "indirect" } }, - "override": { - "locked": { - "lastModified": 1615926763, - "narHash": "sha256-yeq8A3EPNuQVlsxlEQrIRsklfJwJK0Us6jtcG/u8wNs=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "b702a56d417647de4090ac56c0f18bdc7e646610", - "type": "github" - }, - "original": { - "id": "nixpkgs", - "type": "indirect" - } - }, "pkgs": { "inputs": { "nixpkgs": [ @@ -327,11 +327,11 @@ "devos": "devos", "flake-compat": "flake-compat_2", "home": "home", + "latest": "latest", "naersk": "naersk_2", "nixos": "nixos", "nixos-hardware": "nixos-hardware", "nur": "nur", - "override": "override", "pkgs": "pkgs" } }, diff --git a/flake.nix b/flake.nix index bad78f1f..5591fb04 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,7 @@ inputs = { nixos.url = "nixpkgs/nixos-unstable"; - override.url = "nixpkgs"; + latest.url = "nixpkgs"; devos.url = "path:./lib"; # TODO: outfactor into separate repo devos.inputs = { nixpkgs.follows = "nixos"; @@ -17,38 +17,74 @@ ci-agent = { url = "github:hercules-ci/hercules-ci-agent"; - inputs = { nix-darwin.follows = "darwin"; flake-compat.follows = "flake-compat"; nixos-20_09.follows = "nixos"; nixos-unstable.follows = "override"; }; + inputs = { nix-darwin.follows = "darwin"; flake-compat.follows = "flake-compat"; nixos-20_09.follows = "nixos"; nixos-unstable.follows = "latest"; }; }; darwin.url = "github:LnL7/nix-darwin"; - darwin.inputs.nixpkgs.follows = "override"; + darwin.inputs.nixpkgs.follows = "latest"; flake-compat.url = "github:BBBSnowball/flake-compat/pr-1"; flake-compat.flake = false; home.url = "github:nix-community/home-manager"; home.inputs.nixpkgs.follows = "nixos"; naersk.url = "github:nmattia/naersk"; - naersk.inputs.nixpkgs.follows = "override"; + naersk.inputs.nixpkgs.follows = "latest"; nixos-hardware.url = "github:nixos/nixos-hardware"; pkgs.url = "path:./pkgs"; pkgs.inputs.nixpkgs.follows = "nixos"; }; - outputs = inputs@{ self, devos, nixos, nur, ... }: + outputs = inputs@{ self, pkgs, devos, nixos, ci-agent, home, nixos-hardware, nur, ... }: devos.lib.mkFlake { - inherit self inputs nixos; - hosts = ./hosts; - packages = import ./pkgs; - suites = import ./profiles/suites.nix; - extern = import ./extern; - overrides = import ./extern/overrides.nix; - overlays = ./overlays; - profiles = ./profiles; - userProfiles = ./users/profiles; - modules = import ./modules/module-list.nix; - userModules = import ./users/modules/module-list.nix; - } // { - defaultTemplate = self.templates.flk; - templates.flk.path = ./.; - templates.flk.description = "flk template"; - }; + inherit self inputs; + + channelsConfig = { allowUnfree = true; }; + + channels = { + nixos = { + overlays = nixos.lib.flatten [ + (devos.lib.pathsIn ./overlays) + pkgs.overlay + ./overrides.nix # from "latest" channel + nur.overlay + ]; + }; + latest = { }; + }; + + nixos = { + hostDefaults = { + system = "x86_64-linux"; + channelName = "nixos"; + modules = ./modules/module-list.nix; + externalModules = [ + ci-agent.nixosModules.agent-profile + home.nixosModules.home-manager + ]; + }; + hosts = { + NixOS = { + modules = ./hosts/NixOS.nix; + }; + }; + profiles = [ ./profiles ./users ]; + suites = { profiles, users, ... }: with profiles; { + base = [ core users.nixos users.root ]; + }; + }; + + home = { + modules = ./users/modules/module-list.nix; + externalModules = [ ]; + profiles = [ ./users/profiles ]; + suites = { profiles, ... }: with profiles; { + base = [ direnv git ]; + }; + }; + + #defaultTemplate = self.templates.flk; + templates.flk.path = ./.; + templates.flk.description = "flk template"; + + } + ; } diff --git a/overrides.nix b/overrides.nix new file mode 100644 index 00000000..bb3cf68b --- /dev/null +++ b/overrides.nix @@ -0,0 +1,26 @@ +channels: final: prev: { + + inherit (channels.latest) + cachix + dhall + discord + element-desktop + manix + nixpkgs-fmt + qutebrowser + signal-desktop + starship; + + + haskellPackages = prev.haskellPackages.override { + overrides = hfinal: hprev: + let version = prev.lib.replaceChars [ "." ] [ "" ] prev.ghc.version; + in + { + # same for haskell packages, matching ghc versions + inherit (channels.latest.haskell.packages."ghc${version}") + haskell-language-server; + }; + }; + +} From 9f31d5d6d1e5c204fcf5ce938a8ae95528dddf4f Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 12:20:16 -0700 Subject: [PATCH 11/31] mkFlake: use inputs argument not self.inputs --- lib/mkFlake/default.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index 3d285c73..ebeb86c2 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -65,7 +65,10 @@ lib.systemFlake (lib.recursiveUpdate deploy.nodes = os.mkNodes deploy self.nixosConfigurations; - overlays = lib.exporter.overlaysFromChannelsExporter { inherit (self) pkgs inputs; }; + overlays = lib.exporter.overlaysFromChannelsExporter { + inherit inputs; + inherit (self) pkgs; + }; packagesBuilder = lib.builder.packagesFromOverlaysBuilderConstructor self.overlays; From 37820fc2148051117feaa684fb52238cde71d25f Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 12:29:18 -0700 Subject: [PATCH 12/31] explain overlay exporting inputs workaround --- lib/mkFlake/default.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index ebeb86c2..cd8d0377 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -66,6 +66,10 @@ lib.systemFlake (lib.recursiveUpdate deploy.nodes = os.mkNodes deploy self.nixosConfigurations; overlays = lib.exporter.overlaysFromChannelsExporter { + /* since we can't detect overlays owned by self + we have to filter out ones exported by the inputs + optimally we would want a solution for NixOS/nix#4740 + */ inherit inputs; inherit (self) pkgs; }; From b766c693abd5530c1dc4fd16cd229addca7c3219 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 13:21:40 -0700 Subject: [PATCH 13/31] add pkgs overlay, pkgs.overlay is just for srcs --- flake.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 5591fb04..1e23cedb 100644 --- a/flake.nix +++ b/flake.nix @@ -43,7 +43,8 @@ nixos = { overlays = nixos.lib.flatten [ (devos.lib.pathsIn ./overlays) - pkgs.overlay + ./pkgs/default.nix + pkgs.overlay # for `srcs` ./overrides.nix # from "latest" channel nur.overlay ]; From 2a7d9e71096746cd19b56cdbf61ba1c910fb6013 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 13:30:10 -0700 Subject: [PATCH 14/31] fix suites test to match new mkSuites --- lib/tests/lib.nix | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/lib/tests/lib.nix b/lib/tests/lib.nix index 66264787..e992df67 100644 --- a/lib/tests/lib.nix +++ b/lib/tests/lib.nix @@ -71,23 +71,19 @@ lib.runTests { }; }; - testSuites = - let - profiles = os.mkProfileAttrs (toString ./profiles); - users = ""; - userProfiles = ""; - suites = { profiles, ... }: { - system.bar = [ profiles.foo ]; - }; - in - { - expr = os.mkSuites { inherit profiles users userProfiles suites; }; - expected = { - system = { - bar = [ profiles.foo.default ]; - allProfiles = [ profiles.foo.default profiles.t.default ]; - allUsers = [ ]; - }; + testSuites = { + expr = os.mkSuites { + suites = { profiles, ... }: with profiles; { + bar = [ foo ]; }; + profiles = [ (./profiles) ]; }; + expected = { + bar = [ (toString ./profiles/foo) ]; + allProfiles = [ + (toString ./profiles/foo) + (toString ./profiles/t) + ]; + }; + }; } From ffe4836e35e8b4a1ef2d99292c1ea4a3df6ad821 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 18:29:05 -0700 Subject: [PATCH 15/31] update doc to match new template format and logic --- doc/concepts/extern.md | 47 ++++++++++++++++++--------------------- doc/concepts/hosts.md | 38 ++++++++++++++++++------------- doc/concepts/overrides.md | 42 ++++++++++++++-------------------- doc/concepts/suites.md | 8 ++++++- doc/outputs/overlays.md | 2 +- doc/start/from-nixos.md | 12 ++++++++-- doc/tests.md | 2 +- 7 files changed, 80 insertions(+), 71 deletions(-) diff --git a/doc/concepts/extern.md b/doc/concepts/extern.md index 3b269122..171d8c58 100644 --- a/doc/concepts/extern.md +++ b/doc/concepts/extern.md @@ -1,45 +1,42 @@ # External Art When you need to use a module, overlay, or pass a value from one of your inputs -to the rest of your NixOS configuration, [extern][extern] is where you do it. +to the rest of your NixOS configuration, you can make use of a couple arguments. +It is encouraged to add external art directly in your `flake.nix` so the file +represents a complete dependency overview of your flake. -Modules and overlays are self explanatory, and the `specialArgs` attribute is -used to extend the arguments passed to all NixOS modules, allowing for -arbitrary values to be passed from flake inputs to the rest of your -configuration. +## Overlays +External overlays can directly be added to a channel's `overlays` list. -## Home Manager -There is also an `hmModules` attribute set for pulling home-manager modules in -from the outside world: - -### Declare: flake.nix: ```nix { - inputs.doom-emacs.url = "github:vlaci/nix-doom-emacs"; + channels.nixos.overlays = [ inputs.agenix.overlay ]; } ``` +These overlays will be automatically filtered by inspecting the `inputs` argument. -extern/default.nix: +## Modules +There is a dedicated `nixos.hostDefaults.externalModules` argument for external +modules. + +flake.nix: ```nix -with inputs; { - hmModules = { - doom-emacs = doom-emacs.hmModule; - }; + nixos.hostDefaults.externalModules = [ inputs.agenix.nixosModules.age ]; } ``` -### Use: -users/nixos/default.nix: +## Home Manager +Since there isn't a `hosts` concept for home-manager, externalModules is just a +top-level argument in the `home` namespace. + +flake.nix: ```nix -{ hmModules, ... }: { - home-manager.users.nixos = { - imports = [ hmModules.doom-emacs ] ; - - programs.doom-emacs.enable = true; - }; + home.externalModules = [ doom-emacs = doom-emacs.hmModule ]; } ``` -[extern]: https://github.com/divnix/devos/tree/core/extern/default.nix +> ##### Note: +> The optimal solution would be to automatically export modules that were created in +> your flake. But this is not possible due to NixOS/nix#4740. diff --git a/doc/concepts/hosts.md b/doc/concepts/hosts.md index 0a74dd12..770fa51b 100644 --- a/doc/concepts/hosts.md +++ b/doc/concepts/hosts.md @@ -1,19 +1,18 @@ # Hosts Nix flakes contain an output called `nixosConfigurations` declaring an -attribute set of valid NixOS systems. To simplify the management and creation -of these hosts, devos automatically imports every _.nix_ file inside this -directory to the mentioned attribute set, applying the projects defaults to -each. The only hard requirement is that the file contain a valid NixOS module. +attribute set of valid NixOS systems. To create hosts, you can use the +`nixos.hosts` argument and pass `modules` to each host. Host-specific modules +typically go in the `hosts` folder of the template. -As an example, a file `hosts/system.nix` will be available via the flake -output `nixosConfigurations.system`. You can have as many hosts as you want -and all of them will be automatically imported based on their name. +Each host should follow a certain channel to define the `pkgs` of that host. +You can use the `nixos.hostDefaults` to set defaults and global modules for all +hosts. For each host, the configuration automatically sets the `networking.hostName` -attribute to the name of the file minus the _.nix_ extension. This is for -convenience, since `nixos-rebuild` automatically searches for a configuration -matching the current systems hostname if one is not specified explicitly. +attribute to the name of the host. This is for convenience, since `nixos-rebuild` +automatically searches for a configuration matching the current systems hostname +if one is not specified explicitly. It is recommended that the host modules only contain configuration information specific to a particular piece of hardware. Anything reusable across machines @@ -22,12 +21,8 @@ is best saved for [profile modules](./profiles.md). This is a good place to import sets of profiles, called [suites](./suites.md), that you intend to use on your machine. -Additionally, this is the perfect place to import anything you might need from -the [nixos-hardware][nixos-hardware] repository. - -> ##### _Note:_ -> Set `nixpkgs.system` to the architecture of this host, default is "x86_64-linux". -> Keep in mind that not all packages are available for all architectures. +Additionally, you can pass modules from [nixos-hardware][nixos-hardware] in the +`modules` argument for relevant hosts. ## Example @@ -44,4 +39,15 @@ hosts/librem.nix: } ``` +flake.nix +```nix +{ + nixos.hosts.librem = { + system = "aarch64-linux"; + modules = ./hosts/librem.nix; + }; +} +``` + + [nixos-hardware]: https://github.com/NixOS/nixos-hardware diff --git a/doc/concepts/overrides.md b/doc/concepts/overrides.md index 28194cd1..78b50fd1 100644 --- a/doc/concepts/overrides.md +++ b/doc/concepts/overrides.md @@ -1,47 +1,39 @@ # Overrides -By default, the NixOS systems are based on unstable. While it is trivial to -change this to a stable release, or any other branch of nixpkgs by -changing the flake url, sometimes all we want is a single package from another -branch. +Each NixOS host follows one channel. But many times it is useful to get packages +or modules from different channels. -This is what the overrides are for. By default, they are pulled directly from -nixpkgs/master, but you can change the `override` flake input url to -nixos-unstable, or even a specific sha revision. - -They are defined in the `extern/overrides.nix` file. +This is what the overrides are for. You can make use of the `overrides.nix` to +override specific packages to be pulled from other channels. Any overlay may get +`channels` as their first argument. ## Example ### Packages The override packages are defined as a regular overlay with an extra arguement -`pkgs`. This refers to the packages built from the `override` flake. +`channels`. This refers to all channels defined in `flake.nix`. -Pulling the manix package from the override flake: +Pulling the manix package from the latest flake: ```nix -{ - packages = pkgs: final: prev: { - inherit (pkgs) manix; - }; +channels: final: prev: { + inherit (pkgs.latest) manix; } ``` ### Modules -You can also pull modules from override. Simply specify their path relative to -the nixpkgs [modules][nixpkgs-modules] directory. The old version will be added -to `disabledModules` and the new version imported into the configuration. +You can also pull modules from other channels. All modules have access to the +`modulesPath` for each channel as `ModulesPath`. And you can use +`disabledModules` to remove modules from the current channel. -Pulling the zsh module from the override flake: +Pulling the zsh module from the latest flake: ```nix -{ - modules = [ "programs/zsh/zsh.nix" ]; +{ latestModulesPath }: { + modules = [ "${latestModulesPath}/programs/zsh/zsh.nix" ]; + disabledModules = [ "programs/zsh/zsh.nix" ]; } ``` > ##### _Note:_ -> Sometimes a modules name will change from one branch to another. This is what -> the `disabledModules` list is for. If the module name changes, the old -> version will not automatically be disabled, so simply put it's old name in -> this list to disable it. +> Sometimes a modules name will change from one branch to another. [nixpkgs-modules]: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules diff --git a/doc/concepts/suites.md b/doc/concepts/suites.md index e6a8bff7..5c0d5909 100644 --- a/doc/concepts/suites.md +++ b/doc/concepts/suites.md @@ -6,7 +6,13 @@ profiles. For good examples, check out the suites defined in the community In the future, we will use suites as a mechanism for deploying various machine types which don't depend on hardware, such as vm's and containers. -They are defined in `profiles/suites.nix`. +They are defined with the `suites` argument in either `home` or `nixos` namespace. +Suites should be passed as a function that take profiles as an argument. + +The profiles are passed based on the folder names and list passed to the relevant +`profiles` argument. In the template's flake.nix `profiles` is set as +`[ ./profiles ./users ]` and that corresponds to the `{ profiles, users }` argument +pattern. ## Definition ```nix diff --git a/doc/outputs/overlays.md b/doc/outputs/overlays.md index d71b4597..f463d1a7 100644 --- a/doc/outputs/overlays.md +++ b/doc/outputs/overlays.md @@ -4,7 +4,7 @@ we want to keep the process as simple and straightforward as possible. Any _.nix_ files declared in this directory will be assumed to be a valid overlay, and will be automatically imported into all [hosts](../concepts/hosts.md), and -exported via `overlays.` _as well as_ +exported via `overlays./` _as well as_ `packages..` (for valid systems), so all you have to do is write it. diff --git a/doc/start/from-nixos.md b/doc/start/from-nixos.md index bbb0e551..9b0b3f57 100644 --- a/doc/start/from-nixos.md +++ b/doc/start/from-nixos.md @@ -10,10 +10,18 @@ flk up This will make a new file `hosts/up-$(hostname).nix`, which you can edit to your liking. +You must then add a host to `nixos.hosts` in flake.nix: +```nix +{ + nixos.hosts = { + modules = hosts/NixOS.nix; + }; +} +``` + Make sure your `i18n.defaultLocale` and `time.timeZone` are set properly for your region. Keep in mind that `networking.hostName` with be automatically -set to the filename of your hosts file, so `hosts/my-host.nix` will have the -hostname `my-host`. +set to the name of your host; Now might be a good time to read the docs on [suites](../concepts/suites.md) and [profiles](../concepts/profiles.md) and add or create any that you need. diff --git a/doc/tests.md b/doc/tests.md index 033d75af..f6fd7fe9 100644 --- a/doc/tests.md +++ b/doc/tests.md @@ -7,7 +7,7 @@ configuration, and, optionally, run them in ## Lib Tests You can easily write tests for your own library functions in the -___tests/lib.nix___ file and they will be run on every `nix flake check` or +lib/___tests/lib.nix___ file and they will be run on every `nix flake check` or during a CI run. ## Unit Tests From a6344faa9afd17efb8b2069c2332ac302d98944e Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 19:30:55 -0700 Subject: [PATCH 16/31] update fup to fix infinite recursion error --- flake.lock | 8 ++++---- lib/flake.lock | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/flake.lock b/flake.lock index 90ffa98d..13482c4f 100644 --- a/flake.lock +++ b/flake.lock @@ -81,7 +81,7 @@ "utils": "utils_2" }, "locked": { - "narHash": "sha256-MvrBYZG6sZqpa8mTg4RYeD9aezYbVppBnslRyH7qZys=", + "narHash": "sha256-clwJnNLVOASak2CfkWu3Yztb1uWwtndY4VLDWEa9R3s=", "path": "./lib", "type": "path" }, @@ -355,11 +355,11 @@ "flake-utils": "flake-utils" }, "locked": { - "lastModified": 1619438935, - "narHash": "sha256-B8OGqX9QBMW5G8DYTRdY0cb62ETaV0YxBayCZMiaVqQ=", + "lastModified": 1619480667, + "narHash": "sha256-KBiMpZcCv7D3wQ51ow7Sq8Xl01hDiRp5f7Py93CeD40=", "owner": "gytis-ivaskevicius", "repo": "flake-utils-plus", - "rev": "80b53eeda3102bb5aed31ec818c6485e35caffc3", + "rev": "be032a4396ad4cd7ea9bb733db8e456ec339ac9c", "type": "github" }, "original": { diff --git a/lib/flake.lock b/lib/flake.lock index 6942e2a8..eda785b8 100644 --- a/lib/flake.lock +++ b/lib/flake.lock @@ -146,11 +146,11 @@ "flake-utils": "flake-utils" }, "locked": { - "lastModified": 1619438935, - "narHash": "sha256-B8OGqX9QBMW5G8DYTRdY0cb62ETaV0YxBayCZMiaVqQ=", + "lastModified": 1619480667, + "narHash": "sha256-KBiMpZcCv7D3wQ51ow7Sq8Xl01hDiRp5f7Py93CeD40=", "owner": "gytis-ivaskevicius", "repo": "flake-utils-plus", - "rev": "80b53eeda3102bb5aed31ec818c6485e35caffc3", + "rev": "be032a4396ad4cd7ea9bb733db8e456ec339ac9c", "type": "github" }, "original": { From b6c00e74e7c6e574ee72d40141a36adff2ebeccc Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 19:33:31 -0700 Subject: [PATCH 17/31] set add self and hosts module arguments --- lib/modules.nix | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/modules.nix b/lib/modules.nix index 2cd965ff..6e2a3525 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -41,6 +41,12 @@ } ''; + _module.args = { + inherit self; + hosts = builtins.mapAttrs (_: host: host.config) + (removeAttrs self.nixosConfigurations [ config.networking.hostName ]); + }; + system.configurationRevision = lib.mkIf (self ? rev) self.rev; }; From e9675330a7b3717cf6abf090a34b5bf1ac23201a Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 19:34:18 -0700 Subject: [PATCH 18/31] add cachix to base suite to follow the new api --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 1e23cedb..aca677b9 100644 --- a/flake.nix +++ b/flake.nix @@ -69,7 +69,7 @@ }; profiles = [ ./profiles ./users ]; suites = { profiles, users, ... }: with profiles; { - base = [ core users.nixos users.root ]; + base = [ cachix core users.nixos users.root ]; }; }; From 278ae0e108633b70214d1176ed38883910f46e68 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 21:32:26 -0700 Subject: [PATCH 19/31] set _module.check in evalArgs instead of mkFlake this makes more sense since evalArgs is the module and it makes the code cleaner --- lib/mkFlake/default.nix | 2 +- lib/mkFlake/evalArgs.nix | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index cd8d0377..45d99bd2 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -8,7 +8,7 @@ _: { self, inputs, ... } @ args: let config = lib.mkFlake.evalArgs { - args = lib.mkMerge [ args { _module.check = false; } ]; + inherit args; }; cfg = config.config; diff --git a/lib/mkFlake/evalArgs.nix b/lib/mkFlake/evalArgs.nix index 5884dcfb..1a15dc8e 100644 --- a/lib/mkFlake/evalArgs.nix +++ b/lib/mkFlake/evalArgs.nix @@ -187,6 +187,10 @@ let }; in { + # this does not get propagated to submodules + # to allow passing flake outputs directly to mkFlake + config._module.check = false; + options = with types; { self = mkOption { type = flakeType; From c41d3eed0662956c4ad3afd958ebea0be29fcd89 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 21:32:57 -0700 Subject: [PATCH 20/31] drop debugging related mkFlakeConfig output was only meant for debugging, not meant to be commited --- lib/mkFlake/default.nix | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index 45d99bd2..bcab7a13 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -33,8 +33,6 @@ lib.systemFlake (lib.recursiveUpdate inherit self inputs; inherit (cfg) channelsConfig supportedSystems; - mkFlakeConfig = config; - channels = mapAttrs (name: channel: channel // { From 064ba88cdf6ce391cdbe3e4df72363276dbb5ebd Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Mon, 26 Apr 2021 21:38:27 -0700 Subject: [PATCH 21/31] improve, build, and add mkFlake options doc --- doc/mkFlakeOptions.md | 407 +++++++++++++++++++++++++++++++++++++++ lib/mkFlake/evalArgs.nix | 25 ++- 2 files changed, 425 insertions(+), 7 deletions(-) create mode 100644 doc/mkFlakeOptions.md diff --git a/doc/mkFlakeOptions.md b/doc/mkFlakeOptions.md new file mode 100644 index 00000000..42b1f60f --- /dev/null +++ b/doc/mkFlakeOptions.md @@ -0,0 +1,407 @@ +## channels +nixpkgs channels to create + + +*_Type_*: +attribute set of submodules + + +*_Default_* +``` +{} +``` + + + + +## channels.\.config +nixpkgs config for this channel + + +*_Type_*: +attribute set or path convertible to it + + +*_Default_* +``` +{} +``` + + + + +## channels.\.input +nixpkgs flake input to use for this channel + + +*_Type_*: +nix flake + + +*_Default_* +``` +"inputs.\\" +``` + + + + +## channels.\.overlays +overlays to apply to this channel +these will get exported under the 'overlays' flake output +as \/\ and any overlay pulled from ${inputs} +will be filtered out + + +*_Type_*: +list of valid Nixpkgs overlay or path convertible to its or path convertible to it + + +*_Default_* +``` +[] +``` + + + + +## channelsConfig +nixpkgs config for all channels + + +*_Type_*: +attribute set or path convertible to it + + +*_Default_* +``` +{} +``` + + + + +## home +hosts, modules, suites, and profiles for home-manager + + +*_Type_*: +submodule + + +*_Default_* +``` +{} +``` + + + + +## home.externalModules +modules to include that won't be exported +meant importing modules from external flakes + + +*_Type_*: +list of valid module or path convertible to its + + +*_Default_* +``` +[] +``` + + + + +## home.modules +modules to include in all hosts and export to homeModules output + + +*_Type_*: +list of paths or path convertible to it + + +*_Default_* +``` +[] +``` + + + + +## home.profiles +profile folders that can be collected into suites +the name of the argument passed to suites is based +on the folder name. +[ ./profiles ] => { profiles }: + + +*_Type_*: +list of paths + + +*_Default_* +``` +[] +``` + + + + +## home.suites +Function that takes profiles and returns suites for this config system +These can be accessed through the 'suites' special argument. + + +*_Type_*: +function that evaluates to a(n) attrs or path convertible to it + + +*_Default_* +``` +"" +``` + + + + +## inputs +inputs for this flake +used to set channel defaults and create registry + + +*_Type_*: +attribute set of nix flakes + + + + + + +## nixos +hosts, modules, suites, and profiles for nixos + + +*_Type_*: +submodule + + +*_Default_* +``` +{} +``` + + + + +## nixos.hostDefaults +Defaults for all hosts. +the modules passed under hostDefaults will be exported +to the 'nixosModules' flake output. +They will also be added to all hosts. + + +*_Type_*: +submodule + + +*_Default_* +``` +{} +``` + + + + +## nixos.hostDefaults.channelName +Channel this host should follow + + +*_Type_*: +a channel defined in `channels` + + +*_Default_* +``` +null +``` + + + + +## nixos.hostDefaults.externalModules +modules to include that won't be exported +meant importing modules from external flakes + + +*_Type_*: +list of valid module or path convertible to its + + +*_Default_* +``` +[] +``` + + + + +## nixos.hostDefaults.modules +modules to include in all hosts and export to nixosModules output + + +*_Type_*: +list of paths or path convertible to it + + +*_Default_* +``` +[] +``` + + + + +## nixos.hostDefaults.system +system for this host + + +*_Type_*: +system defined in `supportedSystems` + + +*_Default_* +``` +null +``` + + + + +## nixos.hosts +configurations to include in the nixosConfigurations output + + +*_Type_*: +attribute set of submodules + + +*_Default_* +``` +{} +``` + + + + +## nixos.hosts.\.channelName +Channel this host should follow + + +*_Type_*: +a channel defined in `channels` + + +*_Default_* +``` +null +``` + + + + +## nixos.hosts.\.modules +modules to include + + +*_Type_*: +list of valid module or path convertible to its or valid module or path convertible to it convertible to it + + +*_Default_* +``` +[] +``` + + + + +## nixos.hosts.\.system +system for this host + + +*_Type_*: +system defined in `supportedSystems` + + +*_Default_* +``` +null +``` + + + + +## nixos.profiles +profile folders that can be collected into suites +the name of the argument passed to suites is based +on the folder name. +[ ./profiles ] => { profiles }: + + +*_Type_*: +list of paths + + +*_Default_* +``` +[] +``` + + + + +## nixos.suites +Function that takes profiles and returns suites for this config system +These can be accessed through the 'suites' special argument. + + +*_Type_*: +function that evaluates to a(n) attrs or path convertible to it + + +*_Default_* +``` +"" +``` + + + + +## self +The flake to create the devos outputs for + +*_Type_*: +nix flake + + + + + + +## supportedSystems +The systems supported by this flake + + +*_Type_*: +list of strings + + +*_Default_* +``` +["aarch64-linux","i686-linux","x86_64-darwin","x86_64-linux"] +``` + + + diff --git a/lib/mkFlake/evalArgs.nix b/lib/mkFlake/evalArgs.nix index 1a15dc8e..55b37950 100644 --- a/lib/mkFlake/evalArgs.nix +++ b/lib/mkFlake/evalArgs.nix @@ -56,7 +56,9 @@ let default = [ ]; description = escape [ "<" ">" ] '' overlays to apply to this channel - these will get exported under the 'overlays' flake output as / + these will get exported under the 'overlays' flake output + as / and any overlay pulled from ''\${inputs} + will be filtered out ''; }; config = mkOption { @@ -74,14 +76,18 @@ let options = with types; { # anything null in hosts gets filtered out by mkFlake system = mkOption { - type = nullOr systemType; + type = (nullOr systemType) // { + description = "system defined in `supportedSystems`"; + }; default = null; description = '' system for this host ''; }; channelName = mkOption { - type = nullOr (types.enum (builtins.attrNames config.channels)); + type = (nullOr (types.enum (builtins.attrNames config.channels))) // { + description = "a channel defined in `channels`"; + }; default = null; description = '' Channel this host should follow @@ -98,7 +104,8 @@ let type = with types; listOf moduleType; default = [ ]; description = '' - The configuration for this host + modules to include that won't be exported + meant importing modules from external flakes ''; }; }; @@ -168,7 +175,12 @@ let profiles = mkOption { type = listOf path; default = [ ]; - description = "path to profiles folder that can be collected into suites"; + description = '' + profile folders that can be collected into suites + the name of the argument passed to suites is based + on the folder name. + [ ./profiles ] => { profiles }: + ''; }; suites = mkOption { type = pathTo (functionTo attrs); @@ -178,8 +190,7 @@ let inherit (config) profiles; }; description = '' - Function with the input of 'profiles' that returns an attribute set - with the suites for this config system. + Function that takes profiles and returns suites for this config system These can be accessed through the 'suites' special argument. ''; }; From 466304c8cd6d45a62b0e0c82638ce13fc9badaa7 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 08:01:46 -0700 Subject: [PATCH 22/31] improve passing host and channel arguments to fup we need to filter out arguments that are added in the devos api also anything thats null in either hostDefaults and hosts has to be removed --- flake.lock | 8 ++++---- lib/flake.lock | 6 +++--- lib/mkFlake/default.nix | 32 ++++++++++++++++++-------------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/flake.lock b/flake.lock index 13482c4f..6d239faa 100644 --- a/flake.lock +++ b/flake.lock @@ -81,7 +81,7 @@ "utils": "utils_2" }, "locked": { - "narHash": "sha256-clwJnNLVOASak2CfkWu3Yztb1uWwtndY4VLDWEa9R3s=", + "narHash": "sha256-TOrVXGFk5rt1Wn14ja2spg44NuZnFM/V6qguQfO+8Kc=", "path": "./lib", "type": "path" }, @@ -355,11 +355,11 @@ "flake-utils": "flake-utils" }, "locked": { - "lastModified": 1619480667, - "narHash": "sha256-KBiMpZcCv7D3wQ51ow7Sq8Xl01hDiRp5f7Py93CeD40=", + "lastModified": 1619532520, + "narHash": "sha256-+xIFAW5J0AcxwAflAX1gg/C8kfaqeZbS4XAZusCrZPY=", "owner": "gytis-ivaskevicius", "repo": "flake-utils-plus", - "rev": "be032a4396ad4cd7ea9bb733db8e456ec339ac9c", + "rev": "8eb7f9206713a528174c20c5133521dc37e2bfb1", "type": "github" }, "original": { diff --git a/lib/flake.lock b/lib/flake.lock index eda785b8..ebf5e6d3 100644 --- a/lib/flake.lock +++ b/lib/flake.lock @@ -146,11 +146,11 @@ "flake-utils": "flake-utils" }, "locked": { - "lastModified": 1619480667, - "narHash": "sha256-KBiMpZcCv7D3wQ51ow7Sq8Xl01hDiRp5f7Py93CeD40=", + "lastModified": 1619532520, + "narHash": "sha256-+xIFAW5J0AcxwAflAX1gg/C8kfaqeZbS4XAZusCrZPY=", "owner": "gytis-ivaskevicius", "repo": "flake-utils-plus", - "rev": "be032a4396ad4cd7ea9bb733db8e456ec339ac9c", + "rev": "8eb7f9206713a528174c20c5133521dc37e2bfb1", "type": "github" }, "original": { diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index bcab7a13..7b12cf41 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -25,35 +25,39 @@ let }) ]; + stripChannel = channel: removeAttrs channel [ + # arguments in our channels api that shouldn't be passed to fup + "overlays" + ]; getDefaultChannel = channels: channels.${cfg.nixos.hostDefaults.channelName}; + + # evalArgs sets channelName and system to null by default + # but for proper default handling in fup, null args have to be removed + stripHost = args: removeAttrs (lib.filterAttrs (_: arg: arg != null) args) [ + # arguments in our hosts/hostDefaults api that shouldn't be passed to fup + "externalModules" + ]; + hosts = lib.mapAttrs (_: stripHost) cfg.nixos.hosts; + hostDefaults = stripHost cfg.nixos.hostDefaults; in lib.systemFlake (lib.recursiveUpdate otherArguments { - inherit self inputs; + inherit self inputs hosts; inherit (cfg) channelsConfig supportedSystems; channels = mapAttrs (name: channel: - channel // { + stripChannel (channel // { # pass channels if "overlay" has three arguments overlaysBuilder = channels: lib.unifyOverlays channels channel.overlays; - } + }) ) cfg.channels; - # the host arguments cannot exist for fup hostDefaults to work - # so evalArgs sets them to null by default and the null args are filtered out here - hosts = mapAttrs (_: host: lib.filterAttrs (_: arg: arg != null) host) cfg.nixos.hosts; - - hostDefaults = { + hostDefaults = lib.mergeAny hostDefaults { specialArgs.suites = cfg.nixos.suites; - modules = cfg.nixos.hostDefaults.modules - ++ cfg.nixos.hostDefaults.externalModules - ++ defaultModules; + modules = cfg.nixos.hostDefaults.externalModules ++ defaultModules; builder = os.devosSystem { inherit self inputs; }; - inherit (cfg.nixos.hostDefaults) - channelName - system; }; nixosModules = lib.exporter.modulesFromList cfg.nixos.hostDefaults.modules; From 7f3116c1ccb2aa4f6375fa4b45c9863a62656d4f Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 09:30:28 -0700 Subject: [PATCH 23/31] safeReadDir: conver path to string for reliability --- lib/attrs.nix | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/attrs.nix b/lib/attrs.nix index 1ecc2544..d1bc7648 100644 --- a/lib/attrs.nix +++ b/lib/attrs.nix @@ -41,5 +41,6 @@ rec { in lib.filterAttrs filter packages; - safeReadDir = path: lib.optionalAttrs (builtins.pathExists path) (builtins.readDir path); + safeReadDir = path: + lib.optionalAttrs (builtins.pathExists (toString path)) (builtins.readDir (toString path)); } From f57840d723785bc22ad93f0ba17725a620ee9481 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 09:32:12 -0700 Subject: [PATCH 24/31] mkFlake/default.nix: formatting --- lib/mkFlake/default.nix | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index 7b12cf41..bf571ec4 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -52,7 +52,8 @@ lib.systemFlake (lib.recursiveUpdate # pass channels if "overlay" has three arguments overlaysBuilder = channels: lib.unifyOverlays channels channel.overlays; }) - ) cfg.channels; + ) + cfg.channels; hostDefaults = lib.mergeAny hostDefaults { specialArgs.suites = cfg.nixos.suites; @@ -68,10 +69,9 @@ lib.systemFlake (lib.recursiveUpdate deploy.nodes = os.mkNodes deploy self.nixosConfigurations; overlays = lib.exporter.overlaysFromChannelsExporter { - /* since we can't detect overlays owned by self - we have to filter out ones exported by the inputs - optimally we would want a solution for NixOS/nix#4740 - */ + # since we can't detect overlays owned by self + # we have to filter out ones exported by the inputs + # optimally we would want a solution for NixOS/nix#4740 inherit inputs; inherit (self) pkgs; }; From e67b49c2804902b7b4a3c3e74a59aa1667663f1e Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 09:35:44 -0700 Subject: [PATCH 25/31] auto-flatten coercedListOf and type fixes --- flake.nix | 2 +- lib/mkFlake/evalArgs.nix | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/flake.nix b/flake.nix index aca677b9..c2a87add 100644 --- a/flake.nix +++ b/flake.nix @@ -41,7 +41,7 @@ channels = { nixos = { - overlays = nixos.lib.flatten [ + overlays = [ (devos.lib.pathsIn ./overlays) ./pkgs/default.nix pkgs.overlay # for `srcs` diff --git a/lib/mkFlake/evalArgs.nix b/lib/mkFlake/evalArgs.nix index 55b37950..fe49bc3b 100644 --- a/lib/mkFlake/evalArgs.nix +++ b/lib/mkFlake/evalArgs.nix @@ -21,6 +21,12 @@ let inherit (submodule { }) check; description = "valid module"; }); + + # to export modules we need paths to get the name + exportModuleType = with types; + (addCheck path (x: moduleType.check (import x))) // { + description = "path to a module"; + }; overlayType = pathTo (types.anything // { check = builtins.isFunction; description = "valid Nixpkgs overlay"; @@ -37,7 +43,7 @@ let pathToListOf = elemType: with types; pathTo (listOf elemType); coercedListOf = elemType: with types; - coercedTo elemType (x: flatten (singleton x)) (listOf elemType); + coercedTo anything (x: flatten (singleton x)) (listOf elemType); /* Submodules needed for API containers */ @@ -52,7 +58,7 @@ let ''; }; overlays = mkOption { - type = pathToListOf overlayType; + type = coercedListOf overlayType; default = [ ]; description = escape [ "<" ">" ] '' overlays to apply to this channel @@ -126,10 +132,7 @@ let exportModulesModule = name: { options = { modules = mkOption { - type = with types; pathToListOf - # check if the path evaluates to a proper module - # but this must be a path for the export to work - (addCheck path (x: moduleType.check (import x))); + type = with types; pathTo (coercedListOf exportModuleType); default = [ ]; description = '' modules to include in all hosts and export to ${name}Modules output From d5276195f77d1a821454a267bd8b774a8cf896b3 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 09:38:20 -0700 Subject: [PATCH 26/31] move overrides.nix to overlays also update overrides docs it is a pure devos overlay now, it makes sense to go in overlays --- doc/concepts/overrides.md | 19 ++++++++----------- flake.nix | 1 - overrides.nix => overlays/overrides.nix | 0 3 files changed, 8 insertions(+), 12 deletions(-) rename overrides.nix => overlays/overrides.nix (100%) diff --git a/doc/concepts/overrides.md b/doc/concepts/overrides.md index 78b50fd1..0eb1002e 100644 --- a/doc/concepts/overrides.md +++ b/doc/concepts/overrides.md @@ -2,30 +2,27 @@ Each NixOS host follows one channel. But many times it is useful to get packages or modules from different channels. -This is what the overrides are for. You can make use of the `overrides.nix` to -override specific packages to be pulled from other channels. Any overlay may get -`channels` as their first argument. +## Packages +You can make use of `overlays/overrides.nix` to override specific packages in the +default channel to be pulled from other channels. That file is simply an example +of how any overlay can get `channels` as their first argument. -## Example +You can add overlays to any channel to override packages from other channels. -### Packages -The override packages are defined as a regular overlay with an extra arguement -`channels`. This refers to all channels defined in `flake.nix`. - -Pulling the manix package from the latest flake: +Pulling the manix package from the `latest` channel: ```nix channels: final: prev: { inherit (pkgs.latest) manix; } ``` -### Modules +## Modules You can also pull modules from other channels. All modules have access to the `modulesPath` for each channel as `ModulesPath`. And you can use `disabledModules` to remove modules from the current channel. -Pulling the zsh module from the latest flake: +Pulling the zsh module from the `latest` channel: ```nix { latestModulesPath }: { modules = [ "${latestModulesPath}/programs/zsh/zsh.nix" ]; diff --git a/flake.nix b/flake.nix index c2a87add..5468f5a5 100644 --- a/flake.nix +++ b/flake.nix @@ -45,7 +45,6 @@ (devos.lib.pathsIn ./overlays) ./pkgs/default.nix pkgs.overlay # for `srcs` - ./overrides.nix # from "latest" channel nur.overlay ]; }; diff --git a/overrides.nix b/overlays/overrides.nix similarity index 100% rename from overrides.nix rename to overlays/overrides.nix From a7cd35e433c566c5961db1a0b35a775b0dd3d73f Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 09:47:31 -0700 Subject: [PATCH 27/31] update lib subflake lock --- flake.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.lock b/flake.lock index 6d239faa..7841db57 100644 --- a/flake.lock +++ b/flake.lock @@ -81,7 +81,7 @@ "utils": "utils_2" }, "locked": { - "narHash": "sha256-TOrVXGFk5rt1Wn14ja2spg44NuZnFM/V6qguQfO+8Kc=", + "narHash": "sha256-r+OPJF65PToVQK1ll2INAYmIV3zmnDzWBpGLx8m4aVo=", "path": "./lib", "type": "path" }, From df39cb692e7df07a8b7f6531303620888eadeca3 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 09:52:56 -0700 Subject: [PATCH 28/31] rebuild and update mkFlakeOptions.md --- doc/mkFlakeOptions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/mkFlakeOptions.md b/doc/mkFlakeOptions.md index 42b1f60f..9b0e7262 100644 --- a/doc/mkFlakeOptions.md +++ b/doc/mkFlakeOptions.md @@ -54,7 +54,7 @@ will be filtered out *_Type_*: -list of valid Nixpkgs overlay or path convertible to its or path convertible to it +list of valid Nixpkgs overlay or path convertible to its or anything convertible to it *_Default_* @@ -119,7 +119,7 @@ modules to include in all hosts and export to homeModules output *_Type_*: -list of paths or path convertible to it +list of path to a modules or anything convertible to it or path convertible to it *_Default_* @@ -252,7 +252,7 @@ modules to include in all hosts and export to nixosModules output *_Type_*: -list of paths or path convertible to it +list of path to a modules or anything convertible to it or path convertible to it *_Default_* @@ -316,7 +316,7 @@ modules to include *_Type_*: -list of valid module or path convertible to its or valid module or path convertible to it convertible to it +list of valid module or path convertible to its or anything convertible to it *_Default_* From aa825b87a6a16a8a663e14f52155bc924d28bad1 Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 10:26:45 -0700 Subject: [PATCH 29/31] auto import hosts in flake.nix this allows host-specific settings to be overriden with mkMerge --- doc/concepts/hosts.md | 56 ++++++++++++++++++++++++------------------- flake.lock | 2 +- flake.nix | 9 ++++--- lib/attrs.nix | 8 +++++++ lib/flake.nix | 5 ++-- 5 files changed, 48 insertions(+), 32 deletions(-) diff --git a/doc/concepts/hosts.md b/doc/concepts/hosts.md index 770fa51b..1fa90284 100644 --- a/doc/concepts/hosts.md +++ b/doc/concepts/hosts.md @@ -1,18 +1,24 @@ # Hosts Nix flakes contain an output called `nixosConfigurations` declaring an -attribute set of valid NixOS systems. To create hosts, you can use the -`nixos.hosts` argument and pass `modules` to each host. Host-specific modules -typically go in the `hosts` folder of the template. +attribute set of valid NixOS systems. To simplify the management and creation +of these hosts, devos automatically imports every _.nix_ file inside this +directory to the mentioned attribute set, applying the projects defaults to +each. The only hard requirement is that the file contain a valid NixOS module. -Each host should follow a certain channel to define the `pkgs` of that host. -You can use the `nixos.hostDefaults` to set defaults and global modules for all -hosts. +As an example, a file `hosts/system.nix` will be available via the flake +output `nixosConfigurations.system`. You can have as many hosts as you want +and all of them will be automatically imported based on their name. For each host, the configuration automatically sets the `networking.hostName` -attribute to the name of the host. This is for convenience, since `nixos-rebuild` -automatically searches for a configuration matching the current systems hostname -if one is not specified explicitly. +attribute to the name of the file minus the _.nix_ extension. This is for +convenience, since `nixos-rebuild` automatically searches for a configuration +matching the current systems hostname if one is not specified explicitly. + +You can set channels, systems, and add extra modules to each host by editing the +`nixos.hosts` argument in flake.nix. This is the perfect place to import +host specific modules from external sources, such as the +[nixos-hardware][nixos-hardware] repository. It is recommended that the host modules only contain configuration information specific to a particular piece of hardware. Anything reusable across machines @@ -21,16 +27,29 @@ is best saved for [profile modules](./profiles.md). This is a good place to import sets of profiles, called [suites](./suites.md), that you intend to use on your machine. -Additionally, you can pass modules from [nixos-hardware][nixos-hardware] in the -`modules` argument for relevant hosts. ## Example +flake.nix: +```nix +{ + nixos.hosts = mkMerge [ + (devos.lib.importHosts ./hosts) + { + librem = { + channelName = "latest"; + modules = [ hardware.purism-librem-13v3 ]; + }; + } + ]; +} +``` + hosts/librem.nix: ```nix -{ suites, hardware, ... }: +{ suites, ... }: { - imports = suites.laptop ++ [ hardware.purism-librem-13v3 ]; + imports = suites.laptop; boot.loader.systemd-boot.enable = true; boot.loader.efi.canTouchEfiVariables = true; @@ -39,15 +58,4 @@ hosts/librem.nix: } ``` -flake.nix -```nix -{ - nixos.hosts.librem = { - system = "aarch64-linux"; - modules = ./hosts/librem.nix; - }; -} -``` - - [nixos-hardware]: https://github.com/NixOS/nixos-hardware diff --git a/flake.lock b/flake.lock index 7841db57..91c20fdd 100644 --- a/flake.lock +++ b/flake.lock @@ -81,7 +81,7 @@ "utils": "utils_2" }, "locked": { - "narHash": "sha256-r+OPJF65PToVQK1ll2INAYmIV3zmnDzWBpGLx8m4aVo=", + "narHash": "sha256-hpvEXcpq85cDKi0F5UUsuMVISKlk8hgVJiz5FF29RwA=", "path": "./lib", "type": "path" }, diff --git a/flake.nix b/flake.nix index 5468f5a5..d30cc3a9 100644 --- a/flake.nix +++ b/flake.nix @@ -61,11 +61,10 @@ home.nixosModules.home-manager ]; }; - hosts = { - NixOS = { - modules = ./hosts/NixOS.nix; - }; - }; + hosts = nixos.lib.mkMerge [ + (devos.lib.importHosts ./hosts) + { /* set host specific properties here */ } + ]; profiles = [ ./profiles ./users ]; suites = { profiles, users, ... }: with profiles; { base = [ cachix core users.nixos users.root ]; diff --git a/lib/attrs.nix b/lib/attrs.nix index d1bc7648..93f79583 100644 --- a/lib/attrs.nix +++ b/lib/attrs.nix @@ -30,6 +30,14 @@ rec { value = import path; }); + importHosts = dir: + lib.os.recImport { + inherit dir; + _import = base: { + modules = import "${toString dir}/${base}.nix"; + }; + }; + concatAttrs = lib.fold (attr: sum: lib.recursiveUpdate sum attr) { }; # Filter out packages that support given system and follow flake check requirements diff --git a/lib/flake.nix b/lib/flake.nix index 17e069c2..2513311d 100644 --- a/lib/flake.nix +++ b/lib/flake.nix @@ -48,7 +48,8 @@ safeReadDir pathsToImportedAttrs concatAttrs - filterPackages; + filterPackages + importHosts; inherit (lists) pathsIn collectProfiles unifyOverlays; inherit (strings) rgxToString; inherit modules; @@ -60,7 +61,7 @@ { lib = utils.lib // { inherit (lib) - mkFlake pathsIn; + mkFlake pathsIn importHosts; }; } From bb9bc02478a197b28faaac35fa97e9d21fabb16a Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 12:52:16 -0700 Subject: [PATCH 30/31] fix channels.*.input defaultText formatting --- doc/mkFlakeOptions.md | 2 +- lib/mkFlake/evalArgs.nix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/mkFlakeOptions.md b/doc/mkFlakeOptions.md index 9b0e7262..90719ba1 100644 --- a/doc/mkFlakeOptions.md +++ b/doc/mkFlakeOptions.md @@ -40,7 +40,7 @@ nix flake *_Default_* ``` -"inputs.\\" +"inputs." ``` diff --git a/lib/mkFlake/evalArgs.nix b/lib/mkFlake/evalArgs.nix index fe49bc3b..ee42e224 100644 --- a/lib/mkFlake/evalArgs.nix +++ b/lib/mkFlake/evalArgs.nix @@ -52,7 +52,7 @@ let input = mkOption { type = flakeType; default = cfg.inputs.${name}; - defaultText = escape [ "<" ">" ] "inputs."; + defaultText = "inputs."; description = '' nixpkgs flake input to use for this channel ''; From 5bc88ad2c21d1872ccb15eddb7da6945824ceccc Mon Sep 17 00:00:00 2001 From: Pacman99 Date: Tue, 27 Apr 2021 16:36:07 -0700 Subject: [PATCH 31/31] don't use lockfile to get flake-compat lock file format isn't very reliable with naming inputs --- flake.nix | 2 -- lib/compat/default.nix | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/flake.nix b/flake.nix index d30cc3a9..1b469f48 100644 --- a/flake.nix +++ b/flake.nix @@ -21,8 +21,6 @@ }; darwin.url = "github:LnL7/nix-darwin"; darwin.inputs.nixpkgs.follows = "latest"; - flake-compat.url = "github:BBBSnowball/flake-compat/pr-1"; - flake-compat.flake = false; home.url = "github:nix-community/home-manager"; home.inputs.nixpkgs.follows = "nixos"; naersk.url = "github:nmattia/naersk"; diff --git a/lib/compat/default.nix b/lib/compat/default.nix index 0a63b0bc..9d0c2837 100644 --- a/lib/compat/default.nix +++ b/lib/compat/default.nix @@ -1,12 +1,10 @@ let - inherit (lock.nodes.flake-compat.locked) rev narHash; - - lock = builtins.fromJSON (builtins.readFile "${../..}/flake.lock"); + rev = "e7e5d481a0e15dcd459396e55327749989e04ce0"; flake = (import ( fetchTarball { url = "https://github.com/edolstra/flake-compat/archive/${rev}.tar.gz"; - sha256 = narHash; + sha256 = "0zd3x46fswh5n6faq4x2kkpy6p3c6j593xbdlbsl40ppkclwc80x"; } ) {