1# Management of static files in /etc.
2
3{ config, lib, pkgs, ... }:
4
5with lib;
6
7let
8
9 etc' = filter (f: f.enable) (attrValues config.environment.etc);
10
11 etc = pkgs.stdenv.mkDerivation {
12 name = "etc";
13
14 builder = ./make-etc.sh;
15
16 preferLocalBuild = true;
17 allowSubstitutes = false;
18
19 /* !!! Use toXML. */
20 sources = map (x: x.source) etc';
21 targets = map (x: x.target) etc';
22 modes = map (x: x.mode) etc';
23 uids = map (x: x.uid) etc';
24 gids = map (x: x.gid) etc';
25 };
26
27in
28
29{
30
31 ###### interface
32
33 options = {
34
35 environment.etc = mkOption {
36 type = types.loaOf types.optionSet;
37 default = {};
38 example = literalExample ''
39 { example-configuration-file =
40 { source = "/nix/store/.../etc/dir/file.conf.example";
41 mode = "0440";
42 };
43 "default/useradd".text = "GROUP=100 ...";
44 }
45 '';
46 description = ''
47 Set of files that have to be linked in <filename>/etc</filename>.
48 '';
49
50 options = singleton ({ name, config, ... }:
51 { options = {
52
53 enable = mkOption {
54 type = types.bool;
55 default = true;
56 description = ''
57 Whether this /etc file should be generated. This
58 option allows specific /etc files to be disabled.
59 '';
60 };
61
62 target = mkOption {
63 type = types.str;
64 description = ''
65 Name of symlink (relative to
66 <filename>/etc</filename>). Defaults to the attribute
67 name.
68 '';
69 };
70
71 text = mkOption {
72 default = null;
73 type = types.nullOr types.lines;
74 description = "Text of the file.";
75 };
76
77 source = mkOption {
78 type = types.path;
79 description = "Path of the source file.";
80 };
81
82 mode = mkOption {
83 type = types.str;
84 default = "symlink";
85 example = "0600";
86 description = ''
87 If set to something else than <literal>symlink</literal>,
88 the file is copied instead of symlinked, with the given
89 file mode.
90 '';
91 };
92
93 uid = mkOption {
94 default = 0;
95 type = types.int;
96 description = ''
97 UID of created file. Only takes affect when the file is
98 copied (that is, the mode is not 'symlink').
99 '';
100 };
101
102 gid = mkOption {
103 default = 0;
104 type = types.int;
105 description = ''
106 GID of created file. Only takes affect when the file is
107 copied (that is, the mode is not 'symlink').
108 '';
109 };
110
111 };
112
113 config = {
114 target = mkDefault name;
115 source = mkIf (config.text != null) (
116 let name' = "etc-" + baseNameOf name;
117 in mkDefault (pkgs.writeText name' config.text));
118 };
119
120 });
121
122 };
123
124 };
125
126
127 ###### implementation
128
129 config = {
130
131 system.build.etc = etc;
132
133 system.activationScripts.etc = stringAfter [ "stdio" ]
134 ''
135 # Set up the statically computed bits of /etc.
136 echo "setting up /etc..."
137 ${pkgs.perl}/bin/perl -I${pkgs.perlPackages.FileSlurp}/lib/perl5/site_perl ${./setup-etc.pl} ${etc}/etc
138 '';
139
140 };
141
142}