Expose the config in the passthru and move values into the config.
This commit is contained in:
parent
1454525760
commit
46ecaad91e
2 changed files with 158 additions and 121 deletions
144
nix/lib.nix
144
nix/lib.nix
|
|
@ -26,6 +26,7 @@ in
|
||||||
utils = import "${nixos}/lib/utils.nix" {
|
utils = import "${nixos}/lib/utils.nix" {
|
||||||
inherit lib config pkgs;
|
inherit lib config pkgs;
|
||||||
};
|
};
|
||||||
|
inherit (self.packages.${config.nixpkgs.hostPlatform}) system-manager;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -40,7 +41,6 @@ in
|
||||||
# Get the system as it was defined in the modules.
|
# Get the system as it was defined in the modules.
|
||||||
system = config.nixpkgs.hostPlatform;
|
system = config.nixpkgs.hostPlatform;
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
inherit (self.packages.${system}) system-manager;
|
|
||||||
|
|
||||||
returnIfNoAssertions = drv:
|
returnIfNoAssertions = drv:
|
||||||
let
|
let
|
||||||
|
|
@ -50,143 +50,45 @@ in
|
||||||
then throw "\nFailed assertions:\n${lib.concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
|
then throw "\nFailed assertions:\n${lib.concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
|
||||||
else lib.showWarnings config.warnings drv;
|
else lib.showWarnings config.warnings drv;
|
||||||
|
|
||||||
services =
|
|
||||||
lib.mapAttrs'
|
|
||||||
(unitName: unit:
|
|
||||||
lib.nameValuePair unitName {
|
|
||||||
storePath =
|
|
||||||
''${unit.unit}/${unitName}'';
|
|
||||||
})
|
|
||||||
(lib.filterAttrs (_: unit: unit.enable)
|
|
||||||
config.systemd.units);
|
|
||||||
|
|
||||||
servicesPath = pkgs.writeTextFile {
|
servicesPath = pkgs.writeTextFile {
|
||||||
name = "services";
|
name = "services";
|
||||||
destination = "/services.json";
|
destination = "/services.json";
|
||||||
text = lib.generators.toJSON { } services;
|
text = lib.generators.toJSON { } config.build.services;
|
||||||
};
|
};
|
||||||
|
|
||||||
# TODO: handle globbing
|
|
||||||
etcFiles =
|
|
||||||
let
|
|
||||||
addToStore = name: file: pkgs.runCommandLocal "${name}-etc-link" { } ''
|
|
||||||
mkdir -p "$out/$(dirname "${file.target}")"
|
|
||||||
ln -s "${file.source}" "$out/${file.target}"
|
|
||||||
|
|
||||||
if [ "${file.mode}" != symlink ]; then
|
|
||||||
echo "${file.mode}" > "$out/${file.target}.mode"
|
|
||||||
echo "${file.user}" > "$out/${file.target}.uid"
|
|
||||||
echo "${file.group}" > "$out/${file.target}.gid"
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
filteredEntries = lib.filterAttrs
|
|
||||||
(_name: etcFile: etcFile.enable)
|
|
||||||
config.environment.etc;
|
|
||||||
|
|
||||||
srcDrvs = lib.mapAttrs addToStore filteredEntries;
|
|
||||||
|
|
||||||
entries = lib.mapAttrs
|
|
||||||
(name: file: file // { source = "${srcDrvs.${name}}"; })
|
|
||||||
filteredEntries;
|
|
||||||
|
|
||||||
staticEnv = pkgs.buildEnv {
|
|
||||||
name = "etc-static-env";
|
|
||||||
paths = lib.attrValues srcDrvs;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{ inherit entries staticEnv; };
|
|
||||||
|
|
||||||
etcPath = pkgs.writeTextFile {
|
etcPath = pkgs.writeTextFile {
|
||||||
name = "etcFiles";
|
name = "etcFiles";
|
||||||
destination = "/etcFiles.json";
|
destination = "/etcFiles.json";
|
||||||
text = lib.generators.toJSON { } etcFiles;
|
text = lib.generators.toJSON { } { inherit (config.build.etc) entries staticEnv; };
|
||||||
};
|
};
|
||||||
|
|
||||||
registerProfileScript = pkgs.writeShellScript "register-profile" ''
|
|
||||||
${system-manager}/bin/system-manager register \
|
|
||||||
--store-path "$(dirname $(realpath $(dirname ''${0})))" \
|
|
||||||
"$@"
|
|
||||||
'';
|
|
||||||
|
|
||||||
activationScript = pkgs.writeShellScript "activate" ''
|
|
||||||
${system-manager}/bin/system-manager activate \
|
|
||||||
--store-path "$(dirname $(realpath $(dirname ''${0})))" \
|
|
||||||
"$@"
|
|
||||||
'';
|
|
||||||
|
|
||||||
prepopulateScript = pkgs.writeShellScript "prepopulate" ''
|
|
||||||
${system-manager}/bin/system-manager pre-populate \
|
|
||||||
--store-path "$(dirname $(realpath $(dirname ''${0})))" \
|
|
||||||
"$@"
|
|
||||||
'';
|
|
||||||
|
|
||||||
deactivationScript = pkgs.writeShellScript "deactivate" ''
|
|
||||||
${system-manager}/bin/system-manager deactivate "$@"
|
|
||||||
'';
|
|
||||||
|
|
||||||
preActivationAssertionScript =
|
|
||||||
let
|
|
||||||
mkAssertion = { name, script, ... }: ''
|
|
||||||
# ${name}
|
|
||||||
|
|
||||||
echo -e "Evaluating pre-activation assertion ${name}...\n"
|
|
||||||
(
|
|
||||||
set +e
|
|
||||||
${script}
|
|
||||||
)
|
|
||||||
assertion_result=$?
|
|
||||||
|
|
||||||
if [ $assertion_result -ne 0 ]; then
|
|
||||||
failed_assertions+=${name}
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
mkAssertions = assertions:
|
|
||||||
lib.concatStringsSep "\n" (
|
|
||||||
lib.mapAttrsToList (name: mkAssertion) (
|
|
||||||
lib.filterAttrs (name: cfg: cfg.enable)
|
|
||||||
assertions
|
|
||||||
)
|
|
||||||
);
|
|
||||||
in
|
|
||||||
pkgs.writeShellScript "preActivationAssertions" ''
|
|
||||||
set -ou pipefail
|
|
||||||
|
|
||||||
declare -a failed_assertions=()
|
|
||||||
|
|
||||||
${mkAssertions config.system-manager.preActivationAssertions}
|
|
||||||
|
|
||||||
if [ ''${#failed_assertions[@]} -ne 0 ]; then
|
|
||||||
for failed_assertion in ''${failed_assertions[@]}; do
|
|
||||||
echo "Pre-activation assertion $failed_assertion failed."
|
|
||||||
done
|
|
||||||
echo "See the output above for more details."
|
|
||||||
exit 1
|
|
||||||
else
|
|
||||||
echo "All pre-activation assertions succeeded."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
linkFarmNestedEntryFromDrv = dirs: drv: {
|
linkFarmNestedEntryFromDrv = dirs: drv: {
|
||||||
name = lib.concatStringsSep "/" (dirs ++ [ "${drv.name}" ]);
|
name = lib.concatStringsSep "/" (dirs ++ [ "${drv.name}" ]);
|
||||||
path = drv;
|
path = drv;
|
||||||
};
|
};
|
||||||
linkFarmEntryFromDrv = linkFarmNestedEntryFromDrv [ ];
|
linkFarmEntryFromDrv = linkFarmNestedEntryFromDrv [ ];
|
||||||
linkFarmBinEntryFromDrv = linkFarmNestedEntryFromDrv [ "bin" ];
|
linkFarmBinEntryFromDrv = linkFarmNestedEntryFromDrv [ "bin" ];
|
||||||
|
|
||||||
|
toplevel =
|
||||||
|
let
|
||||||
|
scripts = lib.mapAttrsToList
|
||||||
|
(_: script: linkFarmBinEntryFromDrv script)
|
||||||
|
config.build.scripts;
|
||||||
|
|
||||||
|
entries = [
|
||||||
|
(linkFarmEntryFromDrv servicesPath)
|
||||||
|
(linkFarmEntryFromDrv etcPath)
|
||||||
|
] ++ scripts;
|
||||||
|
|
||||||
|
addPassthru = drv: drv.overrideAttrs (prevAttrs: {
|
||||||
|
passthru = (prevAttrs.passthru or { }) // {
|
||||||
|
inherit config;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
in
|
||||||
|
addPassthru (pkgs.linkFarm "system-manager" entries);
|
||||||
in
|
in
|
||||||
returnIfNoAssertions (
|
returnIfNoAssertions toplevel;
|
||||||
pkgs.linkFarm "system-manager" [
|
|
||||||
(linkFarmEntryFromDrv servicesPath)
|
|
||||||
(linkFarmEntryFromDrv etcPath)
|
|
||||||
(linkFarmBinEntryFromDrv activationScript)
|
|
||||||
(linkFarmBinEntryFromDrv prepopulateScript)
|
|
||||||
(linkFarmBinEntryFromDrv deactivationScript)
|
|
||||||
(linkFarmBinEntryFromDrv registerProfileScript)
|
|
||||||
(linkFarmBinEntryFromDrv preActivationAssertionScript)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
# TODO: put these in an external JSON file that we can automatically update
|
# TODO: put these in an external JSON file that we can automatically update
|
||||||
images.ubuntu = {
|
images.ubuntu = {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
{ lib
|
{ lib
|
||||||
, config
|
, config
|
||||||
|
, pkgs
|
||||||
|
, system-manager
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
|
@ -109,6 +111,28 @@
|
||||||
default = { };
|
default = { };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
build = {
|
||||||
|
scripts = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf lib.types.package;
|
||||||
|
};
|
||||||
|
|
||||||
|
etc = {
|
||||||
|
staticEnv = lib.mkOption {
|
||||||
|
type = lib.types.package;
|
||||||
|
};
|
||||||
|
|
||||||
|
entries = lib.mkOption {
|
||||||
|
# TODO: better type
|
||||||
|
type = lib.types.attrsOf lib.types.raw;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services = lib.mkOption {
|
||||||
|
# TODO: better type
|
||||||
|
type = lib.types.attrsOf lib.types.raw;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
|
|
@ -132,5 +156,116 @@
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
build = {
|
||||||
|
scripts = {
|
||||||
|
registerProfileScript = pkgs.writeShellScript "register-profile" ''
|
||||||
|
${system-manager}/bin/system-manager register \
|
||||||
|
--store-path "$(dirname $(realpath $(dirname ''${0})))" \
|
||||||
|
"$@"
|
||||||
|
'';
|
||||||
|
|
||||||
|
activationScript = pkgs.writeShellScript "activate" ''
|
||||||
|
${system-manager}/bin/system-manager activate \
|
||||||
|
--store-path "$(dirname $(realpath $(dirname ''${0})))" \
|
||||||
|
"$@"
|
||||||
|
'';
|
||||||
|
|
||||||
|
prepopulateScript = pkgs.writeShellScript "prepopulate" ''
|
||||||
|
${system-manager}/bin/system-manager pre-populate \
|
||||||
|
--store-path "$(dirname $(realpath $(dirname ''${0})))" \
|
||||||
|
"$@"
|
||||||
|
'';
|
||||||
|
|
||||||
|
deactivationScript = pkgs.writeShellScript "deactivate" ''
|
||||||
|
${system-manager}/bin/system-manager deactivate "$@"
|
||||||
|
'';
|
||||||
|
|
||||||
|
preActivationAssertionScript =
|
||||||
|
let
|
||||||
|
mkAssertion = { name, script, ... }: ''
|
||||||
|
# ${name}
|
||||||
|
|
||||||
|
echo -e "Evaluating pre-activation assertion ${name}...\n"
|
||||||
|
(
|
||||||
|
set +e
|
||||||
|
${script}
|
||||||
|
)
|
||||||
|
assertion_result=$?
|
||||||
|
|
||||||
|
if [ $assertion_result -ne 0 ]; then
|
||||||
|
failed_assertions+=${name}
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
mkAssertions = assertions:
|
||||||
|
lib.concatStringsSep "\n" (
|
||||||
|
lib.mapAttrsToList (name: mkAssertion) (
|
||||||
|
lib.filterAttrs (name: cfg: cfg.enable)
|
||||||
|
assertions
|
||||||
|
)
|
||||||
|
);
|
||||||
|
in
|
||||||
|
pkgs.writeShellScript "preActivationAssertions" ''
|
||||||
|
set -ou pipefail
|
||||||
|
|
||||||
|
declare -a failed_assertions=()
|
||||||
|
|
||||||
|
${mkAssertions config.system-manager.preActivationAssertions}
|
||||||
|
|
||||||
|
if [ ''${#failed_assertions[@]} -ne 0 ]; then
|
||||||
|
for failed_assertion in ''${failed_assertions[@]}; do
|
||||||
|
echo "Pre-activation assertion $failed_assertion failed."
|
||||||
|
done
|
||||||
|
echo "See the output above for more details."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "All pre-activation assertions succeeded."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: handle globbing
|
||||||
|
etc =
|
||||||
|
let
|
||||||
|
addToStore = name: file: pkgs.runCommandLocal "${name}-etc-link" { } ''
|
||||||
|
mkdir -p "$out/$(dirname "${file.target}")"
|
||||||
|
ln -s "${file.source}" "$out/${file.target}"
|
||||||
|
|
||||||
|
if [ "${file.mode}" != symlink ]; then
|
||||||
|
echo "${file.mode}" > "$out/${file.target}.mode"
|
||||||
|
echo "${file.user}" > "$out/${file.target}.uid"
|
||||||
|
echo "${file.group}" > "$out/${file.target}.gid"
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
|
||||||
|
filteredEntries = lib.filterAttrs
|
||||||
|
(_name: etcFile: etcFile.enable)
|
||||||
|
config.environment.etc;
|
||||||
|
|
||||||
|
srcDrvs = lib.mapAttrs addToStore filteredEntries;
|
||||||
|
|
||||||
|
entries = lib.mapAttrs
|
||||||
|
(name: file: file // { source = "${srcDrvs.${name}}"; })
|
||||||
|
filteredEntries;
|
||||||
|
|
||||||
|
staticEnv = pkgs.buildEnv {
|
||||||
|
name = "etc-static-env";
|
||||||
|
paths = lib.attrValues srcDrvs;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{ inherit entries staticEnv; };
|
||||||
|
|
||||||
|
services =
|
||||||
|
lib.mapAttrs'
|
||||||
|
(unitName: unit:
|
||||||
|
lib.nameValuePair unitName {
|
||||||
|
storePath =
|
||||||
|
''${unit.unit}/${unitName}'';
|
||||||
|
})
|
||||||
|
(lib.filterAttrs (_: unit: unit.enable)
|
||||||
|
config.systemd.units);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue