Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(flake): flakify morph #211

Merged
merged 3 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if has nix; then
use flake .
fi
28 changes: 28 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This file contains a list of commits that are not likely what you
# are looking for in a blame, such as mass reformatting or renaming.
# You can set this file as a default ignore file for blame by running
# the following command.
#
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
#
# To temporarily not use this file add
# --ignore-revs-file=""
# to your blame command.
#
# The ignoreRevsFile can't be set globally due to blame failing if the file isn't present.
# To not have to set the option in every repository it is needed in,
# save the following script in your path with the name "git-bblame"
# now you can run
# $ git bblame $FILE
# to use the .git-blame-ignore-revs file if it is present.
#
# #!/usr/bin/env bash
# repo_root=$(git rev-parse --show-toplevel)
# if [[ -e $repo_root/.git-blame-ignore-revs ]]; then
# git blame --ignore-revs-file="$repo_root/.git-blame-ignore-revs" $@
# else
# git blame $@
# fi

# treewide nix fmt after flakification
4a3684b18388d727f36a72f736f68ef379dbb209
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@

# nix result links
/result*
/repl-result*

# Direnv
.direnv

# Generated by nix-pre-commit-hooks
/.pre-commit-config.yaml

205 changes: 105 additions & 100 deletions data/eval-machines.nix
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,88 @@
{ networkExpr }:

let
network = import networkExpr;
nwPkgs = network.network.pkgs or {};
lib = network.network.lib or nwPkgs.lib or (import <nixpkgs/lib>);
evalConfig = network.network.evalConfig or ((nwPkgs.path or <nixpkgs>) + "/nixos/lib/eval-config.nix");
runCommand = network.network.runCommand or nwPkgs.runCommand or ((import <nixpkgs> {}).runCommand);
in
with lib;
network = import networkExpr;
nwPkgs = network.network.pkgs or { };
lib = network.network.lib or nwPkgs.lib or (import <nixpkgs/lib>);
evalConfig = network.network.evalConfig or ((nwPkgs.path or <nixpkgs>)
+ "/nixos/lib/eval-config.nix");
runCommand =
network.network.runCommand or nwPkgs.runCommand or (import <nixpkgs>
{ }).runCommand;
in with lib;

let
modules = { machineName, nodes, check }: [
# Get the configuration of this machine from each network
# expression, attaching _file attributes so the NixOS module
# system can give sensible error messages.
{ imports = [ network.${machineName} ]; }
modules = { machineName, nodes, check }:
[
# Get the configuration of this machine from each network
# expression, attaching _file attributes so the NixOS module
# system can give sensible error messages.
{ imports = [ network.${machineName} ]; }

({ config, lib, options, ... }: {
key = "deploy-stuff";
imports = [ ./options.nix ];
# Make documentation builds deterministic, even with our
# tempdir module imports.
documentation.nixos.extraModuleSources = [ ../. ];
# Provide a default hostname and deployment target equal
# to the attribute name of the machine in the model.
networking.hostName = lib.mkDefault machineName;
deployment.targetHost = lib.mkDefault machineName;
({ lib, ... }: {
key = "deploy-stuff";
imports = [ ./options.nix ];
# Make documentation builds deterministic, even with our
# tempdir module imports.
documentation.nixos.extraModuleSources = [ ../. ];
# Provide a default hostname and deployment target equal
# to the attribute name of the machine in the model.
networking.hostName = lib.mkDefault machineName;
deployment.targetHost = lib.mkDefault machineName;

# If network.pkgs is set, mkDefault nixpkgs.pkgs
nixpkgs.pkgs = lib.mkIf (nwPkgs != {}) (lib.mkDefault nwPkgs);
# If network.pkgs is set, mkDefault nixpkgs.pkgs
nixpkgs.pkgs = lib.mkIf (nwPkgs != { }) (lib.mkDefault nwPkgs);

# Avoid the deprecated evalConfig arguments by
# setting them here instead.
_module = {
args = {
name = machineName;
inherit nodes;
# Avoid the deprecated evalConfig arguments by
# setting them here instead.
_module = {
args = {
name = machineName;
inherit nodes;
};
inherit check;
};
inherit check;
};
})
] ++ optional (network ? _file) { inherit (network) _file; };
})
] ++ optional (network ? _file) { inherit (network) _file; };

machineNames = attrNames (removeAttrs network [ "network" "defaults" "resources" "require" "_file" ]);
machineNames = attrNames (removeAttrs network [
"network"
"defaults"
"resources"
"require"
"_file"
]);

in rec {
# Unchecked configuration of all machines.
# Using unchecked config evaluation allows each machine to access other machines
# configuration without recursing as full evaluation is prevented
uncheckedNodes =
listToAttrs (map (machineName:
{ name = machineName;
value = import evalConfig {
# Force decide system in module system
system = null;
modules = modules {
inherit machineName;
check = false;
nodes = uncheckedNodes;
};
};
}
) machineNames);
uncheckedNodes = listToAttrs (map (machineName: {
name = machineName;
value = import evalConfig {
# Force decide system in module system
system = null;
modules = modules {
inherit machineName;
check = false;
nodes = uncheckedNodes;
};
};
}) machineNames);

# Compute the definitions of the machines.
nodes =
listToAttrs (map (machineName:
{ name = machineName;
value = import evalConfig {
# Force decide system in module system
system = null;
modules = modules {
inherit machineName;
check = true;
nodes = uncheckedNodes;
};
};
}
) machineNames);
nodes = listToAttrs (map (machineName: {
name = machineName;
value = import evalConfig {
# Force decide system in module system
system = null;
modules = modules {
inherit machineName;
check = true;
nodes = uncheckedNodes;
};
};
}) machineNames);

deploymentInfoModule = {
deployment = {
Expand All @@ -89,30 +94,33 @@ in rec {
};

# Phase 1: evaluate only the deployment attributes.
info =
let
network' = network;
nodes' = nodes;
in rec {
info = let network' = network;
in rec {

machines =
flip mapAttrs nodes (n: v': let v = scrubOptionValue v'; in
{ inherit (v.config.deployment) targetHost targetPort targetUser secrets healthChecks buildOnly substituteOnDestination tags;
name = n;
nixosRelease = v.config.system.nixos.release or (removeSuffix v.config.system.nixos.version.suffix v.config.system.nixos.version);
nixConfig = mapAttrs
(n: v: if builtins.isString v then v else throw "nix option '${n}' must have a string typed value")
(network'.network.nixConfig or {});
}
);
machines = flip mapAttrs nodes (n: v':
let v = scrubOptionValue v';
in {
inherit (v.config.deployment)
targetHost targetPort targetUser secrets healthChecks buildOnly
substituteOnDestination tags;
name = n;
nixosRelease = v.config.system.nixos.release or (removeSuffix
v.config.system.nixos.version.suffix v.config.system.nixos.version);
nixConfig = mapAttrs (n: v:
if builtins.isString v then
v
else
throw "nix option '${n}' must have a string typed value")
(network'.network.nixConfig or { });
});

machineList = (map (key: getAttr key machines) (attrNames machines));
network = network'.network or {};
machineList = map (key: getAttr key machines) (attrNames machines);
network = network'.network or { };
deployment = {
hosts = machineList;
meta = {
description = network.description or "";
ordering = network.ordering or {};
ordering = network.ordering or { };
};
};

Expand All @@ -123,24 +131,21 @@ in rec {
machines = { argsFile, buildTargets ? null }:
let
fileArgs = builtins.fromJSON (builtins.readFile argsFile);
nodes' = filterAttrs (n: v: elem n fileArgs.Names) nodes; in
runCommand "morph"
{ preferLocalBuild = true; }
(if buildTargets == null
then ''
mkdir -p $out
${toString (mapAttrsToList (nodeName: nodeDef: ''
ln -s ${nodeDef.config.system.build.toplevel} $out/${nodeName}
'') nodes')}
''
else ''
mkdir -p $out
${toString (mapAttrsToList (nodeName: nodeDef: ''
mkdir -p $out/${nodeName}
${toString (mapAttrsToList (buildName: buildFn: ''
ln -s ${buildFn nodeDef} $out/${nodeName}/${buildName}
'') buildTargets)}
'') nodes')}
'');
nodes' = filterAttrs (n: _v: elem n fileArgs.Names) nodes;
in runCommand "morph" { preferLocalBuild = true; }
(if buildTargets == null then ''
mkdir -p $out
${toString (mapAttrsToList (nodeName: nodeDef: ''
ln -s ${nodeDef.config.system.build.toplevel} $out/${nodeName}
'') nodes')}
'' else ''
mkdir -p $out
${toString (mapAttrsToList (nodeName: nodeDef: ''
mkdir -p $out/${nodeName}
${toString (mapAttrsToList (buildName: buildFn: ''
ln -s ${buildFn nodeDef} $out/${nodeName}/${buildName}
'') buildTargets)}
'') nodes')}
'');

}
Loading
Loading