···1+# Overlayfs {#sec-overlayfs}
2+3+NixOS offers a convenient abstraction to create both read-only as well writable
4+overlays.
5+6+```nix
7+fileSystems = {
8+ "/writable-overlay" = {
9+ overlay = {
10+ lowerdir = [ writableOverlayLowerdir ];
11+ upperdir = "/.rw-writable-overlay/upper";
12+ workdir = "/.rw-writable-overlay/work";
13+ };
14+ # Mount the writable overlay in the initrd.
15+ neededForBoot = true;
16+ };
17+ "/readonly-overlay".overlay.lowerdir = [
18+ writableOverlayLowerdir
19+ writableOverlayLowerdir2
20+ ];
21+};
22+```
23+24+If `upperdir` and `workdir` are not null, they will be created before the
25+overlay is mounted.
26+27+To mount an overlay as read-only, you need to provide at least two `lowerdir`s.
+5
nixos/doc/manual/release-notes/rl-2405.section.md
···278- The option [`services.nextcloud.config.dbport`] of the Nextcloud module was removed to match upstream.
279 The port can be specified in [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost).
28000000281- `stdenv`: The `--replace` flag in `substitute`, `substituteInPlace`, `substituteAll`, `substituteAllStream`, and `substituteStream` is now deprecated if favor of the new `--replace-fail`, `--replace-warn` and `--replace-quiet`. The deprecated `--replace` equates to `--replace-warn`.
282283- A new hardening flag, `zerocallusedregs` was made available, corresponding to the gcc/clang option `-fzero-call-used-regs=used-gpr`.
···278- The option [`services.nextcloud.config.dbport`] of the Nextcloud module was removed to match upstream.
279 The port can be specified in [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost).
280281+- A new abstraction to create both read-only as well as writable overlay file
282+ systems was added. Available via
283+ [fileSystems.overlay](#opt-fileSystems._name_.overlay.lowerdir). See also the
284+ [NixOS docs](#sec-overlayfs).
285+286- `stdenv`: The `--replace` flag in `substitute`, `substituteInPlace`, `substituteAll`, `substituteAllStream`, and `substituteStream` is now deprecated if favor of the new `--replace-fail`, `--replace-warn` and `--replace-quiet`. The deprecated `--replace` equates to `--replace-warn`.
287288- A new hardening flag, `zerocallusedregs` was made available, corresponding to the gcc/clang option `-fzero-call-used-regs=used-gpr`.
···64 example = "--max-freed $((64 * 1024**3))";
65 type = lib.types.singleLineStr;
66 description = lib.mdDoc ''
67- Options given to {file}`nix-collect-garbage` when the
68- garbage collector is run automatically.
69 '';
70 };
71
···64 example = "--max-freed $((64 * 1024**3))";
65 type = lib.types.singleLineStr;
66 description = lib.mdDoc ''
67+ Options given to [`nix-collect-garbage`](https://nixos.org/manual/nix/stable/command-ref/nix-collect-garbage) when the garbage collector is run automatically.
068 '';
69 };
70
···1+{ config, lib, pkgs, utils, ... }:
2+3+let
4+ # The scripted initrd contains some magic to add the prefix to the
5+ # paths just in time, so we don't add it here.
6+ sysrootPrefix = fs:
7+ if config.boot.initrd.systemd.enable && (utils.fsNeededForBoot fs) then
8+ "/sysroot"
9+ else
10+ "";
11+12+ # Returns a service that creates the required directories before the mount is
13+ # created.
14+ preMountService = _name: fs:
15+ let
16+ prefix = sysrootPrefix fs;
17+18+ escapedMountpoint = utils.escapeSystemdPath (prefix + fs.mountPoint);
19+ mountUnit = "${escapedMountpoint}.mount";
20+21+ upperdir = prefix + fs.overlay.upperdir;
22+ workdir = prefix + fs.overlay.workdir;
23+ in
24+ lib.mkIf (fs.overlay.upperdir != null)
25+ {
26+ "rw-${escapedMountpoint}" = {
27+ requiredBy = [ mountUnit ];
28+ before = [ mountUnit ];
29+ unitConfig = {
30+ DefaultDependencies = false;
31+ RequiresMountsFor = "${upperdir} ${workdir}";
32+ };
33+ serviceConfig = {
34+ Type = "oneshot";
35+ ExecStart = "${pkgs.coreutils}/bin/mkdir -p -m 0755 ${upperdir} ${workdir}";
36+ };
37+ };
38+ };
39+40+ overlayOpts = { config, ... }: {
41+42+ options.overlay = {
43+44+ lowerdir = lib.mkOption {
45+ type = with lib.types; nullOr (nonEmptyListOf (either str pathInStore));
46+ default = null;
47+ description = lib.mdDoc ''
48+ The list of path(s) to the lowerdir(s).
49+50+ To create a writable overlay, you MUST provide an upperdir and a
51+ workdir.
52+53+ You can create a read-only overlay when you provide multiple (at
54+ least 2!) lowerdirs and neither an upperdir nor a workdir.
55+ '';
56+ };
57+58+ upperdir = lib.mkOption {
59+ type = lib.types.nullOr lib.types.str;
60+ default = null;
61+ description = lib.mdDoc ''
62+ The path to the upperdir.
63+64+ If this is null, a read-only overlay is created using the lowerdir.
65+66+ If you set this to some value you MUST also set `workdir`.
67+ '';
68+ };
69+70+ workdir = lib.mkOption {
71+ type = lib.types.nullOr lib.types.str;
72+ default = null;
73+ description = lib.mdDoc ''
74+ The path to the workdir.
75+76+ This MUST be set if you set `upperdir`.
77+ '';
78+ };
79+80+ };
81+82+ config = lib.mkIf (config.overlay.lowerdir != null) {
83+ fsType = "overlay";
84+ device = lib.mkDefault "overlay";
85+86+ options =
87+ let
88+ prefix = sysrootPrefix config;
89+90+ lowerdir = map (s: prefix + s) config.overlay.lowerdir;
91+ upperdir = prefix + config.overlay.upperdir;
92+ workdir = prefix + config.overlay.workdir;
93+ in
94+ [
95+ "lowerdir=${lib.concatStringsSep ":" lowerdir}"
96+ ] ++ lib.optionals (config.overlay.upperdir != null) [
97+ "upperdir=${upperdir}"
98+ "workdir=${workdir}"
99+ ] ++ (map (s: "x-systemd.requires-mounts-for=${s}") lowerdir);
100+ };
101+102+ };
103+in
104+105+{
106+107+ options = {
108+109+ # Merge the overlay options into the fileSystems option.
110+ fileSystems = lib.mkOption {
111+ type = lib.types.attrsOf (lib.types.submodule [ overlayOpts ]);
112+ };
113+114+ };
115+116+ config =
117+ let
118+ overlayFileSystems = lib.filterAttrs (_name: fs: (fs.overlay.lowerdir != null)) config.fileSystems;
119+ initrdFileSystems = lib.filterAttrs (_name: utils.fsNeededForBoot) overlayFileSystems;
120+ userspaceFileSystems = lib.filterAttrs (_name: fs: (!utils.fsNeededForBoot fs)) overlayFileSystems;
121+ in
122+ {
123+124+ boot.initrd.availableKernelModules = lib.mkIf (initrdFileSystems != { }) [ "overlay" ];
125+126+ assertions = lib.concatLists (lib.mapAttrsToList
127+ (_name: fs: [
128+ {
129+ assertion = (fs.overlay.upperdir == null) == (fs.overlay.workdir == null);
130+ message = "You cannot define a `lowerdir` without a `workdir` and vice versa for mount point: ${fs.mountPoint}";
131+ }
132+ {
133+ assertion = (fs.overlay.lowerdir != null && fs.overlay.upperdir == null) -> (lib.length fs.overlay.lowerdir) >= 2;
134+ message = "A read-only overlay (without an `upperdir`) requires at least 2 `lowerdir`s: ${fs.mountPoint}";
135+ }
136+ ])
137+ config.fileSystems);
138+139+ boot.initrd.systemd.services = lib.mkMerge (lib.mapAttrsToList preMountService initrdFileSystems);
140+ systemd.services = lib.mkMerge (lib.mapAttrsToList preMountService userspaceFileSystems);
141+142+ };
143+144+}
+12-4
nixos/modules/virtualisation/qemu-vm.nix
···1066 ''}
1067 '';
10681069- systemd.tmpfiles.rules = lib.mkIf config.boot.initrd.systemd.enable [
1070- "f /etc/NIXOS 0644 root root -"
1071- "d /boot 0644 root root -"
1072- ];
0000000010731074 # After booting, register the closure of the paths in
1075 # `virtualisation.additionalPaths' in the Nix database in the VM. This
···1066 ''}
1067 '';
10681069+ systemd.tmpfiles.settings."10-qemu-vm" = lib.mkIf config.boot.initrd.systemd.enable {
1070+ "/etc/NIXOS".f = {
1071+ mode = "0644";
1072+ user = "root";
1073+ group = "root";
1074+ };
1075+ "${config.boot.loader.efi.efiSysMountPoint}".d = {
1076+ mode = "0644";
1077+ user = "root";
1078+ group = "root";
1079+ };
1080+ };
10811082 # After booting, register the closure of the paths in
1083 # `virtualisation.additionalPaths' in the Nix database in the VM. This
···1+{
2+ lib,
3+ buildNimPackage,
4+ fetchFromGitHub,
5+}:
6+buildNimPackage (final: prev: {
7+ pname = "nimlangserver";
8+ version = "1.2.0";
9+10+ # lock.json was generated by converting
11+ # nimble.lock into requires "<gitUrl>#revSha" in a dummy.nimble
12+ # for all packages and then running nim_lk on said dummy package
13+ # default nim_lk output fails because it attempts
14+ # to use branches that will not work instead of HEAD for packages
15+ lockFile = ./lock.json;
16+17+ src = fetchFromGitHub {
18+ owner = "nim-lang";
19+ repo = "langserver";
20+ rev = "71b59bfa77dabf6b8b381f6e18a1d963a1a658fc";
21+ hash = "sha256-dznegEhRHvztrNhBcUhW83RYgJpduwdGLWj/tJ//K8c=";
22+ };
23+24+ doCheck = false;
25+26+ meta = with lib;
27+ final.src.meta
28+ // {
29+ description = "The Nim language server implementation (based on nimsuggest)";
30+ license = licenses.mit;
31+ mainProgram = "nimlangserver";
32+ maintainers = with maintainers; [daylinmorgan];
33+ };
34+})
···188 description = "A flexible, powerful daemon for playing music";
189 homepage = "https://www.musicpd.org/";
190 license = licenses.gpl2Only;
191- maintainers = with maintainers; [ astsmtl ehmry tobim ];
192 platforms = platforms.unix;
193 mainProgram = "mpd";
194
···188 description = "A flexible, powerful daemon for playing music";
189 homepage = "https://www.musicpd.org/";
190 license = licenses.gpl2Only;
191+ maintainers = with maintainers; [ astsmtl tobim ];
192 platforms = platforms.unix;
193 mainProgram = "mpd";
194
+4-3
pkgs/servers/slimserver/default.nix
···22in
23perlPackages.buildPerlPackage rec {
24 pname = "slimserver";
25- version = "8.3.1";
2627 src = fetchFromGitHub {
28 owner = "Logitech";
29 repo = "slimserver";
30 rev = version;
31- hash = "sha256-yMFOwh/oPiJnUsKWBGvd/GZLjkWocMAUK0r+Hx/SUPo=";
32 };
3334 nativeBuildInputs = [ makeWrapper ];
···150151 meta = with lib; {
152 homepage = "https://github.com/Logitech/slimserver";
0153 description = "Server for Logitech Squeezebox players. This server is also called Logitech Media Server";
154- # the firmware is not under a free license, but not included in the default package
155 # https://github.com/Logitech/slimserver/blob/public/8.3/License.txt
156 license = if enableUnfreeFirmware then licenses.unfree else licenses.gpl2Only;
157 mainProgram = "slimserver";
···22in
23perlPackages.buildPerlPackage rec {
24 pname = "slimserver";
25+ version = "8.4.0";
2627 src = fetchFromGitHub {
28 owner = "Logitech";
29 repo = "slimserver";
30 rev = version;
31+ hash = "sha256-92mKchgAWRIrNOeK/zXUYRqIAk6THdtz1zQe3fg2kE0=";
32 };
3334 nativeBuildInputs = [ makeWrapper ];
···150151 meta = with lib; {
152 homepage = "https://github.com/Logitech/slimserver";
153+ changelog = "https://github.com/Logitech/slimserver/blob/${version}/Changelog${lib.versions.major version}.html";
154 description = "Server for Logitech Squeezebox players. This server is also called Logitech Media Server";
155+ # the firmware is not under a free license, so we do not include firmware in the default package
156 # https://github.com/Logitech/slimserver/blob/public/8.3/License.txt
157 license = if enableUnfreeFirmware then licenses.unfree else licenses.gpl2Only;
158 mainProgram = "slimserver";