# Management of static files in /etc. { config, pkgs, ... }: with pkgs.lib; let etc' = filter (f: f.enable) (attrValues config.environment.etc); etc = pkgs.stdenv.mkDerivation { name = "etc"; builder = ./make-etc.sh; preferLocalBuild = true; /* !!! Use toXML. */ sources = map (x: x.source) etc'; targets = map (x: x.target) etc'; modes = map (x: x.mode) etc'; }; in { ###### interface options = { environment.etc = mkOption { type = types.loaOf types.optionSet; default = {}; example = { hosts = { source = "/nix/store/.../etc/dir/file.conf.example"; mode = "0440"; }; "default/useradd".text = "GROUP=100 ..."; }; description = '' Set of files that have to be linked in /etc. ''; options = singleton ({ name, config, ... }: { options = { enable = mkOption { type = types.bool; default = true; description = '' Whether this /etc file should be generated. This option allows specific /etc files to be disabled. ''; }; target = mkOption { description = '' Name of symlink (relative to /etc). Defaults to the attribute name. ''; }; text = mkOption { default = null; type = types.nullOr types.string; description = "Text of the file."; }; source = mkOption { types = types.path; description = "Path of the source file."; }; mode = mkOption { default = "symlink"; example = "0600"; description = '' If set to something else than symlink, the file is copied instead of symlinked, with the given file mode. ''; }; }; config = { target = mkDefault name; source = mkIf (config.text != null) (mkDefault (pkgs.writeText "etc-file" config.text)); }; }); }; }; ###### implementation config = { system.build.etc = etc; system.activationScripts.etc = stringAfter [ "stdio" ] '' # Set up the statically computed bits of /etc. echo "setting up /etc..." ${pkgs.perl}/bin/perl ${./setup-etc.pl} ${etc}/etc ''; }; }