setups: replace as flake-parts module

This commit is contained in:
Gabriel Arazas 2024-01-16 14:54:50 +08:00
parent b06a06888f
commit 9e3469e752
No known key found for this signature in database
GPG Key ID: ADE0C41DAB221FCC
11 changed files with 802 additions and 486 deletions

View File

@ -57,7 +57,6 @@
nixpkgs.overlays = lib.attrValues inputs.self.overlays; nixpkgs.overlays = lib.attrValues inputs.self.overlays;
}; };
defaultSystem = "x86_64-linux";
defaultOverlays = lib.attrValues inputs.self.overlays; defaultOverlays = lib.attrValues inputs.self.overlays;
defaultExtraArgs = { defaultExtraArgs = {
inherit (inputs) nix-colors; inherit (inputs) nix-colors;
@ -66,6 +65,8 @@
perSystem = { lib, system, ... }: { perSystem = { lib, system, ... }: {
_module.args = { _module.args = {
# nixpkgs for this module should be used as less as possible especially
# for building NixOS and home-manager systems.
pkgs = import inputs.nixpkgs { pkgs = import inputs.nixpkgs {
inherit system; inherit system;
overlays = lib.attrValues inputs.self.overlays ++ [ overlays = lib.attrValues inputs.self.overlays ++ [

View File

@ -1,7 +1,6 @@
{ inputs { inputs
, lib , lib
, defaultSystem
, defaultExtraArgs , defaultExtraArgs
, defaultNixConf , defaultNixConf
@ -9,26 +8,12 @@
}: }:
let let
homeManagerConfigs = import ../../setups/home-manager.nix { inherit lib inputs; };
# The default config for our home-manager configurations. This is also to # The default config for our home-manager configurations. This is also to
# be used for sharing modules among home-manager users from NixOS # be used for sharing modules among home-manager users from NixOS
# configurations with `nixpkgs.useGlobalPkgs` set to `true` so avoid # configurations with `nixpkgs.useGlobalPkgs` set to `true` so avoid
# setting nixpkgs-related options here. # setting nixpkgs-related options here.
defaultHomeManagerConfig = defaultHomeManagerConfig =
{ pkgs, config, lib, ... }: { { pkgs, config, lib, ... }: {
imports =
# Import our own custom modules from here..
import ../../modules/home-manager { inherit lib; isInternal = true; }
# ...plus a bunch of third-party modules.
++ [
inputs.nur.hmModules.nur
inputs.sops-nix.homeManagerModules.sops
inputs.nix-index-database.hmModules.nix-index
inputs.nix-colors.homeManagerModules.default
];
# Set some extra, yeah? # Set some extra, yeah?
_module.args = defaultExtraArgs; _module.args = defaultExtraArgs;
@ -73,79 +58,64 @@ let
home.stateVersion = lib.mkDefault "23.11"; home.stateVersion = lib.mkDefault "23.11";
}; };
# A function that generates a home-manager module from a given user
# metadata.
userSpecificModule = user: metadata:
let
name = metadata.username or metadata._name or user;
modules = metadata.modules or [ ];
in in
{ lib, pkgs, config, ... }: { {
imports = modules ++ [ setups.home-manager = {
configs = {
foo-dogsquared = {
systems = [ "aarch64-linux" "x86_64-linux" ];
overlays = [
# Neovim nightly!
inputs.neovim-nightly-overlay.overlays.default
# Emacs unstable version!
inputs.emacs-overlay.overlays.default
# Helix master!
inputs.helix-editor.overlays.default
# Get all of the NUR.
inputs.nur.overlay
];
modules = [
inputs.nix-colors.homeManagerModules.default
inputs.nur.hmModules.nur
];
};
plover.systems = [ "x86_64-linux" ];
};
# This is to be used by the NixOS `home-manager.sharedModules` anyways.
sharedModules =
# Import our own custom modules from here..
import ../../modules/home-manager { inherit lib; isInternal = true; }
# ...plus a bunch of third-party modules.
++ [
inputs.sops-nix.homeManagerModules.sops
inputs.nix-index-database.hmModules.nix-index
defaultHomeManagerConfig defaultHomeManagerConfig
defaultNixConf
../home-manager/${name}
]; ];
standaloneConfigModules = [
defaultNixConf
({ config, lib, ... }: {
# Don't create the user directories since they are assumed to # Don't create the user directories since they are assumed to
# be already created by a pre-installed system (which should # be already created by a pre-installed system (which should
# already handle them). # already handle them).
xdg.userDirs.createDirectories = lib.mkForce false; xdg.userDirs.createDirectories = lib.mkForce false;
# Setting the homely options.
home.username = lib.mkForce name;
home.homeDirectory = lib.mkForce (metadata.home-directory or "/home/${config.home.username}");
programs.home-manager.enable = lib.mkForce true; programs.home-manager.enable = lib.mkForce true;
targets.genericLinux.enable = true; targets.genericLinux.enable = true;
})
];
}; };
in
{
flake = { flake = {
# Extending home-manager with my custom modules, if anyone cares. # Extending home-manager with my custom modules, if anyone cares.
homeModules.default = import ../../modules/home-manager { inherit lib; }; homeModules.default = import ../../modules/home-manager { inherit lib; };
# Put them home-manager configurations.
homeConfigurations =
let
inherit (import ../../lib/extras/flake-helpers.nix { inherit lib inputs; }) mkHome listImagesWithSystems;
in
lib.mapAttrs
(user: metadata:
mkHome {
pkgs = import inputs.${metadata.nixpkgs-channel or "nixpkgs"} {
system = metadata._system;
};
extraModules = [ (userSpecificModule user metadata) ];
home-manager-channel = metadata.home-manager-channel or "home-manager";
})
(listImagesWithSystems homeManagerConfigs);
# Include these as part of the deploy-rs nodes because why not.
deploy.nodes =
lib.mapAttrs'
(name: value:
let
metadata = homeManagerConfigs.${name};
username = metadata.deploy.username or name;
in
lib.nameValuePair "home-manager-${name}" {
hostname = metadata.deploy.hostname or name;
autoRollback = metadata.deploy.auto-rollback or true;
magicRollback = metadata.deploy.magic-rollback or true;
fastConnection = metadata.deploy.fast-connection or true;
remoteBuild = metadata.deploy.remote-build or false;
profiles.home = {
sshUser = metadata.deploy.ssh-user or username;
user = metadata.deploy.user or username;
path = inputs.deploy.lib.${metadata.system or defaultSystem}.activate.home-manager value;
};
})
inputs.self.homeConfigurations;
};
_module.args = {
inherit homeManagerConfigs defaultHomeManagerConfig;
}; };
} }

View File

@ -1,52 +1,13 @@
{ inputs { inputs
, lib , lib
, defaultSystem
, defaultExtraArgs , defaultExtraArgs
, defaultNixConf , defaultNixConf
, defaultHomeManagerConfig
, ... , ...
}: }:
let let
inherit (import ../../lib/extras/flake-helpers.nix { inherit lib inputs; }) mkHost mkImage listImagesWithSystems;
nixosConfigs = import ../../setups/nixos.nix { inherit lib inputs; };
# A function that generates a NixOS module setting up the baseline
# configuration for this project (or at least for this subset of NixOS
# configurations).
hostSpecificModule = host: metadata:
let
modules = metadata.modules or [ ];
name = metadata._name or host;
in
{ lib, ... }: {
imports = modules ++ [
inputs.${metadata.home-manager-channel or "home-manager"}.nixosModules.home-manager
defaultNixOSConfig
defaultNixConf
../nixos/${host}
];
config = lib.mkMerge [
{
networking.hostName = lib.mkForce metadata.hostname or name;
nixpkgs.hostPlatform = metadata._system or defaultSystem;
# The global configuration for the home-manager module.
home-manager.useUserPackages = lib.mkDefault true;
home-manager.useGlobalPkgs = lib.mkDefault true;
home-manager.sharedModules = [ defaultHomeManagerConfig ];
}
(lib.mkIf (metadata ? domain)
{ networking.domain = lib.mkForce metadata.domain; })
];
};
# The shared configuration for the entire list of hosts for this cluster. # The shared configuration for the entire list of hosts for this cluster.
# Take note to only set as minimal configuration as possible since we're # Take note to only set as minimal configuration as possible since we're
# also using this with the stable version of nixpkgs. # also using this with the stable version of nixpkgs.
@ -60,23 +21,6 @@ let
XDG_STATE_HOME = "$HOME/.local/state"; XDG_STATE_HOME = "$HOME/.local/state";
}; };
# Only use imports as minimally as possible with the absolute
# requirements of a host. On second thought, only on flakes with
# optional NixOS modules.
imports =
# Append with our custom NixOS modules from the modules folder.
import ../../modules/nixos { inherit lib; isInternal = true; }
# Then, make the most with the modules from the flake inputs. Take
# note importing some modules such as home-manager are as part of the
# declarative host config so be sure to check out
# `hostSpecificModule` function as well as the declarative host setup.
++ [
inputs.nix-index-database.nixosModules.nix-index
inputs.sops-nix.nixosModules.sops
inputs.disko.nixosModules.disko
];
_module.args = defaultExtraArgs; _module.args = defaultExtraArgs;
# Find Nix files with these! Even if nix-index is already enabled, it # Find Nix files with these! Even if nix-index is already enabled, it
@ -133,80 +77,100 @@ let
}; };
in in
{ {
setups.nixos = {
configs = {
# The main desktop.
ni = {
systems = [ "x86_64-linux" ];
formats = null;
overlays = [
# Neovim nightly!
inputs.neovim-nightly-overlay.overlays.default
# Emacs unstable version!
inputs.emacs-overlay.overlays.default
# Helix master!
inputs.helix-editor.overlays.default
# Access to NUR.
inputs.nur.overlay
];
modules = [
inputs.nur.nixosModules.nur
];
};
# A remote server.
plover = {
systems = [ "x86_64-linux" ];
formats = null;
domain = "foodogsquared.one";
deploy = {
hostname = "plover.foodogsquared.one";
auto-rollback = true;
magic-rollback = true;
};
};
# TODO: Remove extra newlines that are here for whatever reason.
#{{{
void = {
systems = [ "x86_64-linux" ];
formats = [ "vm" ];
};
#}}}
# The barely customized non-graphical installer.
bootstrap = {
systems = [ "aarch64-linux" "x86_64-linux" ];
formats = [ "install-iso" ];
nixpkgs-branch = "nixos-unstable-small";
};
# The barely customized graphical installer.
graphical-installer = {
systems = [ "aarch64-linux" "x86_64-linux" ];
formats = [ "install-iso" ];
};
# The WSL system (that is yet to be used).
winnowing = {
systems = [ "x86_64-linux" ];
formats = null;
overlays = [
inputs.neovim-nightly-overlay.overlays.default
];
modules = [
# Well, well, well...
inputs.nixos-wsl.nixosModules.default
];
};
};
# Only use imports as minimally as possible with the absolute
# requirements of a host. On second thought, only on flakes with
# optional NixOS modules.
sharedModules =
# Append with our custom NixOS modules from the modules folder.
import ../../modules/nixos { inherit lib; isInternal = true; }
# Then, make the most with the modules from the flake inputs. Take
# note importing some modules such as home-manager are as part of the
# declarative host config so be sure to check out
# `hostSpecificModule` function as well as the declarative host setup.
++ [
inputs.nix-index-database.nixosModules.nix-index
inputs.sops-nix.nixosModules.sops
inputs.disko.nixosModules.disko
defaultNixConf
defaultNixOSConfig
];
};
flake = { flake = {
# Listing my public NixOS modules if anyone cares. # Listing my public NixOS modules if anyone cares.
nixosModules.default = import ../../modules/nixos { inherit lib; }; nixosModules.default = import ../../modules/nixos { inherit lib; };
# A list of NixOS configurations from the `./configs/nixos` folder starting
# from project root. It also has some sensible default configurations.
nixosConfigurations =
lib.mapAttrs
(user: metadata:
mkHost {
nixpkgs-channel = metadata.nixpkgs-channel or "nixpkgs";
extraModules = [ (hostSpecificModule user metadata) ];
})
(listImagesWithSystems nixosConfigs);
# Deploy them server configs like a lazy bum-bum.
#
# Anyways, don't forget to flush out your shell history regularly or make
# it ignored which is a more ergonomic option.
deploy.nodes =
lib.mapAttrs'
(name: value:
let
metadata = nixosConfigs.${name};
in
lib.nameValuePair "nixos-${name}" {
hostname = metadata.deploy.hostname or name;
autoRollback = metadata.deploy.auto-rollback or true;
magicRollback = metadata.deploy.magic-rollback or true;
fastConnection = metadata.deploy.fast-connection or true;
remoteBuild = metadata.deploy.remote-build or false;
profiles.system = {
sshUser = metadata.deploy.ssh-user or "admin";
user = "root";
path = inputs.deploy.lib.${metadata.system or defaultSystem}.activate.nixos value;
};
})
inputs.self.nixosConfigurations;
};
perSystem = { system, lib, ... }: {
# This contains images that are meant to be built and distributed
# somewhere else including those NixOS configurations that are built as
# an ISO.
images =
let
validImages = lib.filterAttrs
(host: metadata:
metadata.format != null && (lib.elem system metadata.systems))
nixosConfigs;
in
lib.mapAttrs'
(host: metadata:
let
name = metadata.hostname or host;
nixpkgs-channel = metadata.nixpkgs-channel or "nixpkgs";
in
lib.nameValuePair name (mkImage {
inherit (metadata) format;
inherit nixpkgs-channel;
extraModules = [
(hostSpecificModule host metadata)
# Forcing the host platform set by the host (if there's any).
# Ideally, there shouldn't be.
({ lib, ... }: {
nixpkgs.hostPlatform = lib.mkForce system;
})
];
}))
validImages;
};
_module.args = {
inherit defaultNixOSConfig nixosConfigs;
}; };
} }

View File

@ -1,103 +0,0 @@
# A set of functions intended for creating images. THis is meant to be imported
# for use in flake.nix and nowhere else.
{ inputs, lib }:
let
# A function that generates a lambda suitable for `lib.extend`.
extendLib = import ./extend-lib.nix;
# For NixOS systems.
specialArgs = {
foodogsquaredModulesPath = builtins.toString ../../modules/nixos;
};
in
{
# A thin wrapper around the NixOS configuration function.
mkHost = { extraModules ? [ ], nixpkgs-channel ? "nixpkgs" }:
let
nixpkgs = inputs.${nixpkgs-channel};
# Just to be sure, we'll use everything with the given nixpkgs' stdlib.
lib' = nixpkgs.lib.extend extendLib;
# A modified version of `nixosSystem` from nixpkgs flake. There is a
# recent change at nixpkgs (at 039f73f134546e59ec6f1b56b4aff5b81d889f64)
# that prevents setting our own custom functions so we'll have to
# evaluate the NixOS system ourselves.
nixosSystem = args: import "${nixpkgs}/nixos/lib/eval-config.nix" args;
in
(lib'.makeOverridable nixosSystem) {
inherit specialArgs;
lib = lib';
modules = extraModules;
# Since we're setting it through nixpkgs.hostPlatform, we'll have to pass
# this as null.
system = null;
};
# A thin wrapper around the home-manager configuration function.
mkHome = { pkgs, extraModules ? [ ], home-manager-channel ? "home-manager" }:
inputs.${home-manager-channel}.lib.homeManagerConfiguration {
specialArgs = {
foodogsquaredModulesPath = builtins.toString ../../modules/home-manager;
};
inherit pkgs;
lib = pkgs.lib.extend extendLib;
modules = extraModules;
};
# A thin wrapper around the nixos-generators `nixosGenerate` function.
mkImage = { nixpkgs-channel ? "nixpkgs", extraModules ? [ ], format ? "iso" }:
let
nixpkgs = inputs.${nixpkgs-channel};
# A modified version of `nixosSystem` from nixpkgs flake similar to the
# one found in mkHost.
nixosSystem = args: import "${nixpkgs}/nixos/lib/eval-config.nix" args;
image = nixosSystem {
inherit specialArgs;
lib = nixpkgs.lib.extend extendLib;
modules = extraModules ++ [ inputs.nixos-generators.nixosModules.${format} ];
# We're also setting this up modularly so we'll have to pass these as
# null.
system = null;
};
in
image.config.system.build.${image.config.formatAttr};
# A function to modify the given table of declarative setups (i.e., hosts,
# users) to have its own system attribute and its name.
#
# If the given setup only has one system, its name will stay the same.
# Otherwise, it will be appended with the system as part of the name (e.g.,
# `$NAME-$SYSTEM`).
listImagesWithSystems = data:
lib.foldlAttrs
(acc: name: metadata:
let
name' = metadata.hostname or name;
in
if lib.length metadata.systems > 1 then
acc // (lib.foldl
(images: system: images // {
"${name'}-${system}" = metadata // {
_system = system;
_name = name';
};
})
{ }
metadata.systems)
else
acc // {
"${name'}" = metadata // {
_system = lib.head metadata.systems;
_name = name';
};
})
{ }
data;
}

View File

@ -7,5 +7,7 @@
{ {
imports = [ imports = [
./images.nix ./images.nix
./deploy-rs-nodes.nix
./setups
]; ];
} }

View File

@ -0,0 +1,25 @@
{ lib, flake-parts-lib, ... }:
let
deployType = { config, lib, pkgs, ... }: {
options.nodes = lib.mkOption {
type = with lib.types; attrsOf anything;
description = ''
A set of deploy-rs nodes.
'';
};
};
in
{
options = {
flake = flake-parts-lib.mkSubmoduleOptions {
deploy = lib.mkOption {
type = with lib.types; submodule deployType;
default = { };
description = ''
An attribute set of deploy-rs nodes
'';
};
};
};
}

View File

@ -0,0 +1,6 @@
{
imports = [
./nixos.nix
./home-manager.nix
];
}

View File

@ -0,0 +1,264 @@
# This is the declarative user management converted into a flake-parts module.
{ config, lib, inputs, ... }:
let
cfg = config.setups.home-manager;
# A thin wrapper around the home-manager configuration function.
mkHome = { system, nixpkgs-branch ? "nixpkgs", home-manager-branch ? "home-manager", extraModules ? [ ] }:
let
pkgs = inputs.${nixpkgs-branch}.legacyPackages.${system};
in
inputs.${home-manager-branch}.lib.homeManagerConfiguration {
extraSpecialArgs = {
foodogsquaredModulesPath = builtins.toString ../../home-manager;
};
inherit pkgs;
lib = pkgs.lib.extend (import ../../../lib/extras/extend-lib.nix);
modules = extraModules;
};
deploySettingsType = { config, lib, ... }: {
freeformType = with lib.types; attrsOf anything;
options = {
fastConnection = lib.mkEnableOption "deploy-rs to assume the target machine is considered fast";
autoRollback = lib.mkEnableOption "deploy-rs auto-rollback feature";
magicRollback = lib.mkEnableOption "deploy-rs magic rollback feature";
remoteBuild = lib.mkEnableOption "pass the build process to the remote machine";
profiles = lib.mkOption {
type = with lib.types; functionTo (attrsOf anything);
default = os: {
sshUser = "root";
user = "admin";
path = inputs.deploy-rs.lib.${os.system}.activate.nixos os.config;
};
defaultText = lib.literalExpression ''
os: {
sshUser = "root";
user = "admin";
path = inputs.deploy-rs.lib.''${os.system}.activate.nixos os.config;
}
'';
description = ''
A set of profiles for the resulting deploy node.
Since each config can result in more than one NixOS system, it has to
be a function where the passed argument is an attribute set with the
following values:
* `name` is the attribute name from `configs`.
* `config` is the NixOS configuration itself.
* `system` is a string indicating the platform of the NixOS system.
If unset, it will create a deploy-rs node profile called `home`
similar to those from nixops.
'';
};
};
};
configType = { config, name, lib, ... }: {
options = {
systems = lib.mkOption {
type = with lib.types; listOf str;
default = lib.lists.take 1 config.systems;
example = [ "x86_64-linux" "aarch64-linux" ];
description = ''
A list of platforms that the NixOS configuration is supposed to be
deployed on.
'';
};
modules = lib.mkOption {
type = with lib.types; listOf raw;
default = [];
description = ''
A list of NixOS modules specific for that host.
'';
};
overlays = lib.mkOption {
type = with lib.types; listOf (functionTo raw);
default = [];
example = lib.literalExpression ''
[
inputs.neovim-nightly-overlay.overlays.default
inputs.emacs-overlay.overlays.default
]
'';
description = ''
A list of overlays to be applied for that host.
'';
};
nixpkgs-branch = lib.mkOption {
type = lib.types.str;
default = "nixpkgs";
example = "nixos-unstable-small";
description = ''
The nixpkgs branch to be used for evaluating the NixOS configuration.
By default, it will use the `nixpkgs` flake input.
::: {.note}
This is based from your flake inputs and not somewhere else. If you
want to have support for multiple nixpkgs branch, simply add them as
a flake input.
:::
'';
};
home-manager-branch = lib.mkOption {
type = lib.types.str;
default = "home-manager";
example = "home-manager-stable";
description = ''
The home-manager branch to be used for the NixOS module. By default,
it will use the `home-manager` flake input.
'';
};
home-directory = lib.mkOption {
type = lib.types.path;
default = "/home/${name}";
example = "/var/home/public-user";
description = ''
The home directory of the home-manager user.
'';
};
deploy = lib.mkOption {
type = with lib.types; nullOr (submodule deploySettingsType);
default = null;
description = ''
deploy-rs settings to be passed onto the home-manager configuration node.
'';
};
};
config = {
modules = [
../../../configs/home-manager/${name}
{
nixpkgs.overlays = config.overlays;
home.username = lib.mkForce name;
home.homeDirectory = lib.mkForce config.home-directory;
}
];
};
};
in
{
options.setups.home-manager = {
sharedModules = lib.mkOption {
type = with lib.types; listOf raw;
default = [];
description = ''
A list of modules to be shared by all of the declarative home-manager
setups.
::: {.note}
Note this will be shared into NixOS as well through the home-manager
NixOS module.
:::
'';
};
standaloneConfigModules = lib.mkOption {
type = with lib.types; listOf raw;
default = [];
internal = true;
description = ''
A list of modules to be added alongside the shared home-manager modules
in the standalone home-manager configurations.
This is useful for modules that are only suitable for standalone
home-manager configurations compared to home-manager configurations
used as a NixOS module.
'';
};
configs = lib.mkOption {
type = with lib.types; attrsOf (submodule configType);
default = {};
description = ''
An attribute set of metadata for the declarative home-manager setups.
'';
example = lib.literalExpression ''
{
foo-dogsquared = {
systems = [ "aarch64-linux" "x86_64-linux" ];
modules = [
inputs.nur.hmModules.nur
inputs.nixvim.homeManagerModules.nixvim
];
overlays = [
inputs.neovim-nightly-overlay.overlays.default
inputs.emacs-overlay.overlays.default
inputs.helix-editor.overlays.default
inputs.nur.overlay
];
};
plover.systems = [ "x86_64-linux" ];
}
'';
};
};
config = lib.mkIf (cfg.configs != {}) {
flake =
let
# A quick data structure we can pass through multiple build pipelines.
pureHomeManagerConfigs =
let
generatePureConfigs = username: metadata:
lib.listToAttrs
(builtins.map
(system:
let
name = "${username}-${system}";
in
lib.nameValuePair name (mkHome {
inherit (metadata) nixpkgs-branch home-manager-branch;
inherit system;
extraModules =
cfg.sharedModules
++ cfg.standaloneConfigModules
++ metadata.modules;
})
)
metadata.systems);
in
lib.mapAttrs
(hostname: metadata:
generatePureConfigs hostname metadata)
cfg.configs;
in
{
homeConfigurations =
lib.concatMapAttrs
(name: configs:
lib.mapAttrs'
(system: config: lib.nameValuePair "${name}-${system}" config)
configs)
pureHomeManagerConfigs;
deploy.nodes =
let
validConfigs =
lib.filterAttrs
(name: _: cfg.configs.${name}.deploy != null)
pureHomeManagerConfigs;
in
lib.concatMapAttrs
(name: configs:
lib.mapAttrs'
(system: config: lib.nameValuePair "home-manager-${name}-${system}"
(cfg.configs.${name}.deploy.profiles { inherit name config system; })))
validConfigs;
};
};
}

View File

@ -0,0 +1,357 @@
# This is the declarative host management converted into a flake-parts module.
# It also enforces a structure for declarative NixOS setups such as a mandatory
# inclusion of the home-manager NixOS module, a deploy-rs node, a hostname and
# an optional domain, and deploy-rs-related options so it isn't really made to
# be generic or anything like that.
{ config, lib, inputs, ... }:
let
cfg = config.setups.nixos;
# A thin wrapper around the NixOS configuration function.
mkHost = { extraModules ? [ ], nixpkgs-branch ? "nixpkgs", system }:
let
nixpkgs = inputs.${nixpkgs-branch};
# Just to be sure, we'll use everything with the given nixpkgs' stdlib.
lib' = nixpkgs.lib.extend (import ../../../lib/extras/extend-lib.nix);
# A modified version of `nixosSystem` from nixpkgs flake. There is a
# recent change at nixpkgs (at 039f73f134546e59ec6f1b56b4aff5b81d889f64)
# that prevents setting our own custom functions so we'll have to
# evaluate the NixOS system ourselves.
nixosSystem = args: import "${nixpkgs}/nixos/lib/eval-config.nix" args;
in
(lib'.makeOverridable nixosSystem) {
specialArgs = {
foodogsquaredModulesPath = builtins.toString ../../nixos;
};
lib = lib';
modules = extraModules ++ [{
nixpkgs.hostPlatform = lib.mkForce system;
}];
# Since we're setting it through nixpkgs.hostPlatform, we'll have to pass
# this as null.
system = null;
};
# A very very thin wrapper around `mkHost` to build with the given format.
mkImage = { system, nixpkgs-branch ? "nixpkgs", extraModules ? [ ], format ? "iso" }:
let
extraModules' =
extraModules ++ [ inputs.nixos-generators.nixosModules.${format} ];
image = mkHost {
inherit nixpkgs-branch system;
extraModules = extraModules';
};
in
image.config.system.build.${image.config.formatAttr};
deployNodeType = { config, lib, ... }: {
freeformType = with lib.types; attrsOf anything;
options = {
fastConnection = lib.mkEnableOption "deploy-rs to assume the target machine is considered fast";
autoRollback = lib.mkEnableOption "deploy-rs auto-rollback feature";
magicRollback = lib.mkEnableOption "deploy-rs magic rollback feature";
remoteBuild = lib.mkEnableOption "pass the build process to the remote machine";
profiles = lib.mkOption {
type = with lib.types; functionTo (attrsOf anything);
default = os: {
sshUser = "root";
user = "admin";
path = inputs.deploy.lib.${os.system}.activate.nixos os.config;
};
defaultText = lib.literalExpression ''
os: {
sshUser = "root";
user = "admin";
path = inputs.deploy-rs.lib.''${os.system}.activate.nixos os.config;
}
'';
description = ''
A set of profiles for the resulting deploy node.
Since each config can result in more than one NixOS system, it has to
be a function where the passed argument is an attribute set with the
following values:
* `name` is the attribute name from `configs`.
* `config` is the NixOS configuration itself.
* `system` is a string indicating the platform of the NixOS system.
If unset, it will create a deploy-rs node profile called `system`
similar to those from nixops.
'';
};
};
};
configType = { config, name, lib, ... }: {
options = {
systems = lib.mkOption {
type = with lib.types; listOf str;
default = lib.lists.take 1 config.systems;
defaultText = "The first system listed from `config.systems`.";
example = [ "x86_64-linux" "aarch64-linux" ];
description = ''
A list of platforms that the NixOS configuration is supposed to be
deployed on.
'';
};
formats = lib.mkOption {
type = with lib.types; nullOr (listOf str);
default = [ "iso" ];
description = ''
The image formats to be generated from nixos-generators. When given
as `null`, it is listed as part of `nixosConfigurations` and excluded
from `images` flake output which is often the case for desktop NixOS
systems.
'';
};
modules = lib.mkOption {
type = with lib.types; listOf raw;
default = [];
description = ''
A list of NixOS modules specific for that host.
'';
};
overlays = lib.mkOption {
type = with lib.types; listOf (functionTo raw);
default = [];
example = lib.literalExpression ''
[
inputs.neovim-nightly-overlay.overlays.default
inputs.emacs-overlay.overlays.default
]
'';
description = ''
A list of overlays to be applied for that host.
'';
};
hostname = lib.mkOption {
type = lib.types.nonEmptyStr;
default = name;
example = "MyWhatNow";
description = "The hostname of the NixOS configuration.";
};
domain = lib.mkOption {
type = with lib.types; nullOr nonEmptyStr;
default = null;
example = "work.example.com";
description = "The domain of the NixOS system.";
};
nixpkgs-branch = lib.mkOption {
type = lib.types.str;
default = "nixpkgs";
description = ''
The nixpkgs branch to be used for evaluating the NixOS configuration.
By default, it will use the `nixpkgs` flake input.
::: {.note}
This is based from your flake inputs and not somewhere else. If you
want to have support for multiple nixpkgs branch, simply add them as
a flake input.
:::
'';
example = "nixos-unstable-small";
};
home-manager-branch = lib.mkOption {
type = lib.types.str;
default = "home-manager";
example = "home-manager-stable";
description = ''
The home-manager branch to be used for the NixOS module. By default,
it will use the `home-manager` flake input.
'';
};
deploy = lib.mkOption {
type = with lib.types; nullOr (submodule deployNodeType);
default = null;
description = ''
deploy-rs node settings for the resulting NixOS configuration.
'';
example = {
hostname = "work1.example.com";
fastConnection = true;
autoRollback = true;
magicRollback = true;
remoteBuild = true;
};
};
};
config = {
modules = [
inputs.${config.home-manager-branch}.nixosModules.home-manager
../../../configs/nixos/${name}
{
nixpkgs.overlays = config.overlays;
networking.hostName = lib.mkDefault config.hostname;
}
(lib.mkIf (config.domain != null) {
networking.domain = lib.mkForce config.domain;
})
];
};
};
in
{
options.setups.nixos = {
sharedModules = lib.mkOption {
type = with lib.types; listOf raw;
default = [];
description = ''
A list of modules to be shared by all of the declarative NixOS setups.
'';
};
configs = lib.mkOption {
type = with lib.types; attrsOf (submodule configType);
default = {};
description = ''
An attribute set of metadata for the declarative NixOS setups. This
will then be used for related flake outputs such as
`nixosConfigurations` and `images`.
::: {.note}
For `nixosConfigurations` output, each of them is a pure NixOS
configuration where `nixpkgs.hostPlatform` is set and each of the
config is renamed into `$CONFIGNAME-$SYSTEM` if the host is configured
to have more than one system.
:::
'';
example = lib.literalExpression ''
{
desktop = {
systems = [ "x86_64-linux" "aarch64-linux" ];
formats = null;
modules = [
inputs.nur.nixosModules.nur
];
overlays = [
# Neovim nightly!
inputs.neovim-nightly-overlay.overlays.default
# Emacs unstable version!
inputs.emacs-overlay.overlays.default
# Helix master!
inputs.helix-editor.overlays.default
# Access to NUR.
inputs.nur.overlay
];
};
server = {
systems = [ "x86_64-linux" "aarch64-linux" ];
domain = "work.example.com";
formats = [ "do" "linode" ];
nixpkgs-branch = "nixos-unstable-small";
deploy = {
};
};
vm = {
systems = [ "x86_64-linux" "aarch64-linux" ];
formats = [ "vm" ];
};
}
'';
};
};
config = lib.mkIf (cfg.configs != {}) {
setups.nixos.sharedModules = [
{
home-manager.useUserPackages = lib.mkDefault true;
home-manager.useGlobalPkgs = lib.mkDefault true;
home-manager.sharedModules = config.setups.home-manager.sharedModules;
}
];
flake =
let
# A quick data structure we can pass through multiple build pipelines.
pureNixosConfigs =
let
validConfigs =
lib.filterAttrs (_: v: v.formats == null || v.deploy != null) cfg.configs;
generatePureConfigs = hostname: metadata:
lib.listToAttrs
(builtins.map
(system:
lib.nameValuePair system (mkHost {
nixpkgs-branch = metadata.nixpkgs-branch;
extraModules = cfg.sharedModules ++ metadata.modules;
inherit system;
})
)
metadata.systems);
in
lib.mapAttrs
(hostname: metadata:
generatePureConfigs hostname metadata)
validConfigs;
in
{
nixosConfigurations =
lib.concatMapAttrs
(name: configs:
lib.mapAttrs'
(system: config: lib.nameValuePair "${name}-${system}" config)
configs)
pureNixosConfigs;
deploy.nodes =
let
validConfigs =
lib.filterAttrs
(name: _: cfg.configs.${name}.deploy != null)
pureNixosConfigs;
in
lib.concatMapAttrs
(name: configs:
lib.mapAttrs'
(system: config: lib.nameValuePair "nixos-${name}-${system}"
(cfg.configs.${name}.deploy.profiles { inherit name config system; }))
configs)
validConfigs;
};
perSystem = { system, lib, ... }: {
images =
let
validImages = lib.filterAttrs
(host: metadata:
metadata.formats != null && (lib.elem system metadata.systems))
cfg.configs;
in
lib.mapAttrs'
(host: metadata:
let
name = metadata.hostname or host;
nixpkgs-channel = metadata.nixpkgs-channel or "nixpkgs";
in
lib.nameValuePair name (mkImage {
inherit (metadata) format;
inherit nixpkgs-channel system;
extraModules = cfg.sharedModules ++ metadata.modules;
}))
validImages;
};
};
}

View File

@ -1,59 +0,0 @@
/*
This is project data for deploying home-manager users with this flake. Each
of the users defined here should correspond to one of the home-manager users
at `./configs/home-manager/`.
Schema:
* systems
A list of host platforms to be deployed. When given no systems, it will
be deployed with `x86_64-linux`.
* modules
A list of home-manager modules to be included. Take note there is a
baseline configuration defined at `flake.nix`. You should add modules
very minimally here such as additional overlays, modules, and so forth.
* home-manager-channel
The home-manager branch to be used. By default, it uses the
`home-manager` flake input which follows the `home-manager-unstable`
input.
* nixpkgs-channel
The nixpkgs branch to be included. By default, it uses the `nixpkgs`
flake input which follows the `nixos-unstable` input.
* deploy
An attribute set of options for deploy-rs nodes.
* username
The username of the home-manager user. By default, it will use the
attribute name.
* home-directory
The home directory of the home-manager user. By default, it is
set to "/home/${username}".
*/
{ lib, inputs }:
{
foo-dogsquared = {
systems = [ "aarch64-linux" "x86_64-linux" ];
modules = [
inputs.nur.hmModules.nur
({ config, ... }: {
nixpkgs.overlays = [
# Neovim nightly!
inputs.neovim-nightly-overlay.overlays.default
# Emacs unstable version!
inputs.emacs-overlay.overlays.default
# Helix master!
inputs.helix-editor.overlays.default
# Get all of the NUR.
inputs.nur.overlay
];
})
];
};
plover.systems = [ "x86_64-linux" ];
}

View File

@ -1,111 +0,0 @@
/*
This is a custom data for this project where it lists the images found in
this flake. This can range from NixOS configurations intended to be deployed
for servers and desktops to installers.
The data is then used for the image creation functions found in `flake.nix`.
Each of the entry should correspond to one of the hosts in `./configs/nixos/`
directory.
Schema:
* systems
A list of systems that is expected to be deployed. This is required and
will have a default list of "x86_64-linux" when no system is given.
* format
The image format to be generated from nixos-generators. You can give it
as `null` when not intended to be listed as part of the images which is
often the case for desktop NixOS systems.
* modules
A list of extra NixOS modules to be passed. You'll want to see the
baseline host configuration defined in `flake.nix`.
* deploy
An attribute set of arguments similar to the `deploy` CLI. When this
attribute is present, it will be assumed as part of NixOS configurations
even with `format = null` which is often the case for bare metal NixOS
servers that also has a suitable image format for deployment.
* hostname
The hostname of the host. By default, it assumes the hostname being given
from the attribute name.
* domain
The domain set for the host. Normally given to server systems.
*/
{ lib, inputs }:
{
# The main desktop.
ni = {
systems = [ "x86_64-linux" ];
format = null;
modules = [
inputs.nur.nixosModules.nur
({ config, ... }: {
nixpkgs.overlays = [
# Neovim nightly!
inputs.neovim-nightly-overlay.overlays.default
# Emacs unstable version!
inputs.emacs-overlay.overlays.default
# Helix master!
inputs.helix-editor.overlays.default
# Access to NUR.
inputs.nur.overlay
];
})
];
};
# A remote server.
plover = {
systems = [ "x86_64-linux" ];
format = null;
domain = "foodogsquared.one";
deploy = {
hostname = "plover.foodogsquared.one";
auto-rollback = true;
magic-rollback = true;
};
};
# TODO: Remove extra newlines that are here for whatever reason.
#{{{
void = {
systems = [ "x86_64-linux" ];
format = "vm";
};
#}}}
# The barely customized non-graphical installer.
bootstrap = {
systems = [ "aarch64-linux" "x86_64-linux" ];
format = "install-iso";
nixpkgs-channel = "nixos-unstable-small";
};
# The barely customized graphical installer.
graphical-installer = {
systems = [ "aarch64-linux" "x86_64-linux" ];
format = "install-iso";
};
# The WSL system (that is yet to be used).
winnowing = {
systems = [ "x86_64-linux" ];
format = null;
modules = [
# Well, well, well...
inputs.nixos-wsl.nixosModules.default
({ config, ... }: {
nixpkgs.overlays = [
# Make the most of it.
inputs.neovim-nightly-overlay.overlays.default
];
})
];
};
}
# vim:foldmethod=marker