231: Move flake implementation logic to lib r=nrdxp a=Pacman99

This is a simpler version of #218 that moves flake logic to lib and adds a module to evaluate devos. This DOES NOT support out of tree usage, so if you were following any of the previous PR's, the doc sections/examples to use devos as a library will not work. There is work to make a cleaner api and only then will out of tree support work. Until then, this is still useful to simplify devos and clean up a lot of the implementation logic.

Co-authored-by: Pacman99 <pachum99@gmail.com>
This commit is contained in:
bors[bot] 2021-04-09 02:58:30 +00:00 committed by GitHub
commit 3823eb6423
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 234 additions and 74 deletions

View File

@ -30,77 +30,24 @@
outputs = inputs@{ deploy, nixos, nur, self, utils, ... }: outputs = inputs@{ deploy, nixos, nur, self, utils, ... }:
let let
inherit (self) lib; lib = import ./lib { inherit self nixos inputs; };
inherit (lib) os; in
lib.mkFlake {
extern = import ./extern { inherit inputs; }; inherit self;
overrides = import ./overrides; hosts = ./hosts;
packages = import ./pkgs;
multiPkgs = os.mkPkgs {
inherit extern overrides;
};
suites = os.mkSuites {
suites = import ./suites; suites = import ./suites;
users = os.mkProfileAttrs "${self}/users"; extern = import ./extern;
profiles = os.mkProfileAttrs "${self}/profiles";
userProfiles = os.mkProfileAttrs "${self}/users/profiles";
};
outputs = {
nixosConfigurations = os.mkHosts {
dir = "${self}/hosts";
overrides = import ./overrides; overrides = import ./overrides;
inherit multiPkgs suites extern; overlays = ./overlays;
}; profiles = ./profiles;
userProfiles = ./users/profiles;
homeConfigurations = os.mkHomeConfigurations; modules = import ./modules/module-list.nix;
userModules = import ./users/modules/module-list.nix;
nixosModules = } // {
let moduleList = import ./modules/module-list.nix; inherit lib;
in lib.pathsToImportedAttrs moduleList; defaultTemplate = self.templates.flk;
homeModules =
let moduleList = import ./users/modules/module-list.nix;
in lib.pathsToImportedAttrs moduleList;
overlay = import ./pkgs;
overlays = lib.pathsToImportedAttrs (lib.pathsIn ./overlays);
lib = import ./lib { inherit nixos self inputs; };
templates.flk.path = ./.; templates.flk.path = ./.;
templates.flk.description = "flk template"; templates.flk.description = "flk template";
defaultTemplate = self.templates.flk;
deploy.nodes = os.mkNodes deploy self.nixosConfigurations;
};
systemOutputs = utils.lib.eachDefaultSystem (system:
let
pkgs = multiPkgs.${system};
# all packages that are defined in ./pkgs
legacyPackages = os.mkPackages { inherit pkgs; };
in
{
checks =
let
tests = nixos.lib.optionalAttrs (system == "x86_64-linux")
(import ./tests { inherit self pkgs; });
deployHosts = nixos.lib.filterAttrs
(n: _: self.nixosConfigurations.${n}.config.nixpkgs.system == system) self.deploy.nodes;
deployChecks = deploy.lib.${system}.deployChecks { nodes = deployHosts; };
in
nixos.lib.recursiveUpdate tests deployChecks;
inherit legacyPackages;
packages = lib.filterPackages system legacyPackages;
devShell = import ./shell {
inherit self system extern overrides;
}; };
} }
);
in
nixos.lib.recursiveUpdate outputs systemOutputs;
}

View File

@ -17,6 +17,8 @@ lib.makeExtensible (final:
lists = callLibs ./lists.nix; lists = callLibs ./lists.nix;
strings = callLibs ./strings.nix; strings = callLibs ./strings.nix;
mkFlake = callLibs ./mkFlake;
inherit (attrs) mapFilterAttrs genAttrs' safeReadDir inherit (attrs) mapFilterAttrs genAttrs' safeReadDir
pathsToImportedAttrs concatAttrs filterPackages; pathsToImportedAttrs concatAttrs filterPackages;
inherit (lists) pathsIn; inherit (lists) pathsIn;

View File

@ -2,7 +2,7 @@
{ {
pathsIn = dir: pathsIn = dir:
let let
fullPath = name: "${toString dir}/${name}"; fullPath = name: "${dir}/${name}";
in in
map fullPath (lib.attrNames (dev.safeReadDir dir)); map fullPath (lib.attrNames (dev.safeReadDir dir));
} }

60
lib/mkFlake/default.nix Normal file
View File

@ -0,0 +1,60 @@
{ dev, nixos, inputs, ... }:
let
inherit (dev) os;
inherit (inputs) utils deploy;
evalFlakeArgs = dev.callLibs ./evalArgs.nix;
in
{ self, ... } @ args:
let
cfg = (evalFlakeArgs { inherit args; }).config;
multiPkgs = os.mkPkgs { inherit (cfg) extern overrides; };
outputs = {
nixosConfigurations = os.mkHosts {
inherit self multiPkgs;
inherit (cfg) extern suites overrides;
dir = cfg.hosts;
};
homeConfigurations = os.mkHomeConfigurations;
nixosModules = cfg.modules;
homeModules = cfg.userModules;
overlay = cfg.packages;
inherit (cfg) overlays;
deploy.nodes = os.mkNodes deploy self.nixosConfigurations;
};
systemOutputs = utils.lib.eachDefaultSystem (system:
let
pkgs = multiPkgs.${system};
# all packages that are defined in ./pkgs
legacyPackages = os.mkPackages { inherit pkgs; };
in
{
checks =
let
tests = nixos.lib.optionalAttrs (system == "x86_64-linux")
(import "${self}/tests" { inherit self pkgs; });
deployHosts = nixos.lib.filterAttrs
(n: _: self.nixosConfigurations.${n}.config.nixpkgs.system == system) self.deploy.nodes;
deployChecks = deploy.lib.${system}.deployChecks { nodes = deployHosts; };
in
nixos.lib.recursiveUpdate tests deployChecks;
inherit legacyPackages;
packages = dev.filterPackages system legacyPackages;
devShell = import "${self}/shell" {
inherit self system;
};
});
in
outputs // systemOutputs

151
lib/mkFlake/evalArgs.nix Normal file
View File

@ -0,0 +1,151 @@
{ self, dev, nixos, inputs, ... }:
{ args }:
let
argOpts = with nixos.lib; { config, options, ... }:
let
inherit (dev) 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 nixos.lib.isStorePath;
description = "The flake to create the devos outputs for";
};
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 = dev.pathsToImportedAttrs;
description = ''
list of modules to include in confgurations and export in 'nixosModules' output
'';
};
userModules = mkOption {
type = listOf moduleType;
default = [];
apply = dev.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 (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: dev.pathsToImportedAttrs (dev.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
nixos.lib.evalModules {
modules = [ argOpts args ];
}