Skip to content

Commit 0fe5300

Browse files
committed
Merge branch 'master' into staging-next
2 parents 1181aa7 + 826934d commit 0fe5300

152 files changed

Lines changed: 2941 additions & 1772 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
# This also holds true for GitHub teams. Since almost none of our teams have write
1212
# permissions, you need to list all members of the team with commit access individually.
1313

14-
# This file
15-
/.github/CODEOWNERS @edolstra
16-
1714
# GitHub actions
1815
/.github/workflows @NixOS/Security @Mic92 @zowoq
1916
/.github/workflows/merge-staging @FRidh
@@ -22,12 +19,12 @@
2219
/.editorconfig @Mic92 @zowoq
2320

2421
# Libraries
25-
/lib @edolstra @infinisil
22+
/lib @infinisil
2623
/lib/systems @alyssais @ericson2314 @amjoseph-nixpkgs
27-
/lib/generators.nix @infinisil @edolstra @Profpatsch
28-
/lib/cli.nix @infinisil @edolstra @Profpatsch
29-
/lib/debug.nix @infinisil @edolstra @Profpatsch
30-
/lib/asserts.nix @infinisil @edolstra @Profpatsch
24+
/lib/generators.nix @infinisil @Profpatsch
25+
/lib/cli.nix @infinisil @Profpatsch
26+
/lib/debug.nix @infinisil @Profpatsch
27+
/lib/asserts.nix @infinisil @Profpatsch
3128
/lib/path.* @infinisil @fricklerhandwerk
3229
/lib/fileset @infinisil
3330
/doc/functions/fileset.section.md @infinisil

lib/fileset/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,21 @@ Arguments:
238238
And it would be unclear how the library should behave if the one file wouldn't be added to the store:
239239
`toSource { root = ./file.nix; fileset = <empty>; }` has no reasonable result because returing an empty store path wouldn't match the file type, and there's no way to have an empty file store path, whatever that would mean.
240240

241+
### `fileFilter` takes a path
242+
243+
The `fileFilter` function takes a path, and not a file set, as its second argument.
244+
245+
- (-) Makes it harder to compose functions, since the file set type, the return value, can't be passed to the function itself like `fileFilter predicate fileset`
246+
- (+) It's still possible to use `intersection` to filter on file sets: `intersection fileset (fileFilter predicate ./.)`
247+
- (-) This does need an extra `./.` argument that's not obvious
248+
- (+) This could always be `/.` or the project directory, `intersection` will make it lazy
249+
- (+) In the future this will allow `fileFilter` to support a predicate property like `subpath` and/or `components` in a reproducible way.
250+
This wouldn't be possible if it took a file set, because file sets don't have a predictable absolute path.
251+
- (-) What about the base path?
252+
- (+) That can change depending on which files are included, so if it's used for `fileFilter`
253+
it would change the `subpath`/`components` value depending on which files are included.
254+
- (+) If necessary, this restriction can be relaxed later, the opposite wouldn't be possible
255+
241256
## To update in the future
242257

243258
Here's a list of places in the library that need to be updated in the future:

lib/fileset/default.nix

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ in {
366366
type :: String,
367367
...
368368
} -> Bool)
369-
-> FileSet
369+
-> Path
370370
-> FileSet
371371
372372
Example:
@@ -397,14 +397,24 @@ in {
397397
Other attributes may be added in the future.
398398
*/
399399
predicate:
400-
# The file set to filter based on the predicate function
401-
fileset:
400+
# The path whose files to filter
401+
path:
402402
if ! isFunction predicate then
403403
throw ''
404404
lib.fileset.fileFilter: First argument is of type ${typeOf predicate}, but it should be a function instead.''
405+
else if ! isPath path then
406+
if path._type or "" == "fileset" then
407+
throw ''
408+
lib.fileset.fileFilter: Second argument is a file set, but it should be a path instead.
409+
If you need to filter files in a file set, use `intersection fileset (fileFilter pred ./.)` instead.''
410+
else
411+
throw ''
412+
lib.fileset.fileFilter: Second argument is of type ${typeOf path}, but it should be a path instead.''
413+
else if ! pathExists path then
414+
throw ''
415+
lib.fileset.fileFilter: Second argument (${toString path}) is a path that does not exist.''
405416
else
406-
_fileFilter predicate
407-
(_coerce "lib.fileset.fileFilter: Second argument" fileset);
417+
_fileFilter predicate path;
408418

409419
/*
410420
The file set containing all files that are in both of two given file sets.

lib/fileset/internal.nix

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -786,9 +786,9 @@ rec {
786786
_differenceTree (path + "/${name}") lhsValue (rhs.${name} or null)
787787
) (_directoryEntries path lhs);
788788

789-
# Filters all files in a file set based on a predicate
790-
# Type: ({ name, type, ... } -> Bool) -> FileSet -> FileSet
791-
_fileFilter = predicate: fileset:
789+
# Filters all files in a path based on a predicate
790+
# Type: ({ name, type, ... } -> Bool) -> Path -> FileSet
791+
_fileFilter = predicate: root:
792792
let
793793
# Check the predicate for a single file
794794
# Type: String -> String -> filesetTree
@@ -807,19 +807,22 @@ rec {
807807

808808
# Check the predicate for all files in a directory
809809
# Type: Path -> filesetTree
810-
fromDir = path: tree:
811-
mapAttrs (name: subtree:
812-
if isAttrs subtree || subtree == "directory" then
813-
fromDir (path + "/${name}") subtree
814-
else if subtree == null then
815-
null
810+
fromDir = path:
811+
mapAttrs (name: type:
812+
if type == "directory" then
813+
fromDir (path + "/${name}")
816814
else
817-
fromFile name subtree
818-
) (_directoryEntries path tree);
815+
fromFile name type
816+
) (readDir path);
817+
818+
rootType = pathType root;
819819
in
820-
if fileset._internalIsEmptyWithoutBase then
821-
_emptyWithoutBase
820+
if rootType == "directory" then
821+
_create root (fromDir root)
822822
else
823-
_create fileset._internalBase
824-
(fromDir fileset._internalBase fileset._internalTree);
823+
# Single files are turned into a directory containing that file or nothing.
824+
_create (dirOf root) {
825+
${baseNameOf root} =
826+
fromFile (baseNameOf root) rootType;
827+
};
825828
}

lib/fileset/tests.sh

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -813,14 +813,15 @@ checkFileset 'difference ./. ./b'
813813
# The first argument needs to be a function
814814
expectFailure 'fileFilter null (abort "this is not needed")' 'lib.fileset.fileFilter: First argument is of type null, but it should be a function instead.'
815815

816-
# The second argument can be a file set or an existing path
817-
expectFailure 'fileFilter (file: abort "this is not needed") null' 'lib.fileset.fileFilter: Second argument is of type null, but it should be a file set or a path instead.'
816+
# The second argument needs to be an existing path
817+
expectFailure 'fileFilter (file: abort "this is not needed") _emptyWithoutBase' 'lib.fileset.fileFilter: Second argument is a file set, but it should be a path instead.
818+
\s*If you need to filter files in a file set, use `intersection fileset \(fileFilter pred \./\.\)` instead.'
819+
expectFailure 'fileFilter (file: abort "this is not needed") null' 'lib.fileset.fileFilter: Second argument is of type null, but it should be a path instead.'
818820
expectFailure 'fileFilter (file: abort "this is not needed") ./a' 'lib.fileset.fileFilter: Second argument \('"$work"'/a\) is a path that does not exist.'
819821

820822
# The predicate is not called when there's no files
821823
tree=()
822824
checkFileset 'fileFilter (file: abort "this is not needed") ./.'
823-
checkFileset 'fileFilter (file: abort "this is not needed") _emptyWithoutBase'
824825

825826
# The predicate must be able to handle extra attributes
826827
touch a
@@ -882,14 +883,6 @@ checkFileset 'union ./c/a (fileFilter (file: assert file.name != "a"; true) ./.)
882883
# but here we need to use ./c
883884
checkFileset 'union (fileFilter (file: assert file.name != "a"; true) ./.) ./c'
884885

885-
# Also lazy, the filter isn't called on a filtered out path
886-
tree=(
887-
[a]=1
888-
[b]=0
889-
[c]=0
890-
)
891-
checkFileset 'fileFilter (file: assert file.name != "c"; file.name == "a") (difference ./. ./c)'
892-
893886
# Make sure single files are filtered correctly
894887
tree=(
895888
[a]=1

maintainers/maintainer-list.nix

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3079,6 +3079,12 @@
30793079
githubId = 1689801;
30803080
name = "Mikhail Chekan";
30813081
};
3082+
chen = {
3083+
email = "i@cuichen.cc";
3084+
github = "cu1ch3n";
3085+
githubId = 80438676;
3086+
name = "Chen Cui";
3087+
};
30823088
ChengCat = {
30833089
email = "yu@cheng.cat";
30843090
github = "ChengCat";
@@ -11714,6 +11720,12 @@
1171411720
githubId = 34864484;
1171511721
name = "Mikael Fangel";
1171611722
};
11723+
mikecm = {
11724+
email = "mikecmcleod@gmail.com";
11725+
github = "MaxwellDupre";
11726+
githubId = 14096356;
11727+
name = "Michael McLeod";
11728+
};
1171711729
mikefaille = {
1171811730
email = "michael@faille.io";
1171911731
github = "mikefaille";
@@ -16513,6 +16525,11 @@
1651316525
githubId = 158321;
1651416526
name = "Stewart Mackenzie";
1651516527
};
16528+
skovati = {
16529+
github = "skovati";
16530+
githubId = 49844593;
16531+
name = "skovati";
16532+
};
1651616533
skykanin = {
1651716534
github = "skykanin";
1651816535
githubId = 3789764;

nixos/doc/manual/release-notes/rl-2311.section.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@
385385
386386
- The `prayer` package as well as `services.prayer` have been removed because it's been unmaintained for several years and the author's website has vanished.
387387
388+
- The `chrony` NixOS module now tracks the Real-Time Clock drift from the System Clock with `rtcfile` and automatically adjusts it with `rtcautotrim` when it exceeds the maximum error specified in `services.chrony.autotrimThreshold` (default 30 seconds). If you enabled `rtcsync` in `extraConfig`, you should remove RTC related options from `extraConfig`. If you do not want chrony configured to keep the RTC in check, you can set `services.chrony.enableRTCTrimming = false;`
389+
388390
## Other Notable Changes {#sec-release-23.11-notable-changes}
389391
390392
- A new option `system.switch.enable` was added. By default, this is option is

nixos/modules/services/networking/ntp/chrony.nix

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ let
99
stateDir = cfg.directory;
1010
driftFile = "${stateDir}/chrony.drift";
1111
keyFile = "${stateDir}/chrony.keys";
12+
rtcFile = "${stateDir}/chrony.rtc";
1213

1314
configFile = pkgs.writeText "chrony.conf" ''
1415
${concatMapStringsSep "\n" (server: "server " + server + " " + cfg.serverOption + optionalString (cfg.enableNTS) " nts") cfg.servers}
@@ -20,8 +21,10 @@ let
2021
2122
driftfile ${driftFile}
2223
keyfile ${keyFile}
24+
${optionalString (cfg.enableRTCTrimming) "rtcfile ${rtcFile}"}
2325
${optionalString (cfg.enableNTS) "ntsdumpdir ${stateDir}"}
2426
27+
${optionalString (cfg.enableRTCTrimming) "rtcautotrim ${builtins.toString cfg.autotrimThreshold}"}
2528
${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"}
2629
2730
${cfg.extraConfig}
@@ -85,6 +88,33 @@ in
8588
'';
8689
};
8790

91+
enableRTCTrimming = mkOption {
92+
type = types.bool;
93+
default = true;
94+
description = lib.mdDoc ''
95+
Enable tracking of the RTC offset to the system clock and automatic trimming.
96+
See also [](#opt-services.chrony.autotrimThreshold)
97+
98+
::: {.note}
99+
This is not compatible with the `rtcsync` directive, which naively syncs the RTC time every 11 minutes.
100+
101+
Tracking the RTC drift will allow more precise timekeeping,
102+
especially on intermittently running devices, where the RTC is very relevant.
103+
:::
104+
'';
105+
};
106+
107+
autotrimThreshold = mkOption {
108+
type = types.ints.positive;
109+
default = 30;
110+
example = 10;
111+
description = ''
112+
Maximum estimated error threshold for the `rtcautotrim` command.
113+
When reached, the RTC will be trimmed.
114+
Only used when [](#opt-services.chrony.enableRTCTrimming) is enabled.
115+
'';
116+
};
117+
88118
enableNTS = mkOption {
89119
type = types.bool;
90120
default = false;
@@ -141,7 +171,7 @@ in
141171
};
142172

143173
config = mkIf cfg.enable {
144-
meta.maintainers = with lib.maintainers; [ thoughtpolice ];
174+
meta.maintainers = with lib.maintainers; [ thoughtpolice vifino ];
145175

146176
environment.systemPackages = [ chronyPkg ];
147177

@@ -156,12 +186,19 @@ in
156186

157187
services.timesyncd.enable = mkForce false;
158188

189+
# If chrony controls and tracks the RTC, writing it externally causes clock error.
190+
systemd.services.save-hwclock = lib.mkIf cfg.enableRTCTrimming {
191+
enable = lib.mkForce false;
192+
};
193+
159194
systemd.services.systemd-timedated.environment = { SYSTEMD_TIMEDATED_NTP_SERVICES = "chronyd.service"; };
160195

161196
systemd.tmpfiles.rules = [
162197
"d ${stateDir} 0750 chrony chrony - -"
163198
"f ${driftFile} 0640 chrony chrony - -"
164199
"f ${keyFile} 0640 chrony chrony - -"
200+
] ++ lib.optionals cfg.enableRTCTrimming [
201+
"f ${rtcFile} 0640 chrony chrony - -"
165202
];
166203

167204
systemd.services.chronyd =

nixos/modules/services/networking/unbound.nix

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ in {
166166
services.unbound.settings = {
167167
server = {
168168
directory = mkDefault cfg.stateDir;
169-
username = cfg.user;
169+
username = ''""'';
170170
chroot = ''""'';
171171
pidfile = ''""'';
172172
# when running under systemd there is no need to daemonize
@@ -245,14 +245,13 @@ in {
245245
NotifyAccess = "main";
246246
Type = "notify";
247247

248-
# FIXME: Which of these do we actually need, can we drop the chroot flag?
249248
AmbientCapabilities = [
249+
"CAP_NET_BIND_SERVICE"
250+
"CAP_NET_RAW" # needed if ip-transparent is set to true
251+
];
252+
CapabilityBoundingSet = [
250253
"CAP_NET_BIND_SERVICE"
251254
"CAP_NET_RAW"
252-
"CAP_SETGID"
253-
"CAP_SETUID"
254-
"CAP_SYS_CHROOT"
255-
"CAP_SYS_RESOURCE"
256255
];
257256

258257
User = cfg.user;
@@ -266,22 +265,19 @@ in {
266265
ProtectControlGroups = true;
267266
ProtectKernelModules = true;
268267
ProtectSystem = "strict";
268+
ProtectClock = true;
269+
ProtectHostname = true;
270+
ProtectProc = "invisible";
271+
ProcSubset = "pid";
272+
ProtectKernelLogs = true;
273+
ProtectKernelTunables = true;
269274
RuntimeDirectory = "unbound";
270275
ConfigurationDirectory = "unbound";
271276
StateDirectory = "unbound";
272277
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_NETLINK" "AF_UNIX" ];
273278
RestrictRealtime = true;
274279
SystemCallArchitectures = "native";
275-
SystemCallFilter = [
276-
"~@clock"
277-
"@cpu-emulation"
278-
"@debug"
279-
"@keyring"
280-
"@module"
281-
"mount"
282-
"@obsolete"
283-
"@resources"
284-
];
280+
SystemCallFilter = [ "@system-service" ];
285281
RestrictNamespaces = true;
286282
LockPersonality = true;
287283
RestrictSUIDSGID = true;

0 commit comments

Comments
 (0)