-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathoptions.nix
More file actions
271 lines (246 loc) · 8.7 KB
/
Copy pathoptions.nix
File metadata and controls
271 lines (246 loc) · 8.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
{ lib, ... }:
let
specialFSTypes = [
"proc"
"sysfs"
"tmpfs"
"ramfs"
"devtmpfs"
"devpts"
];
# Check whenever fileSystem is needed for boot. NOTE: Make sure
# pathsNeededForBoot is closed under the parent relationship, i.e. if /a/b/c
# is in the list, put /a and /a/b in as well.
pathsNeededForBoot = [
"/"
"/etc"
"/nix"
"/nix/store"
"/usr"
"/var"
"/var/lib"
"/var/log"
];
addCheckDesc =
desc: elemType: check:
lib.types.addCheck elemType check
// {
description = "${elemType.description} (with check: ${desc})";
};
nonEmptyWithoutTrailingSlash = addCheckDesc "non-empty without trailing slash" lib.types.str (
s: (builtins.match "[ \t\n]*" s) == null && (builtins.match ".+/" s) == null
);
fileSystemOpts =
{ name, config, ... }:
{
options = {
mountPoint = lib.mkOption {
example = "/mnt/usb";
type = nonEmptyWithoutTrailingSlash;
description = "Location of the mounted file system.";
};
device = lib.mkOption {
default = null;
example = "/dev/sda";
type = with lib.types; nullOr nonEmptyStr;
description = "Location of the device.";
};
fsType = lib.mkOption {
default = "auto";
example = "ext3";
type = lib.types.nonEmptyStr;
description = "Type of the file system.";
};
label = lib.mkOption {
default = null;
example = "root-partition";
type = with lib.types; nullOr nonEmptyStr;
description = "Label of the device (if any).";
};
noCheck = lib.mkOption {
default = false;
type = lib.types.bool;
description = "Disable running fsck on this filesystem.";
};
options = lib.mkOption {
default = [ "defaults" ];
example = [ "data=journal" ];
description = "Options used to mount the file system.";
type = with lib.types; nonEmptyListOf nonEmptyStr;
};
depends = lib.mkOption {
default = [ ];
example = [ "/persist" ];
type = lib.types.listOf nonEmptyWithoutTrailingSlash;
description = ''
List of paths that should be mounted before this one. This filesystem's
{option}`device` and {option}`mountPoint` are always
checked and do not need to be included explicitly. If a path is added
to this list, any other filesystem whose mount point is a parent of
the path will be mounted before this filesystem. The paths do not need
to actually be the {option}`mountPoint` of some other filesystem.
'';
};
neededForBoot = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether this filesystem is needed for boot. If set, the filesystem
will be mounted in the initial ramdisk.
'';
};
};
config = {
mountPoint = lib.mkDefault name;
device = lib.mkIf (lib.elem config.fsType specialFSTypes) (lib.mkDefault config.fsType);
neededForBoot = lib.mkIf (lib.elem config.mountPoint pathsNeededForBoot) (lib.mkForce true);
};
};
swapDeviceOpts =
{ ... }:
{
options = {
device = lib.mkOption {
example = "/dev/sda2";
type = lib.types.nonEmptyStr;
description = "Path of the swap device or file.";
};
label = lib.mkOption {
default = null;
example = "swap";
type = with lib.types; nullOr nonEmptyStr;
description = "Label of the swap device (if any).";
};
priority = lib.mkOption {
default = null;
example = 100;
type = with lib.types; nullOr int;
description = ''
Specify the priority of the swap device. Higher numbers
indicate higher priority. `null` lets the kernel choose
a priority, starting at -1 and going down.
'';
};
options = lib.mkOption {
default = [ "defaults" ];
example = [ "nofail" ];
type = with lib.types; nonEmptyListOf nonEmptyStr;
description = "Options used to set up the swap device.";
};
discardPolicy = lib.mkOption {
default = null;
example = "both";
type = with lib.types; nullOr (enum [ "once" "pages" "both" ]);
description = ''
Specify the discard policy for the swap device. If "once",
then the discard operation will be performed once, at swapon
invocation. If "pages", then the discard operation will be
performed on every freed page (this is "discard" semantics
in swap parlance, not TRIM). If "both", then both will be
enabled. If unset, then no discard policy is applied.
'';
};
randomEncryption = lib.mkOption {
default = { };
description = ''
Encrypt swap device with a random key. This way you won't have a
persistent swap device, the entire contents become unreadable
after every reboot. Mutually exclusive with {option}`label`,
since the underlying mapped device is regenerated on every boot
and is therefore not activated through `/etc/fstab` like a
regular swap device, but through a dedicated `finit` task.
'';
type = lib.types.submodule {
options = {
enable = lib.mkOption {
default = false;
type = lib.types.bool;
description = "Encrypt swap device with a random key.";
};
cipher = lib.mkOption {
default = "aes-xts-plain64";
type = lib.types.nonEmptyStr;
description = ''
Specify the cipher to use, see {command}`cryptsetup
benchmark` for a list of options.
'';
};
keySize = lib.mkOption {
default = 256;
type = lib.types.ints.positive;
description = "Specify the size of the randomly generated key, in bits.";
};
sectorSize = lib.mkOption {
default = 0;
type = lib.types.ints.unsigned;
description = ''
Specify the sector size in bytes, or `0` to let
{command}`cryptsetup` pick the default.
'';
};
source = lib.mkOption {
default = "/dev/urandom";
type = lib.types.nonEmptyStr;
description = ''
Source of randomness used to generate the swap
encryption key on every boot.
'';
};
allowDiscards = lib.mkOption {
default = false;
type = lib.types.bool;
description = ''
Whether to allow TRIM requests to the underlying device.
This option has security implications, see the
upstream NixOS manual section on swap encryption.
'';
};
};
};
};
};
};
in
{
options = {
fileSystems = lib.mkOption {
type = with lib.types; attrsOf (submodule fileSystemOpts);
default = { };
example = lib.literalExpression ''
{
"/".device = "/dev/hda1";
"/data" = {
device = "/dev/hda2";
fsType = "ext3";
options = [ "data=journal" ];
};
"/bigdisk".label = "bigdisk";
}
'';
description = ''
The file systems to be mounted. It must include an entry for
the root directory (`mountPoint = "/"`). Each
entry in the list is an attribute set with the following fields:
`mountPoint`, `device`,
`fsType` (a file system type recognised by
{command}`mount`; defaults to
`"auto"`), and `options`
(the mount options passed to {command}`mount` using the
{option}`-o` flag; defaults to `[ "defaults" ]`).
Instead of specifying `device`, you can also
specify a volume label (`label`) for file
systems that support it, such as ext2/ext3 (see {command}`mke2fs -L`).
'';
};
swapDevices = lib.mkOption {
type = with lib.types; listOf (submodule swapDeviceOpts);
default = [ ];
example = [
{ device = "/dev/sda2"; }
];
description = ''
The swap devices and swap files. These are activated at boot time.
'';
};
};
}