Add capability to choose home-manager branch

This commit is contained in:
Jack O'Sullivan 2022-02-15 20:50:27 +00:00
parent 716ee35c29
commit 948ae3f80f
12 changed files with 305 additions and 131 deletions

46
flake.lock generated
View File

@ -109,7 +109,27 @@
"type": "github" "type": "github"
} }
}, },
"home-manager": { "home-manager-stable": {
"inputs": {
"nixpkgs": [
"nixpkgs-stable"
]
},
"locked": {
"lastModified": 1643933536,
"narHash": "sha256-yRmsWAG4DnLxLIUtlaZsl0kH7rN5xSoyNRlf0YZrcH4=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "2860d7e3bb350f18f7477858f3513f9798896831",
"type": "github"
},
"original": {
"id": "home-manager",
"ref": "release-21.11",
"type": "indirect"
}
},
"home-manager-unstable": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"nixpkgs-unstable" "nixpkgs-unstable"
@ -195,6 +215,20 @@
"type": "indirect" "type": "indirect"
} }
}, },
"nixpkgs-master": {
"locked": {
"lastModified": 1644486793,
"narHash": "sha256-EeijR4guVHgVv+JpOX3cQO+1XdrkJfGmiJ9XVsVU530=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "1882c6b7368fd284ad01b0a5b5601ef136321292",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"nixpkgs-regression": { "nixpkgs-regression": {
"locked": { "locked": {
"lastModified": 1643052045, "lastModified": 1643052045,
@ -227,11 +261,11 @@
}, },
"nixpkgs-unstable": { "nixpkgs-unstable": {
"locked": { "locked": {
"lastModified": 1644420267, "lastModified": 1644525281,
"narHash": "sha256-rFJuctggkjM412OC6OGPdXogFp7czGDW05ueWqpJbj8=", "narHash": "sha256-D3VuWLdnLmAXIkooWAtbTGSQI9Fc1lkvAr94wTxhnTU=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "98bb5b77c8c6666824a4c13d23befa1e07210ef1", "rev": "48d63e924a2666baf37f4f14a18f19347fbd54a2",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -246,9 +280,11 @@
"deploy-rs": "deploy-rs", "deploy-rs": "deploy-rs",
"devshell": "devshell", "devshell": "devshell",
"flake-utils": "flake-utils_2", "flake-utils": "flake-utils_2",
"home-manager": "home-manager", "home-manager-stable": "home-manager-stable",
"home-manager-unstable": "home-manager-unstable",
"impermanence": "impermanence", "impermanence": "impermanence",
"nix": "nix", "nix": "nix",
"nixpkgs-master": "nixpkgs-master",
"nixpkgs-stable": "nixpkgs-stable", "nixpkgs-stable": "nixpkgs-stable",
"nixpkgs-unstable": "nixpkgs-unstable" "nixpkgs-unstable": "nixpkgs-unstable"
} }

View File

@ -5,18 +5,20 @@
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
devshell.url = "github:numtide/devshell"; devshell.url = "github:numtide/devshell";
devshell.inputs.nixpkgs.follows = "nixpkgs-unstable"; devshell.inputs.nixpkgs.follows = "nixpkgs-unstable";
# Used by most systems
nixpkgs-master.url = "nixpkgs";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable"; nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# For extra-stable systems
nixpkgs-stable.url = "nixpkgs/nixos-21.11"; nixpkgs-stable.url = "nixpkgs/nixos-21.11";
home-manager-unstable.url = "home-manager";
home-manager-unstable.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager-stable.url = "home-manager/release-21.11";
home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable";
# Stuff used by the flake for build / deployment # Stuff used by the flake for build / deployment
agenix.url = "github:ryantm/agenix"; agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs-unstable"; agenix.inputs.nixpkgs.follows = "nixpkgs-unstable";
deploy-rs.url = "github:serokell/deploy-rs"; deploy-rs.url = "github:serokell/deploy-rs";
deploy-rs.inputs.nixpkgs.follows = "nixpkgs-unstable"; deploy-rs.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager.url = "home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs-unstable";
# Stuff used by systems # Stuff used by systems
nix.url = "nix/latest-release"; nix.url = "nix/latest-release";
@ -30,7 +32,8 @@
flake-utils, flake-utils,
nixpkgs-unstable, nixpkgs-stable, nixpkgs-master, nixpkgs-unstable, nixpkgs-stable,
home-manager-unstable, home-manager-stable,
... ...
}: }:
@ -39,37 +42,49 @@
inherit (lib.flake) eachDefaultSystem; inherit (lib.flake) eachDefaultSystem;
inherit (lib.my) attrsToList mkApp mkShellApp mkShellApp' inlineModules mkDefaultSystemsPkgs flakePackageOverlay; inherit (lib.my) attrsToList mkApp mkShellApp mkShellApp' inlineModules mkDefaultSystemsPkgs flakePackageOverlay;
extendLib = lib: lib.extend (final: prev: { # Extend a lib with extras that _must not_ internally reference private nixpkgs. flake-utils doesn't, but many
# other flakes (e.g. home-manager) probably do internally.
libOverlay = final: prev: {
my = import ./util.nix { lib = final; }; my = import ./util.nix { lib = final; };
flake = flake-utils.lib; flake = flake-utils.lib;
}); };
libOverlay = final: prev: { lib = extendLib prev.lib; }; pkgsLibOverlay = final: prev: { lib = prev.lib.extend libOverlay; };
pkgsFlakes = mapAttrs (_: pkgs: pkgs // { lib = extendLib pkgs.lib; }) { # Override the flake-level lib since we're going to use it for non-config specific stuff
pkgsFlakes = mapAttrs (_: pkgsFlake: pkgsFlake // { lib = pkgsFlake.lib.extend libOverlay; }) {
master = nixpkgs-master;
unstable = nixpkgs-unstable; unstable = nixpkgs-unstable;
stable = nixpkgs-stable; stable = nixpkgs-stable;
}; };
hmFlakes = {
unstable = home-manager-unstable;
stable = home-manager-stable;
};
# Should only be used for platform-independent flake stuff! This should never leak into a NixOS or home-manager
# config - they'll get their own.
lib = pkgsFlakes.unstable.lib; lib = pkgsFlakes.unstable.lib;
# pkgs for dev shell etc
pkgs' = mapAttrs pkgs' = mapAttrs
(_: path: mkDefaultSystemsPkgs path (system: { (_: path: mkDefaultSystemsPkgs path (system: {
overlays = [ overlays = [
libOverlay pkgsLibOverlay
inputs.devshell.overlay inputs.devshell.overlay
inputs.agenix.overlay inputs.agenix.overlay
inputs.deploy-rs.overlay inputs.deploy-rs.overlay
# TODO: This causes a compile from source which is pretty unnecessary
inputs.nix.overlay inputs.nix.overlay
(flakePackageOverlay inputs.home-manager system) (flakePackageOverlay inputs.home-manager-unstable system)
]; ];
})) }))
pkgsFlakes; pkgsFlakes;
# Easiest to build the basic pkgs here (with our lib overlay too) # Easiest to build the basic pkgs here (with our lib overlay too)
homePkgs' = mapAttrs configPkgs' = mapAttrs
(_: path: mkDefaultSystemsPkgs path (_: { (_: path: mkDefaultSystemsPkgs path (_: {
overlays = [ overlays = [
libOverlay pkgsLibOverlay
]; ];
})) }))
pkgsFlakes; pkgsFlakes;
@ -96,7 +111,8 @@
homeModules = inlineModules homeModules; homeModules = inlineModules homeModules;
nixosConfigurations = import ./systems.nix { nixosConfigurations = import ./systems.nix {
inherit lib pkgsFlakes inputs; inherit lib pkgsFlakes hmFlakes inputs;
pkgs' = configPkgs';
modules = attrValues modules; modules = attrValues modules;
homeModules = attrValues homeModules; homeModules = attrValues homeModules;
}; };
@ -104,8 +120,8 @@
vms = mapAttrs (_: system: system.config.my.build.devVM) self.nixosConfigurations; vms = mapAttrs (_: system: system.config.my.build.devVM) self.nixosConfigurations;
homeConfigurations = import ./homes.nix { homeConfigurations = import ./homes.nix {
inherit lib inputs; inherit lib hmFlakes inputs;
pkgs' = homePkgs'; pkgs' = configPkgs';
modules = attrValues homeModules; modules = attrValues homeModules;
}; };
homes = mapAttrs(_: home: home.activationPackage) self.homeConfigurations; homes = mapAttrs(_: home: home.activationPackage) self.homeConfigurations;

View File

@ -1,9 +1,23 @@
{ lib, pkgs, inputs, isStandalone, config, ... }: { lib, pkgs, pkgs', inputs, config, ... }@args:
let let
inherit (lib) mkMerge mkIf mkDefault mkForce; inherit (lib) optionalAttrs versionAtLeast mkMerge mkIf mkDefault mkOption;
inherit (lib.my) mkOpt' dummyOption;
in in
mkMerge [
{ {
options = with lib.types; {
my = {
isStandalone = mkOption {
type = bool;
internal = true;
description = "Whether home-manager is running inside a NixOS system or not.";
};
};
# Only present in >=22.05, so forward declare
nix.registry = dummyOption;
};
config = mkMerge [
(mkIf (versionAtLeast config.home.stateVersion "22.05") {
nix.registry = { nix.registry = {
pkgs = { pkgs = {
to = { to = {
@ -13,6 +27,9 @@ mkMerge [
exact = true; exact = true;
}; };
}; };
})
{
my.isStandalone = !(args ? sysConfig);
programs = { programs = {
# Even when enabled this will only be actually installed in standalone mode # Even when enabled this will only be actually installed in standalone mode
@ -64,22 +81,22 @@ mkMerge [
}; };
language.base = mkDefault "en_IE.UTF-8"; language.base = mkDefault "en_IE.UTF-8";
# The flake passes a default setting, but we don't care about that
stateVersion = mkForce "22.05";
}; };
} }
(mkIf isStandalone { (mkIf (config.my.isStandalone || !args.sysConfig.home-manager.useGlobalPkgs) {
# Note: this only applies outside NixOS where home-manager imports nixpkgs internally # Note: If globalPkgs mode is on, then these will be overridden by the NixOS equivalents of these options
nixpkgs = { nixpkgs = {
overlays = [ overlays = [
inputs.nix.overlay inputs.nix.overlay
# TODO: Wait for https://github.com/NixOS/nixpkgs/pull/159074 to arrive to nixos-unstable
(final: prev: { remarshal = pkgs'.master.remarshal; })
]; ];
config = { config = {
allowUnfree = true; allowUnfree = true;
}; };
}; };
})
(mkIf config.my.isStandalone {
fonts.fontconfig.enable = true; fonts.fontconfig.enable = true;
home = { home = {
@ -88,4 +105,5 @@ mkMerge [
]; ];
}; };
}) })
] ];
}

View File

@ -1,23 +1,42 @@
{ lib, inputs, pkgs', modules }: { lib, hmFlakes, inputs, pkgs', modules }:
let let
inherit (builtins) removeAttrs mapAttrs; inherit (builtins) removeAttrs mapAttrs;
inherit (lib) recursiveUpdate; inherit (lib) flatten optional recursiveUpdate;
inherit (lib.my) homeStateVersion;
mkHome = name: { mkHome = name: {
system, system,
nixpkgs ? "unstable", nixpkgs ? "unstable",
home-manager ? nixpkgs,
config, config,
... ...
}@args: }@args:
let let
rest = removeAttrs args [ "nixpkgs" "config" ]; rest = removeAttrs args [ "nixpkgs" "home-manager" "config" ];
in in
inputs.home-manager.lib.homeManagerConfiguration (recursiveUpdate rest { # homeManagerConfiguration doesn't allow us to set lib directly (inherits from passed pkgs)
hmFlakes.${home-manager}.lib.homeManagerConfiguration (recursiveUpdate rest {
configuration = config; configuration = config;
# Passing pkgs here doesn't set the global pkgs, just where it'll be imported from (and where the global lib is
# derived from). We want home-manager to import pkgs itself so it'll apply config and overlays modularly. Any config
# and overlays previously applied will be passed on by `homeManagerConfiguration` though.
pkgs = pkgs'.${nixpkgs}.${system}; pkgs = pkgs'.${nixpkgs}.${system};
extraModules = modules ++ [{ extraModules = modules ++ [
_module.args = { inherit inputs; isStandalone = true; }; {
}]; warnings = flatten [
(optional (nixpkgs != home-manager)
''
Using nixpkgs ${nixpkgs} with home-manager ${home-manager} may cause issues.
'')
];
_module.args = {
inherit inputs;
pkgs' = mapAttrs (_: p: p.${system}) pkgs';
};
}
(homeStateVersion home-manager)
];
}); });
in in
mapAttrs mkHome { mapAttrs mkHome {

View File

@ -44,4 +44,6 @@ in
devVM = recursiveUpdate config.my.asDevVM.system.build.vm { meta.mainProgram = "run-${config.system.name}-vm"; }; devVM = recursiveUpdate config.my.asDevVM.system.build.vm { meta.mainProgram = "run-${config.system.name}-vm"; };
}; };
}; };
meta.buildDocsInSandbox = false;
} }

View File

@ -1,16 +1,21 @@
{ lib, pkgs, inputs, homeModules, config, options, ... }: { lib, pkgs, inputs, options, config, ... }:
let let
inherit (builtins) attrValues; inherit (builtins) attrValues;
inherit (lib) mkIf mkDefault mkAliasDefinitions; inherit (lib) mkIf mkDefault mkAliasDefinitions;
inherit (lib.my) mkOpt'; inherit (lib.my) mkOpt' dummyOption;
in in
{ {
options.my = with lib.types; { options = with lib.types; {
my = {
# Pretty hacky but too lazy to figure out if there's a better way to alias the options # Pretty hacky but too lazy to figure out if there's a better way to alias the options
user = mkOpt' (attrsOf anything) { } "User definition (as `users.users.*`)."; user = mkOpt' (attrsOf anything) { } "User definition (as `users.users.*`).";
homeConfig = mkOpt' anything { } "Home configuration (as `home-manager.users.*`)"; homeConfig = mkOpt' anything { } "Home configuration (as `home-manager.users.*`)";
}; };
# Only present in >=22.05, so forward declare
documentation.nixos.options.warningsAreErrors = dummyOption;
};
config = config =
let let
defaultUsername = "dev"; defaultUsername = "dev";
@ -28,11 +33,8 @@ in
}; };
home-manager = { home-manager = {
useGlobalPkgs = mkDefault true; # Installs packages in the system config instead of in the local profile on activation
useUserPackages = mkDefault true; useUserPackages = mkDefault true;
sharedModules = homeModules ++ [{
_module.args = { inherit inputs; isStandalone = false; };
}];
}; };
users = { users = {
@ -67,6 +69,13 @@ in
}; };
}; };
documentation = {
nixos = {
enable = mkDefault true;
options.warningsAreErrors = mkDefault false;
};
};
time.timeZone = mkDefault "Europe/Dublin"; time.timeZone = mkDefault "Europe/Dublin";
boot = { boot = {
@ -106,4 +115,6 @@ in
configurationRevision = with inputs; mkIf (self ? rev) self.rev; configurationRevision = with inputs; mkIf (self ? rev) self.rev;
}; };
}; };
meta.buildDocsInSandbox = false;
} }

View File

@ -22,4 +22,6 @@ in
''; '';
}); });
}; };
meta.buildDocsInSandbox = false;
} }

View File

@ -164,4 +164,6 @@ in
''; '';
}) })
]); ]);
meta.buildDocsInSandbox = false;
} }

View File

@ -10,4 +10,6 @@ in
config = mkIf cfg.enable { config = mkIf cfg.enable {
services.getty.autologinUser = config.my.user.name; services.getty.autologinUser = config.my.user.name;
}; };
meta.buildDocsInSandbox = false;
} }

View File

@ -210,4 +210,6 @@ in
}) })
])) ]))
]); ]);
meta.buildDocsInSandbox = false;
} }

View File

@ -1,18 +1,24 @@
{ lib, pkgsFlakes, inputs, modules, homeModules }: { lib, pkgsFlakes, hmFlakes, inputs, pkgs', modules, homeModules }:
let let
inherit (builtins) attrValues mapAttrs; inherit (builtins) attrValues mapAttrs;
inherit (lib) optionals mkDefault; inherit (lib) flatten optional optionals mkDefault mkForce;
inherit (lib.my) homeStateVersion;
mkSystem = mkSystem =
name: { name: {
system, system,
nixpkgs ? "unstable", nixpkgs ? "unstable",
home-manager ? nixpkgs,
hmNixpkgs ? home-manager,
config, config,
# This causes a (very slow) docs rebuild on every change to a module's options it seems
docCustom ? true, docCustom ? true,
}: }:
let let
# The flake contains `nixosSystem`, so we do need it (if we didn't have the TODO hacked version anyway)
pkgsFlake = pkgsFlakes.${nixpkgs}; pkgsFlake = pkgsFlakes.${nixpkgs};
lib = pkgsFlake.lib;
# TODO: This is mostly yoinked from nixpkgs/flake.nix master (as of 2022/02/11) since 21.11's version has hacky # TODO: This is mostly yoinked from nixpkgs/flake.nix master (as of 2022/02/11) since 21.11's version has hacky
# vm build stuff that breaks our impl. REMOVE WHEN 22.05 IS OUT! # vm build stuff that breaks our impl. REMOVE WHEN 22.05 IS OUT!
nixosSystem' = args: nixosSystem' = args:
@ -23,22 +29,73 @@ let
system.nixos.revision = pkgsFlake.rev; system.nixos.revision = pkgsFlake.rev;
}]; }];
}); });
in
nixosSystem' { modules' = [
inherit lib system;
baseModules =
(import "${pkgsFlake}/nixos/modules/module-list.nix") ++ [
# Importing modules from module args causes infinite recursion # Importing modules from module args causes infinite recursion
inputs.impermanence.nixosModule inputs.impermanence.nixosModule
hmFlake.nixosModule
inputs.agenix.nixosModules.age inputs.agenix.nixosModules.age
inputs.home-manager.nixosModule ] ++ modules;
] ++ (optionals docCustom modules); pkgs = pkgs'.${nixpkgs}.${system};
modules = (optionals (!docCustom) modules) ++ [ allPkgs = mapAttrs (_: p: p.${system}) pkgs';
{
_module.args = { inherit system inputs homeModules; }; hmFlake = hmFlakes.${home-manager};
in
nixosSystem' {
# Gotta override lib here unforunately, eval-config.nix likes to import its own (unextended) lib. We explicitly
# don't pass pkgs so that it'll be imported with modularly applied config and overlays.
lib = pkgs.lib;
# `baseModules` informs the manual which modules to document
baseModules =
(import "${pkgsFlake}/nixos/modules/module-list.nix") ++ (optionals docCustom modules');
modules = (optionals (!docCustom) modules') ++ [
(modArgs: {
warnings = flatten [
(optional (modArgs.config.home-manager.useGlobalPkgs && (nixpkgs != home-manager))
''
Using global nixpkgs ${nixpkgs} with home-manager ${home-manager} may cause problems.
'')
];
_module.args = {
inherit inputs;
pkgs' = allPkgs;
};
system.name = name; system.name = name;
networking.hostName = mkDefault name; networking.hostName = mkDefault name;
nixpkgs = {
inherit system;
# Make sure any previously set config / overlays (e.g. lib which will be inherited by home-manager down the
# line) are passed on when nixpkgs is imported.
inherit (pkgs) config overlays;
};
# Unfortunately it seems there's no way to fully decouple home-manager's lib from NixOS's pkgs.lib. :(
# https://github.com/nix-community/home-manager/blob/7c2ae0bdd20ddcaafe41ef669226a1df67f8aa06/nixos/default.nix#L22
home-manager = {
# Optimise if system and home-manager nixpkgs are the same
useGlobalPkgs = mkDefault (nixpkgs == home-manager);
sharedModules = homeModules ++ [
{
warnings = flatten [
(optional (!modArgs.config.home-manager.useGlobalPkgs && (hmNixpkgs != home-manager))
''
Using per-user nixpkgs ${hmNixpkgs} with home-manager ${home-manager} may cause issues.
'')
];
# pkgsPath is used by home-manager's nixkpgs module to import nixpkgs (i.e. if !useGlobalPkgs)
_module.args = {
inherit inputs;
pkgsPath = toString pkgsFlakes.${hmNixpkgs};
pkgs' = allPkgs;
};
} }
(homeStateVersion home-manager)
];
};
})
config config
]; ];
}; };
@ -47,6 +104,8 @@ mapAttrs mkSystem {
colony = { colony = {
system = "x86_64-linux"; system = "x86_64-linux";
nixpkgs = "stable"; nixpkgs = "stable";
home-manager = "unstable";
config = boxes/colony.nix; config = boxes/colony.nix;
docCustom = false;
}; };
} }

View File

@ -1,7 +1,7 @@
{ lib }: { lib }:
let let
inherit (builtins) replaceStrings elemAt mapAttrs; inherit (builtins) replaceStrings elemAt mapAttrs;
inherit (lib) genAttrs mapAttrs' mapAttrsToList nameValuePair types mkOption mkOverride; inherit (lib) genAttrs mapAttrs' mapAttrsToList nameValuePair types mkOption mkOverride mkForce;
inherit (lib.flake) defaultSystems; inherit (lib.flake) defaultSystems;
in in
rec { rec {
@ -61,4 +61,9 @@ rec {
dummyOption = mkOption { }; dummyOption = mkOption { };
mkVMOverride' = mkOverride 9; mkVMOverride' = mkOverride 9;
homeStateVersion = hmBranch: {
# The flake passes a default setting, but we don't care about that
home.stateVersion = mkForce (if hmBranch == "unstable" then "22.05" else "21.11");
};
} }