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..1fa90284 100644 --- a/doc/concepts/hosts.md +++ b/doc/concepts/hosts.md @@ -15,6 +15,11 @@ 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 is best saved for [profile modules](./profiles.md). @@ -22,20 +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, 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. ## 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; diff --git a/doc/concepts/overrides.md b/doc/concepts/overrides.md index 28194cd1..0eb1002e 100644 --- a/doc/concepts/overrides.md +++ b/doc/concepts/overrides.md @@ -1,47 +1,36 @@ # 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. +## 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. -They are defined in the `extern/overrides.nix` file. +You can add overlays to any channel to override packages from other channels. -## 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. - -Pulling the manix package from the override flake: +Pulling the manix package from the `latest` channel: ```nix -{ - packages = pkgs: final: prev: { - inherit (pkgs) manix; - }; +channels: final: prev: { + inherit (pkgs.latest) manix; } ``` -### Modules +## 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` channel: ```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/mkFlakeOptions.md b/doc/mkFlakeOptions.md new file mode 100644 index 00000000..90719ba1 --- /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 anything 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 path to a modules or anything convertible to it 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 path to a modules or anything convertible to it 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 anything 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/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 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 1c95e54a..91c20fdd 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-t14TKUtw83dZ2mbqjRpeUvdAx4zpe/ySr5KhPhB1JMU=", + "narHash": "sha256-hpvEXcpq85cDKi0F5UUsuMVISKlk8hgVJiz5FF29RwA=", "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": [ @@ -158,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": { @@ -182,7 +211,7 @@ "naersk_2": { "inputs": { "nixpkgs": [ - "override" + "latest" ] }, "locked": { @@ -259,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": [ @@ -312,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" } }, @@ -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": 1619532520, + "narHash": "sha256-+xIFAW5J0AcxwAflAX1gg/C8kfaqeZbS4XAZusCrZPY=", + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "rev": "8eb7f9206713a528174c20c5133521dc37e2bfb1", "type": "github" }, "original": { - "owner": "numtide", - "repo": "flake-utils", + "owner": "gytis-ivaskevicius", + "ref": "staging", + "repo": "flake-utils-plus", "type": "github" } } diff --git a/flake.nix b/flake.nix index bad78f1f..1b469f48 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,71 @@ 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"; - flake-compat.url = "github:BBBSnowball/flake-compat/pr-1"; - flake-compat.flake = false; + darwin.inputs.nixpkgs.follows = "latest"; 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 = [ + (devos.lib.pathsIn ./overlays) + ./pkgs/default.nix + pkgs.overlay # for `srcs` + 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.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 ]; + }; + }; + + 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/lib/attrs.nix b/lib/attrs.nix index 1ecc2544..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 @@ -41,5 +49,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)); } 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"; } ) { 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; + }; + }; + }]; + }) 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; +} + + diff --git a/lib/flake.lock b/lib/flake.lock index f70c491f..ebf5e6d3 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": 1619532520, + "narHash": "sha256-+xIFAW5J0AcxwAflAX1gg/C8kfaqeZbS4XAZusCrZPY=", + "owner": "gytis-ivaskevicius", + "repo": "flake-utils-plus", + "rev": "8eb7f9206713a528174c20c5133521dc37e2bfb1", "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 15d87197..2513311d 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, ... }: @@ -35,12 +35,11 @@ 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 { lib = nixpkgs.lib // self; - inherit nixpkgs deploy devshell; + inherit deploy devshell; }; inherit (attrs) @@ -49,8 +48,9 @@ safeReadDir pathsToImportedAttrs concatAttrs - filterPackages; - inherit (lists) pathsIn collectProfiles; + filterPackages + importHosts; + inherit (lists) pathsIn collectProfiles unifyOverlays; inherit (strings) rgxToString; inherit modules; } @@ -61,7 +61,7 @@ { lib = utils.lib // { inherit (lib) - mkFlake; + mkFlake pathsIn importHosts; }; } @@ -83,7 +83,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/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); } diff --git a/lib/mkFlake/default.nix b/lib/mkFlake/default.nix index d086283a..bf571ec4 100644 --- a/lib/mkFlake/default.nix +++ b/lib/mkFlake/default.nix @@ -1,64 +1,94 @@ { 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 { + inherit args; }; - 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; + }) + ]; + + 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 hosts; + inherit (cfg) channelsConfig supportedSystems; + + channels = mapAttrs + (name: channel: + stripChannel (channel // { + # pass channels if "overlay" has three arguments + overlaysBuilder = channels: lib.unifyOverlays channels channel.overlays; + }) + ) + cfg.channels; + + hostDefaults = lib.mergeAny hostDefaults { + specialArgs.suites = cfg.nixos.suites; + modules = cfg.nixos.hostDefaults.externalModules ++ defaultModules; + builder = os.devosSystem { inherit self inputs; }; + }; + + 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 { + # 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; + }; + + 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/evalArgs.nix b/lib/mkFlake/evalArgs.nix index cb90f614..ee42e224 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: @@ -20,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"; @@ -33,46 +40,37 @@ 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 anything (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 = "inputs."; description = '' nixpkgs flake input to use for this channel ''; }; overlays = mkOption { - type = pathToListOf overlayType; + type = coercedListOf 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 + these will get exported under the 'overlays' flake output + as / and any overlay pulled from ''\${inputs} + will be filtered out ''; }; config = mkOption { type = pathTo attrs; default = { }; + apply = lib.recursiveUpdate cfg.channelsConfig; description = '' nixpkgs config for this channel ''; @@ -82,21 +80,25 @@ 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) // { + description = "system defined in `supportedSystems`"; + }; + 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))) // { + description = "a channel defined in `channels`"; + }; + default = null; description = '' Channel this host should follow ''; }; - }; }; @@ -105,10 +107,11 @@ let externalModulesModule = { options = { externalModules = mkOption { - type = pathToListOf moduleType; + 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 ''; }; }; @@ -117,7 +120,7 @@ let modulesModule = { options = { modules = mkOption { - type = pathToListOf moduleType; + type = with types; coercedListOf moduleType; default = [ ]; description = '' modules to include @@ -126,13 +129,31 @@ let }; }; + exportModulesModule = name: { + options = { + modules = mkOption { + type = with types; pathTo (coercedListOf exportModuleType); + 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,16 +173,17 @@ 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"; + 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); @@ -171,8 +193,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. ''; }; @@ -180,11 +201,22 @@ 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; 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 +224,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 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 ]; -} diff --git a/lib/modules.nix b/lib/modules.nix index 7024f13f..6e2a3525 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,49 +19,41 @@ "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 } ''; + _module.args = { + inherit self; + hosts = builtins.mapAttrs (_: host: host.config) + (removeAttrs self.nixosConfigurations [ config.networking.hostName ]); + }; + 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 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 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) + ]; + }; + }; } diff --git a/overlays/overrides.nix b/overlays/overrides.nix new file mode 100644 index 00000000..bb3cf68b --- /dev/null +++ b/overlays/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; + }; + }; + +}