Implement files under /etc
This commit is contained in:
parent
8b3bba30af
commit
b3c7f71456
10 changed files with 494 additions and 242 deletions
77
nix/lib.nix
77
nix/lib.nix
|
|
@ -12,10 +12,19 @@ in
|
|||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
|
||||
nixosConfig = lib.nixosSystem {
|
||||
inherit system modules;
|
||||
nixosConfig = (lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [ ./modules/system-manager.nix ] ++ modules;
|
||||
specialArgs = { };
|
||||
};
|
||||
}).config;
|
||||
|
||||
returnIfNoAssertions = drv:
|
||||
let
|
||||
failedAssertions = map (x: x.message) (lib.filter (x: !x.assertion) nixosConfig.assertions);
|
||||
in
|
||||
if failedAssertions != [ ]
|
||||
then throw "\nFailed assertions:\n${lib.concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}"
|
||||
else lib.showWarnings nixosConfig.warnings drv;
|
||||
|
||||
services =
|
||||
lib.listToAttrs
|
||||
|
|
@ -24,21 +33,69 @@ in
|
|||
let
|
||||
serviceName = "${name}.service";
|
||||
in
|
||||
lib.nameValuePair serviceName { storePath = ''${nixosConfig.config.systemd.units."${serviceName}".unit}/${serviceName}''; })
|
||||
nixosConfig.config.system-manager.services);
|
||||
lib.nameValuePair serviceName {
|
||||
storePath =
|
||||
''${nixosConfig.systemd.units."${serviceName}".unit}/${serviceName}'';
|
||||
})
|
||||
nixosConfig.system-manager.services);
|
||||
|
||||
servicesPath = pkgs.writeTextFile {
|
||||
name = "services";
|
||||
destination = "/services.json";
|
||||
text = lib.generators.toJSON { } services;
|
||||
};
|
||||
|
||||
# TODO: handle globbing
|
||||
etcFiles =
|
||||
let
|
||||
isManaged = name: lib.elem name nixosConfig.system-manager.etcFiles;
|
||||
|
||||
addToStore = name: file: pkgs.runCommandLocal "${name}-etc-link" { } ''
|
||||
mkdir -p "$out/etc/$(dirname "${file.target}")"
|
||||
ln -s "${file.source}" "$out/etc/${file.target}"
|
||||
|
||||
if [ "${file.mode}" != symlink ]; then
|
||||
echo "${file.mode}" > "$out/etc/${file.target}.mode"
|
||||
echo "${file.user}" > "$out/etc/${file.target}.uid"
|
||||
echo "${file.group}" > "$out/etc/${file.target}.gid"
|
||||
fi
|
||||
'';
|
||||
|
||||
filteredEntries = lib.filterAttrs
|
||||
(name: etcFile: etcFile.enable && isManaged name)
|
||||
nixosConfig.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 {
|
||||
name = "etcFiles";
|
||||
destination = "/etcFiles.json";
|
||||
text = lib.generators.toJSON { } etcFiles;
|
||||
};
|
||||
|
||||
# TODO: remove --ephemeral
|
||||
activationScript = pkgs.writeShellScript "activate" ''
|
||||
${system-manager}/bin/system-manager activate \
|
||||
--store-path "$(realpath $(dirname ''${0}))"
|
||||
--store-path "$(realpath $(dirname ''${0}))" \
|
||||
"$@"
|
||||
'';
|
||||
in
|
||||
pkgs.linkFarmFromDrvs "system-manager" [
|
||||
servicesPath
|
||||
activationScript
|
||||
];
|
||||
returnIfNoAssertions (
|
||||
pkgs.linkFarmFromDrvs "system-manager" [
|
||||
servicesPath
|
||||
etcPath
|
||||
activationScript
|
||||
]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
{ lib
|
||||
, pkgs
|
||||
, config
|
||||
, ...
|
||||
}:
|
||||
let
|
||||
|
|
@ -30,16 +31,42 @@ let
|
|||
'';
|
||||
})
|
||||
);
|
||||
in
|
||||
{
|
||||
options = {
|
||||
system-manager.services = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
|
||||
etcFiles = {
|
||||
foo = {
|
||||
text = ''
|
||||
This is just a test!
|
||||
'';
|
||||
target = "foo_test";
|
||||
};
|
||||
|
||||
"baz/bar/foo2" = {
|
||||
text = ''
|
||||
Another test!
|
||||
'';
|
||||
mode = "symlink";
|
||||
};
|
||||
|
||||
foo3 = {
|
||||
text = "boo!";
|
||||
mode = "0700";
|
||||
user = "root";
|
||||
group = "root";
|
||||
};
|
||||
|
||||
out-of-store = {
|
||||
source = "/run/systemd/system/";
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
config = {
|
||||
system-manager.services = lib.attrNames services;
|
||||
system.stateVersion = lib.trivial.release;
|
||||
system-manager = {
|
||||
etcFiles = lib.attrNames etcFiles;
|
||||
services = lib.attrNames services;
|
||||
};
|
||||
environment.etc = etcFiles;
|
||||
systemd = { inherit services; };
|
||||
};
|
||||
}
|
||||
|
|
|
|||
34
nix/modules/system-manager.nix
Normal file
34
nix/modules/system-manager.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
{ lib
|
||||
, pkgs
|
||||
, config
|
||||
, ...
|
||||
}:
|
||||
{
|
||||
options.system-manager = {
|
||||
services = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
};
|
||||
|
||||
etcFiles = lib.mkOption {
|
||||
type = with lib.types; listOf str;
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
# Avoid some standard NixOS assertions
|
||||
boot = {
|
||||
loader.grub.enable = false;
|
||||
initrd.enable = false;
|
||||
};
|
||||
|
||||
assertions = lib.flip map config.system-manager.etcFiles (entry:
|
||||
{
|
||||
assertion = lib.hasAttr entry config.environment.etc;
|
||||
message = lib.concatStringsSep " " [
|
||||
"The entry ${entry} that was passed to system-manager.etcFiles"
|
||||
"is not present in environment.etc"
|
||||
];
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue