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"
}
},
"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": {
"nixpkgs": [
"nixpkgs-unstable"
@ -195,6 +215,20 @@
"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": {
"locked": {
"lastModified": 1643052045,
@ -227,11 +261,11 @@
},
"nixpkgs-unstable": {
"locked": {
"lastModified": 1644420267,
"narHash": "sha256-rFJuctggkjM412OC6OGPdXogFp7czGDW05ueWqpJbj8=",
"lastModified": 1644525281,
"narHash": "sha256-D3VuWLdnLmAXIkooWAtbTGSQI9Fc1lkvAr94wTxhnTU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "98bb5b77c8c6666824a4c13d23befa1e07210ef1",
"rev": "48d63e924a2666baf37f4f14a18f19347fbd54a2",
"type": "github"
},
"original": {
@ -246,9 +280,11 @@
"deploy-rs": "deploy-rs",
"devshell": "devshell",
"flake-utils": "flake-utils_2",
"home-manager": "home-manager",
"home-manager-stable": "home-manager-stable",
"home-manager-unstable": "home-manager-unstable",
"impermanence": "impermanence",
"nix": "nix",
"nixpkgs-master": "nixpkgs-master",
"nixpkgs-stable": "nixpkgs-stable",
"nixpkgs-unstable": "nixpkgs-unstable"
}

View File

@ -5,18 +5,20 @@
flake-utils.url = "github:numtide/flake-utils";
devshell.url = "github:numtide/devshell";
devshell.inputs.nixpkgs.follows = "nixpkgs-unstable";
# Used by most systems
nixpkgs-master.url = "nixpkgs";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
# For extra-stable systems
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
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixpkgs-unstable";
deploy-rs.url = "github:serokell/deploy-rs";
deploy-rs.inputs.nixpkgs.follows = "nixpkgs-unstable";
home-manager.url = "home-manager";
home-manager.inputs.nixpkgs.follows = "nixpkgs-unstable";
# Stuff used by systems
nix.url = "nix/latest-release";
@ -30,7 +32,8 @@
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.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; };
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;
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;
# pkgs for dev shell etc
pkgs' = mapAttrs
(_: path: mkDefaultSystemsPkgs path (system: {
overlays = [
libOverlay
pkgsLibOverlay
inputs.devshell.overlay
inputs.agenix.overlay
inputs.deploy-rs.overlay
# TODO: This causes a compile from source which is pretty unnecessary
inputs.nix.overlay
(flakePackageOverlay inputs.home-manager system)
(flakePackageOverlay inputs.home-manager-unstable system)
];
}))
pkgsFlakes;
# Easiest to build the basic pkgs here (with our lib overlay too)
homePkgs' = mapAttrs
configPkgs' = mapAttrs
(_: path: mkDefaultSystemsPkgs path (_: {
overlays = [
libOverlay
pkgsLibOverlay
];
}))
pkgsFlakes;
@ -96,7 +111,8 @@
homeModules = inlineModules homeModules;
nixosConfigurations = import ./systems.nix {
inherit lib pkgsFlakes inputs;
inherit lib pkgsFlakes hmFlakes inputs;
pkgs' = configPkgs';
modules = attrValues modules;
homeModules = attrValues homeModules;
};
@ -104,8 +120,8 @@
vms = mapAttrs (_: system: system.config.my.build.devVM) self.nixosConfigurations;
homeConfigurations = import ./homes.nix {
inherit lib inputs;
pkgs' = homePkgs';
inherit lib hmFlakes inputs;
pkgs' = configPkgs';
modules = attrValues homeModules;
};
homes = mapAttrs(_: home: home.activationPackage) self.homeConfigurations;

View File

@ -1,91 +1,109 @@
{ lib, pkgs, inputs, isStandalone, config, ... }:
{ lib, pkgs, pkgs', inputs, config, ... }@args:
let
inherit (lib) mkMerge mkIf mkDefault mkForce;
inherit (lib) optionalAttrs versionAtLeast mkMerge mkIf mkDefault mkOption;
inherit (lib.my) mkOpt' dummyOption;
in
mkMerge [
{
nix.registry = {
pkgs = {
to = {
type = "path";
path = toString pkgs.path;
{
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 = {
pkgs = {
to = {
type = "path";
path = toString pkgs.path;
};
exact = true;
};
exact = true;
};
};
})
{
my.isStandalone = !(args ? sysConfig);
programs = {
# Even when enabled this will only be actually installed in standalone mode
# Note: `home-manager.path` is for telling home-manager is installed and setting it in NIX_PATH, which we should
# never care about.
home-manager.enable = true;
programs = {
# Even when enabled this will only be actually installed in standalone mode
# Note: `home-manager.path` is for telling home-manager is installed and setting it in NIX_PATH, which we should
# never care about.
home-manager.enable = true;
bash = {
# This not only installs bash but has home-manager control .bashrc and friends
enable = mkDefault true;
bash = {
# This not only installs bash but has home-manager control .bashrc and friends
enable = mkDefault true;
};
direnv = {
enable = mkDefault true;
nix-direnv.enable = true;
stdlib =
''
# addition to nix-direnv's use_nix that registers outputs as gc roots (as well as the .drv)
use_nix_outputs() {
local layout_dir drv deps
layout_dir="$(direnv_layout_dir)"
drv="$layout_dir/drv"
deps="$layout_dir/deps"
if [ ! -e "$deps" ] || (( "$(stat --format=%Z "$drv")" > "$(stat --format=%Z "$deps")" )); then
rm -rf "$deps"
mkdir -p "$deps"
nix-store --indirect --add-root "$deps/out" --realise $(nix-store --query --references "$drv") > /dev/null
log_status renewed outputs gc roots
fi
}
'';
};
htop = {
enable = true;
settings = {};
};
};
direnv = {
enable = mkDefault true;
nix-direnv.enable = true;
stdlib =
''
# addition to nix-direnv's use_nix that registers outputs as gc roots (as well as the .drv)
use_nix_outputs() {
local layout_dir drv deps
layout_dir="$(direnv_layout_dir)"
drv="$layout_dir/drv"
deps="$layout_dir/deps"
home = {
packages = with pkgs; [
tree
iperf3
];
if [ ! -e "$deps" ] || (( "$(stat --format=%Z "$drv")" > "$(stat --format=%Z "$deps")" )); then
rm -rf "$deps"
mkdir -p "$deps"
nix-store --indirect --add-root "$deps/out" --realise $(nix-store --query --references "$drv") > /dev/null
log_status renewed outputs gc roots
fi
}
'';
sessionVariables = {
EDITOR = "vim";
};
language.base = mkDefault "en_IE.UTF-8";
};
htop = {
enable = true;
settings = {};
}
(mkIf (config.my.isStandalone || !args.sysConfig.home-manager.useGlobalPkgs) {
# Note: If globalPkgs mode is on, then these will be overridden by the NixOS equivalents of these options
nixpkgs = {
overlays = [
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 = {
allowUnfree = true;
};
};
};
})
(mkIf config.my.isStandalone {
fonts.fontconfig.enable = true;
home = {
packages = with pkgs; [
tree
iperf3
];
sessionVariables = {
EDITOR = "vim";
home = {
packages = with pkgs; [
nix
];
};
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 {
# Note: this only applies outside NixOS where home-manager imports nixpkgs internally
nixpkgs = {
overlays = [
inputs.nix.overlay
];
config = {
allowUnfree = true;
};
};
fonts.fontconfig.enable = true;
home = {
packages = with pkgs; [
nix
];
};
})
]
})
];
}

View File

@ -1,23 +1,42 @@
{ lib, inputs, pkgs', modules }:
{ lib, hmFlakes, inputs, pkgs', modules }:
let
inherit (builtins) removeAttrs mapAttrs;
inherit (lib) recursiveUpdate;
inherit (lib) flatten optional recursiveUpdate;
inherit (lib.my) homeStateVersion;
mkHome = name: {
system,
nixpkgs ? "unstable",
home-manager ? nixpkgs,
config,
...
}@args:
let
rest = removeAttrs args [ "nixpkgs" "config" ];
rest = removeAttrs args [ "nixpkgs" "home-manager" "config" ];
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;
# 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};
extraModules = modules ++ [{
_module.args = { inherit inputs; isStandalone = true; };
}];
extraModules = modules ++ [
{
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
mapAttrs mkHome {

View File

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

View File

@ -1,14 +1,19 @@
{ lib, pkgs, inputs, homeModules, config, options, ... }:
{ lib, pkgs, inputs, options, config, ... }:
let
inherit (builtins) attrValues;
inherit (lib) mkIf mkDefault mkAliasDefinitions;
inherit (lib.my) mkOpt';
inherit (lib.my) mkOpt' dummyOption;
in
{
options.my = with lib.types; {
# 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.*`).";
homeConfig = mkOpt' anything {} "Home configuration (as `home-manager.users.*`)";
options = with lib.types; {
my = {
# 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.*`).";
homeConfig = mkOpt' anything { } "Home configuration (as `home-manager.users.*`)";
};
# Only present in >=22.05, so forward declare
documentation.nixos.options.warningsAreErrors = dummyOption;
};
config =
@ -28,11 +33,8 @@ in
};
home-manager = {
useGlobalPkgs = mkDefault true;
# Installs packages in the system config instead of in the local profile on activation
useUserPackages = mkDefault true;
sharedModules = homeModules ++ [{
_module.args = { inherit inputs; isStandalone = false; };
}];
};
users = {
@ -67,6 +69,13 @@ in
};
};
documentation = {
nixos = {
enable = mkDefault true;
options.warningsAreErrors = mkDefault false;
};
};
time.timeZone = mkDefault "Europe/Dublin";
boot = {
@ -106,4 +115,6 @@ in
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 {
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
inherit (builtins) attrValues mapAttrs;
inherit (lib) optionals mkDefault;
inherit (lib) flatten optional optionals mkDefault mkForce;
inherit (lib.my) homeStateVersion;
mkSystem =
name: {
system,
nixpkgs ? "unstable",
home-manager ? nixpkgs,
hmNixpkgs ? home-manager,
config,
# This causes a (very slow) docs rebuild on every change to a module's options it seems
docCustom ? true,
}:
let
# The flake contains `nixosSystem`, so we do need it (if we didn't have the TODO hacked version anyway)
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
# vm build stuff that breaks our impl. REMOVE WHEN 22.05 IS OUT!
nixosSystem' = args:
@ -23,22 +29,73 @@ let
system.nixos.revision = pkgsFlake.rev;
}];
});
in
nixosSystem' {
inherit lib system;
baseModules =
(import "${pkgsFlake}/nixos/modules/module-list.nix") ++ [
modules' = [
# Importing modules from module args causes infinite recursion
inputs.impermanence.nixosModule
hmFlake.nixosModule
inputs.agenix.nixosModules.age
inputs.home-manager.nixosModule
] ++ (optionals docCustom modules);
modules = (optionals (!docCustom) modules) ++ [
{
_module.args = { inherit system inputs homeModules; };
] ++ modules;
pkgs = pkgs'.${nixpkgs}.${system};
allPkgs = mapAttrs (_: p: p.${system}) pkgs';
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;
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
];
};
@ -47,6 +104,8 @@ mapAttrs mkSystem {
colony = {
system = "x86_64-linux";
nixpkgs = "stable";
home-manager = "unstable";
config = boxes/colony.nix;
docCustom = false;
};
}

View File

@ -1,7 +1,7 @@
{ lib }:
let
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;
in
rec {
@ -61,4 +61,9 @@ rec {
dummyOption = mkOption { };
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");
};
}