diff options
Diffstat (limited to 'nixos')
220 files changed, 2982 insertions, 1912 deletions
diff --git a/nixos/doc/manual/configuration/abstractions.section.md b/nixos/doc/manual/configuration/abstractions.section.md index 8e7f4d80fbc64..3ff8ac885b653 100644 --- a/nixos/doc/manual/configuration/abstractions.section.md +++ b/nixos/doc/manual/configuration/abstractions.section.md @@ -33,7 +33,7 @@ in { services.httpd.virtualHosts = { "blog.example.org" = (commonConfig // { documentRoot = "/webroot/blog.example.org"; }); - "wiki.example.org" = (commonConfig // { documentRoot = "/webroot/wiki.example.com"; }); + "wiki.example.org" = (commonConfig // { documentRoot = "/webroot/wiki.example.org"; }); }; } ``` diff --git a/nixos/doc/manual/configuration/profiles/graphical.section.md b/nixos/doc/manual/configuration/profiles/graphical.section.md index 3bd80b52e845a..84fad5c0a612a 100644 --- a/nixos/doc/manual/configuration/profiles/graphical.section.md +++ b/nixos/doc/manual/configuration/profiles/graphical.section.md @@ -6,5 +6,5 @@ graphical installation CD. It sets [](#opt-services.xserver.enable), [](#opt-services.displayManager.sddm.enable), [](#opt-services.xserver.desktopManager.plasma5.enable), -and [](#opt-services.xserver.libinput.enable) to true. It also +and [](#opt-services.libinput.enable) to true. It also includes glxinfo and firefox in the system packages list. diff --git a/nixos/doc/manual/configuration/x-windows.chapter.md b/nixos/doc/manual/configuration/x-windows.chapter.md index c09e0877e8663..31752330dd9a8 100644 --- a/nixos/doc/manual/configuration/x-windows.chapter.md +++ b/nixos/doc/manual/configuration/x-windows.chapter.md @@ -207,7 +207,7 @@ Latitude series) can be enabled as follows: ```nix { - services.xserver.libinput.enable = true; + services.libinput.enable = true; } ``` @@ -216,7 +216,7 @@ For instance, the following disables tap-to-click behavior: ```nix { - services.xserver.libinput.touchpad.tapping = false; + services.libinput.touchpad.tapping = false; } ``` diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix index 558fec4cab923..80916e9733c5c 100644 --- a/nixos/doc/manual/default.nix +++ b/nixos/doc/manual/default.nix @@ -80,17 +80,17 @@ let cp -r --no-preserve=all $inputs/* . substituteInPlace ./manual.md \ - --replace '@NIXOS_VERSION@' "${version}" + --replace-fail '@NIXOS_VERSION@' "${version}" substituteInPlace ./configuration/configuration.md \ - --replace \ + --replace-fail \ '@MODULE_CHAPTERS@' \ ${escapeShellArg (concatMapStringsSep "\n" (p: "${p.value}") config.meta.doc)} substituteInPlace ./nixos-options.md \ - --replace \ + --replace-fail \ '@NIXOS_OPTIONS_JSON@' \ ${optionsDoc.optionsJSON}/${common.outputPath}/options.json substituteInPlace ./development/writing-nixos-tests.section.md \ - --replace \ + --replace-fail \ '@NIXOS_TEST_OPTIONS_JSON@' \ ${testOptionsDoc.optionsJSON}/${common.outputPath}/options.json sed -e '/@PYTHON_MACHINE_METHODS@/ {' -e 'r ${testDriverMachineDocstrings}/machine-methods.md' -e 'd' -e '}' \ diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 0693ca9e17bc2..cd2393514be8c 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -10,13 +10,13 @@ In addition to numerous new and upgraded packages, this release has the followin - `cryptsetup` has been upgraded from 2.6.1 to 2.7.0. Cryptsetup is a critical component enabling LUKS-based (but not only) full disk encryption. Take the time to review [the release notes](https://gitlab.com/cryptsetup/cryptsetup/-/raw/v2.7.0/docs/v2.7.0-ReleaseNotes). - One of the highlight is that it is now possible to use hardware OPAL-based encryption of your disk with `cryptsetup`, it has a lot of caveats, see the above notes for the full details. + One of the highlights is that it is now possible to use hardware OPAL-based encryption of your disk with `cryptsetup`. It has a lot of caveats, see the above notes for the full details. - `screen`'s module has been cleaned, and will now require you to set `programs.screen.enable` in order to populate `screenrc` and add the program to the environment. - `linuxPackages_testing_bcachefs` is now fully deprecated by `linuxPackages_latest`, and is therefore no longer available. -- The default kernel package has been updated from 6.1 to 6.6. All supported kernels remain available. +- (TODO not sure what path to use here) The default kernel package has been updated from 6.1 to 6.6. All supported kernels remain available. - NixOS now installs a stub ELF loader that prints an informative error message when users attempt to run binaries not made for NixOS. - This can be disabled through the `environment.stub-ld.enable` option. @@ -30,9 +30,13 @@ In addition to numerous new and upgraded packages, this release has the followin To disable this, set [nixpkgs.flake.setNixPath](#opt-nixpkgs.flake.setNixPath) and [nixpkgs.flake.setFlakeRegistry](#opt-nixpkgs.flake.setFlakeRegistry) to false. -- Julia environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`. +- `nixVersions.unstable` was removed. Instead the following attributes are provided: + - `nixVersions.git` which tracks the latest Nix master and is roughly updated once a week. This is intended to enable people to easily test unreleased changes of Nix to catch regressions earlier. + - `nixVersions.latest` which points to the latest Nix version packaged in nixpkgs. -- The PipeWire and WirePlumber modules have removed support for using +- `julia` environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`. + +- `pipewire` and `wireplumber` modules have removed support for using `environment.etc."pipewire/..."` and `environment.etc."wireplumber/..."`. Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for PipeWire and `services.pipewire.wireplumber.configPackages` for WirePlumber instead." @@ -41,16 +45,12 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi Refer to upstream [upgrade instructions](https://goteleport.com/docs/management/operations/upgrading/) and release notes for [v15](https://goteleport.com/docs/changelog/#1500-013124). -- A new option `systemd.sysusers.enable` was added. If enabled, users and +- `systemd.sysusers.enable` option was added. If enabled, users and groups are created with systemd-sysusers instead of with a custom perl script. -- The default dbus implementation has transitioned to dbus-broker from the classic dbus daemon for better performance and reliability. Users can revert to the classic dbus daemon by setting `services.dbus.implementation = "dbus";`. For detailed deviations, refer to [dbus-broker's deviations page](https://github.com/bus1/dbus-broker/wiki/Deviations). - -- A new option `virtualisation.containers.cdi` was added. It contains `static` and `dynamic` attributes (corresponding to `/etc/cdi` and `/run/cdi` respectively) to configure the Container Device Interface (CDI). - -- `virtualisation.docker.enableNvidia` and `virtualisation.podman.enableNvidia` options are deprecated. `virtualisation.containers.cdi.dynamic.nvidia.enable` should be used instead. This option will expose GPUs on containers with the `--device` CLI option. This is supported by Docker 25, Podman 3.2.0 and Singularity 4. Any container runtime that supports the CDI specification will take advantage of this feature. +- `virtualisation.docker.enableNvidia` and `virtualisation.podman.enableNvidia` options are deprecated. `hardware.nvidia-container-toolkit.enable` should be used instead. This option will expose GPUs on containers with the `--device` CLI option. This is supported by Docker 25, Podman 3.2.0 and Singularity 4. Any container runtime that supports the CDI specification will take advantage of this feature. -- A new option `system.etc.overlay.enable` was added. If enabled, `/etc` is +- `system.etc.overlay.enable` option was added. If enabled, `/etc` is mounted via an overlayfs instead of being created by a custom perl script. - NixOS AMIs are now uploaded regularly to a new AWS Account. @@ -69,16 +69,16 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi } ``` -- The initial Incus LTS release (v6.0.x) is now available through `virtualisation.incus` as the default. Users who wish to continue using the non-LTS release will need to set `virtualisation.incus.package = pkgs.incus`. Stable release users are encouraged to stay on the LTS release as non-LTS releases will by default not be backported. +- `virtialisation.incus` now defaults to the newly-added `incus-lts` release (v6.0.x). Users who wish to continue using the non-LTS release will need to set `virtualisation.incus.package = pkgs.incus`. Stable release users are encouraged to stay on the LTS release as non-LTS releases will by default not be backported. -- Canonical LXD has been upgraded to v5.21.x, an LTS release. The LTS release is now the only supported LXD release. Users are encouraged to [migrate to Incus](https://linuxcontainers.org/incus/docs/main/howto/server_migrate_lxd/) for better support on NixOS. +- Canonical `lxd` has been upgraded to v5.21.x, an LTS release. The LTS release is now the only supported LXD release. Users are encouraged to [migrate to Incus](https://linuxcontainers.org/incus/docs/main/howto/server_migrate_lxd/) for better support on NixOS. -- lua interpreters default LUA_PATH and LUA_CPATH are not overriden by nixpkgs +- `lua` interpreters default LUA_PATH and LUA_CPATH are not overriden by nixpkgs anymore, we patch LUA_ROOT instead which is more respectful to upstream. -- Plasma 6 is now available and can be installed with `services.xserver.desktopManager.plasma6.enable = true;`. Plasma 5 will likely be deprecated in the next release (24.11). Note that Plasma 6 runs as Wayland by default, and the X11 session needs to be explicitly selected if necessary. +- `plasma6` is now available and can be installed with `services.xserver.desktopManager.plasma6.enable = true;`. Plasma 5 will likely be deprecated in the next release (24.11). Note that Plasma 6 runs as Wayland by default, and the X11 session needs to be explicitly selected if necessary. -- The desktop mode of Lomiri (formerly known as Unity8), using Mir 2.x to function as a Wayland compositor, is now available and can be installed with `services.desktopManager.lomiri.enable = true`. Note that some core applications, services and indicators have yet to be packaged, and some functions may remain incomplete, but the base experience should be there. +- `lomiri` (formerly known as Unity8) desktop mode, using Mir 2.x to function as a Wayland compositor, is now available and can be installed with `services.desktopManager.lomiri.enable = true`. Note that some core applications, services and indicators have yet to be packaged, and some functions may remain incomplete, but the base experience should be there. ## New Services {#sec-release-24.05-new-services} @@ -92,6 +92,8 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi - [PhotonVision](https://photonvision.org/), a free, fast, and easy-to-use computer vision solution for the FIRST® Robotics Competition. +- [clatd](https://github.com/toreanderson/clatd), a a CLAT / SIIT-DC Edge Relay implementation for Linux. + - [pyLoad](https://pyload.net/), a FOSS download manager written in Python. Available as [services.pyload](#opt-services.pyload.enable) - [maubot](https://github.com/maubot/maubot), a plugin-based Matrix bot framework. Available as [services.maubot](#opt-services.maubot.enable). @@ -100,7 +102,7 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi - [ryzen-smu](https://gitlab.com/leogx9r/ryzen_smu), Linux kernel driver to expose the SMU (System Management Unit) for certain AMD Ryzen Processors. Includes the userspace program `monitor_cpu`. Available at [hardward.cpu.amd.ryzen-smu](#opt-hardware.cpu.amd.ryzen-smu.enable) -- systemd's gateway, upload, and remote services, which provides ways of sending journals across the network. Enable using [services.journald.gateway](#opt-services.journald.gateway.enable), [services.journald.upload](#opt-services.journald.upload.enable), and [services.journald.remote](#opt-services.journald.remote.enable). +- `systemd`'s `gateway`, `upload`, and `remote` services, which provide ways of sending journals across the network. Enable using [services.journald.gateway](#opt-services.journald.gateway.enable), [services.journald.upload](#opt-services.journald.upload.enable), and [services.journald.remote](#opt-services.journald.remote.enable). - [GNS3](https://www.gns3.com/), a network software emulator. Available as [services.gns3-server](#opt-services.gns3-server.enable). @@ -127,10 +129,12 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi - [db-rest](https://github.com/derhuerst/db-rest), a wrapper around Deutsche Bahn's internal API for public transport data. Available as [services.db-rest](#opt-services.db-rest.enable). - [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable). -The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares. +The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server software. - [mautrix-meta](https://github.com/mautrix/meta), a Matrix <-> Facebook and Matrix <-> Instagram hybrid puppeting/relaybot bridge. Available as services.mautrix-meta +- [Jottacloud Command-line Tool](https://docs.jottacloud.com/en/articles/1436834-jottacloud-command-line-tool), a CLI for the [Jottacloud](https://jottacloud.com/) cloud storage provider. Available as [user.services.jotta-cli](#opt-user.services.jotta-cli.enable). + - [transfer-sh](https://github.com/dutchcoders/transfer.sh), a tool that supports easy and fast file sharing from the command-line. Available as [services.transfer-sh](#opt-services.transfer-sh.enable). - [FCast Receiver](https://fcast.org), an open-source alternative to Chromecast and AirPlay. Available as [programs.fcast-receiver](#opt-programs.fcast-receiver.enable). @@ -139,7 +143,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [Suwayomi Server](https://github.com/Suwayomi/Suwayomi-Server), a free and open source manga reader server that runs extensions built for [Tachiyomi](https://tachiyomi.org). Available as [services.suwayomi-server](#opt-services.suwayomi-server.enable). -- A self-hosted management server for the [Netbird](https://netbird.io). Available as [services.netbird.server](#opt-services.netbird.server.enable). +- [Netbird](https://netbird.io), an open-source VPN management platform, now has a self-hosted management server. Available as [services.netbird.server](#opt-services.netbird.server.enable). - [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable). @@ -151,9 +155,9 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [Monado](https://monado.freedesktop.org/), an open source XR runtime. Available as [services.monado](#opt-services.monado.enable). -- [Pretix](https://pretix.eu/about/en/), an open source ticketing software for events. Available as [services.pretix]($opt-services-pretix.enable). +- [Pretix](https://pretix.eu/about/en/), an open source ticketing software for events. Available as [services.pretix](#opt-services.pretix.enable). -- [microsocks](https://github.com/rofl0r/microsocks), a tiny, portable SOCKS5 server with very moderate resource usage. Available as [services.microsocks]($opt-services-microsocks.enable). +- [microsocks](https://github.com/rofl0r/microsocks), a tiny, portable SOCKS5 server with very moderate resource usage. Available as [services.microsocks](#opt-services.microsocks.enable). - [inadyn](https://github.com/troglobit/inadyn), a Dynamic DNS client with built-in support for multiple providers. Available as [services.inadyn](#opt-services.inadyn.enable). @@ -163,21 +167,21 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [armagetronad](https://wiki.armagetronad.org), a mid-2000s 3D lightcycle game widely played at iD Tech Camps. You can define multiple servers using `services.armagetronad.<server>.enable`. -- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite]($opt-services.wyoming.satellite.enable). +- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite](#opt-services.wyoming.satellite.enable). - [TuxClocker](https://github.com/Lurkki14/tuxclocker), a hardware control and monitoring program. Available as [programs.tuxclocker](#opt-programs.tuxclocker.enable). -- binfmt option for AppImage-run to support running [AppImage](https://appimage.org/)'s seamlessly on NixOS.. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt). +- [AppImage](https://appimage.org/), a tool to package desktop applications, now has a `binfmt` option to support running AppImages seamlessly on NixOS. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt). - [nh](https://github.com/viperML/nh), yet another Nix CLI helper. Available as [programs.nh](#opt-programs.nh.enable). - [ALVR](https://github.com/alvr-org/alvr), a VR desktop streamer. Available as [programs.alvr](#opt-programs.alvr.enable) -- [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. +- [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. Available as [services.rustdesk-server](#opt-services.rustdesk-server.enable). -- [Scrutiny](https://github.com/AnalogJ/scrutiny), a S.M.A.R.T monitoring tool for hard disks with a web frontend. +- [Scrutiny](https://github.com/AnalogJ/scrutiny), a S.M.A.R.T monitoring tool for hard disks with a web frontend. Available as [services.scrutiny](#opt-services.scrutiny.enable). -- [davis](https://github.com/tchapi/davis), a simple CardDav and CalDav server inspired by Baïkal. Available as [services.davis]($opt-services-davis.enable). +- [davis](https://github.com/tchapi/davis), a simple CardDav and CalDav server inspired by Baïkal. Available as [services.davis](#opt-services.davis.enable). - [Firefly-iii](https://www.firefly-iii.org), a free and open source personal finance manager. Available as [services.firefly-iii](#opt-services.firefly-iii.enable) @@ -193,13 +197,29 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [prometheus-nats-exporter](https://github.com/nats-io/prometheus-nats-exporter), a Prometheus exporter for NATS. Available as [services.prometheus.exporters.nats](#opt-services.prometheus.exporters.nats.enable). +- [isolate](https://github.com/ioi/isolate), a sandbox for securely executing untrusted programs. Available as [security.isolate](#opt-security.isolate.enable). + ## Backward Incompatibilities {#sec-release-24.05-incompatibilities} <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> - `k3s`: was updated to version [v1.29](https://github.com/k3s-io/k3s/releases/tag/v1.29.1%2Bk3s2), all previous versions (k3s_1_26, k3s_1_27, k3s_1_28) will be removed. See [changelog and upgrade notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md#urgent-upgrade-notes) for more information. -- `himalaya` was updated to `v1.0.0-beta.4`, which introduces breaking changes. Check out the [release note](https://github.com/soywod/himalaya/releases/tag/v1.0.0-beta.4) for details. +- `himalaya` was updated to v1.0.0-beta.4, which introduces breaking changes. Check out the [release note](https://github.com/soywod/himalaya/releases/tag/v1.0.0-beta.4) for details. + +- `security.pam.enableSSHAgentAuth` was replaced by the `sshAgentAuth` attrset, and **only** + `authorized_keys` files listed in [`sshAgentAuth.authorizedKeysFiles`] are trusted, + defaulting to `/etc/ssh/authorized_keys.d/%u`. + ::: {.warning} + Users of {manpage}`pam_ssh_agent_auth(8)` must take care that the pubkeys they use (for instance with `sudo`) + are listed in [`sshAgentAuth.authorizedKeysFiles`]. + ::: + ::: {.note} + Previously, all `services.openssh.authorizedKeysFiles` were trusted, including `~/.ssh/authorized_keys`, + which results in an **insecure** configuration; see [#31611](https://github.com/NixOS/nixpkgs/issues/31611). + ::: + +[`sshAgentAuth.authorizedKeysFiles`]: #opt-security.pam.sshAgentAuth.authorizedKeysFiles - The `power.ups` module now generates `upsd.conf`, `upsd.users` and `upsmon.conf` automatically from a set of new configuration options. This breaks compatibility with existing `power.ups` setups where these files were created manually. Back up these files before upgrading NixOS. @@ -210,11 +230,13 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `cudaPackages.autoFixElfFiles` has been deprecated for `pkgs.autoFixElfFiles`. Functionality has not changed, but the setuphook has been renamed and moved to the top-level package scope. +- `appimageTools.wrapAppImage` now creates the binary at `$out/bin/${pname}` rather than `$out/bin/${pname}-${version}`, which will break downstream workarounds. + - `pdns` was updated to version [v4.9.x](https://doc.powerdns.com/authoritative/changelog/4.9.html), which introduces breaking changes. Check out the [Upgrade Notes](https://doc.powerdns.com/authoritative/upgrading.html#to-4-9-0) for details. - `unrar` was updated to v7. See [changelog](https://www.rarlab.com/unrar7notes.htm) for more information. -- `git-town` was updated from version `11` to `13`. See the [changelog](https://github.com/git-town/git-town/blob/main/CHANGELOG.md#1300-2024-03-22) for breaking changes. +- `git-town` was updated from version 11 to 13. See the [changelog](https://github.com/git-town/git-town/blob/main/CHANGELOG.md#1300-2024-03-22) for breaking changes. - `k9s` was updated to v0.31. There have been various breaking changes in the config file format, check out the changelog of [v0.29](https://github.com/derailed/k9s/releases/tag/v0.29.0), @@ -228,16 +250,16 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m The list in `nixos/modules/virtualisation/amazon-ec2-amis.nix` will stop being updated and will be removed in the future. -- The option `services.postgresql.ensureUsers._.ensurePermissions` has been removed as it's +- The option `services.postgresql.ensureUsers._.ensurePermissions` has been removed as it is not declarative and is broken with newer postgresql versions. Consider using [](#opt-services.postgresql.ensureUsers._.ensureDBOwnership) - instead or a tool that's more suited for managing the data inside a postgresql database. + instead or a tool that is more suited for managing the data inside a postgresql database. - `idris2` was updated to v0.7.0. This version introduces breaking changes. Check out the [changelog](https://github.com/idris-lang/Idris2/blob/v0.7.0/CHANGELOG.md#v070) for details. - `nvtop` family of packages was reorganized into nested attrset. `nvtop` has been renamed to `nvtopPackages.full`, and all `nvtop-{amd,nvidia,intel,msm}` packages are now named as `nvtopPackages.{amd,nvidia,intel,msm}` -- `neo4j` has been updated to 5, you may want to read the [release notes for Neo4j 5](https://neo4j.com/release-notes/database/neo4j-5/) +- `neo4j` has been updated to version 5. You may want to read the [release notes for Neo4j 5](https://neo4j.com/release-notes/database/neo4j-5/). - `services.neo4j.allowUpgrade` was removed and no longer has any effect. Neo4j 5 supports automatic rolling upgrades. @@ -251,37 +273,39 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `services.aria2.rpcSecret` has been replaced with `services.aria2.rpcSecretFile`. This was done so that secrets aren't stored in the world-readable nix store. - To migrate, you will have create a file with the same exact string, and change + To migrate, you will have to create a file with the same exact string, and change your module options to point to that file. For example, `services.aria2.rpcSecret = "mysecret"` becomes `services.aria2.rpcSecretFile = "/path/to/secret_file"` where the file `secret_file` contains the string `mysecret`. - `openssh`, `openssh_hpn` and `openssh_gssapi` are now compiled without support for the DSA signature algorithm as it is being deprecated upstream. Users still relying on DSA keys should consider upgrading - to another signature algorithm. It is however possible, for the time being, to restore the DSA keys support using `override` to set `dsaKeysSupport = true`. + to another signature algorithm. However, for the time being it is possible to restore DSA key support using `override` to set `dsaKeysSupport = true`. -- `buildGoModule` now throws error when `vendorHash` is not specified. `vendorSha256`, deprecated in Nixpkgs 23.11, is now ignored and is no longer a `vendorHash` alias. +- `buildGoModule` now throws an error when `vendorHash` is not specified. `vendorSha256`, deprecated in Nixpkgs 23.11, is now ignored and is no longer a `vendorHash` alias. -- Invidious has changed its default database username from `kemal` to `invidious`. Setups involving an externally provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857) +- `services.invidious.settings.db.user`, the default database username has changed from `kemal` to `invidious`. Setups involving an externally-provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857) - `writeReferencesToFile` is deprecated in favour of the new trivial build helper `writeClosure`. The latter accepts a list of paths and has an unambiguous name and cleaner implementation. - `inetutils` now has a lower priority to avoid shadowing the commonly used `util-linux`. If one wishes to restore the default priority, simply use `lib.setPrio 5 inetutils` or override with `meta.priority = 5`. -- `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the freeform type and option named `services.paperless.settings`. +- `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the free-form type and option named `services.paperless.settings`. -- `davfs2`' `services.davfs2.extraConfig` setting has been deprecated and converted to the freeform type option named `services.davfs2.settings` according to RFC42. +- `davfs2`' `services.davfs2.extraConfig` setting has been deprecated and converted to the free-form type option named `services.davfs2.settings` according to RFC42. -- `services.homepage-dashboard` now takes it's configuration using native Nix expressions, rather than dumping templated configurations into `/var/lib/homepage-dashboard` where they were previously managed manually. There are now new options which allow the configuration of bookmarks, services, widgets and custom CSS/JS natively in Nix. +- `services.homepage-dashboard` now takes its configuration using native Nix expressions, rather than dumping templated configurations into `/var/lib/homepage-dashboard` where they were previously managed manually. There are now new options which allow the configuration of bookmarks, services, widgets and custom CSS/JS natively in Nix. - `hare` may now be cross-compiled. For that to work, however, `haredoc` needed to stop being built together with it. Thus, the latter is now its own package with the name of `haredoc`. -- The legacy and long deprecated systemd target `network-interfaces.target` has been removed. Use `network.target` instead. +- `network-interfaces.target` system target was removed as it has been deprecated for a long time. Use `network.target` instead. + +- `services.redis.vmOverCommit` now defaults to `true` and no longer enforces Transparent Hugepages (THP) to be disabled. Redis only works with THP configured to `madvise` which is the kernel's default. - `azure-cli` now has extension support. For example, to install the `aks-preview` extension, use ```nix environment.systemPackages = [ - (azure-cli.withExtensions [ azure-cli.extensions.aks-preview ]); + (azure-cli.withExtensions [ azure-cli.extensions.aks-preview ]) ]; ``` To make the `azure-cli` immutable and prevent clashes in case `azure-cli` is also installed via other package managers, some configuration files were moved into the derivation. @@ -299,11 +323,15 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `gonic` has been updated to v0.16.4. Config now requires `playlists-path` to be set. See the rest of the [v0.16.0 release notes](https://github.com/sentriz/gonic/releases/tag/v0.16.0) for more details. -- The `services.vikunja` systemd service now uses `vikunja` as dynamic user instead of `vikunja-api`. Database users might need to be changed. +- `services.vikunja` systemd service now uses `vikunja` as dynamic user instead of `vikunja-api`. Database users might need to be changed. -- The `services.vikunja.setupNginx` setting has been removed. Users now need to setup the webserver configuration on their own with a proxy pass to the vikunja service. +- `services.vikunja.setupNginx` setting has been removed. Users now need to setup the webserver configuration on their own with a proxy pass to the vikunja service. -- The `woodpecker-*` packages have been updated to v2 which includes [breaking changes](https://woodpecker-ci.org/docs/next/migrations#200). +- `services.vmagent` module deprecates `dataDir`, `group` and `user` setting in favor of systemd provided CacheDirectory and DynamicUser. + +- `services.vmagent.remoteWriteUrl` setting has been renamed to `services.vmagent.remoteWrite.url` and now defaults to `null`. + +- `woodpecker-*` packages have been updated to v2 which includes [breaking changes](https://woodpecker-ci.org/docs/next/migrations#200). - `services.nginx` will no longer advertise HTTP/3 availability automatically. This must now be manually added, preferably to each location block. Example: @@ -319,27 +347,30 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m } ``` -- The package `optparse-bash` is now dropped due to upstream inactivity. Alternatives available in Nixpkgs include [`argc`](https://github.com/sigoden/argc), [`argbash`](https://github.com/matejak/argbash), [`bashly`](https://github.com/DannyBen/bashly) and [`gum`](https://github.com/charmbracelet/gum), to name a few. +- `optparse-bash` is now dropped due to upstream inactivity. Alternatives available in Nixpkgs include [`argc`](https://github.com/sigoden/argc), [`argbash`](https://github.com/matejak/argbash), [`bashly`](https://github.com/DannyBen/bashly) and [`gum`](https://github.com/charmbracelet/gum), to name a few. -- The `kanata` package has been updated to v1.5.0, which includes [breaking changes](https://github.com/jtroo/kanata/releases/tag/v1.5.0). +- `kanata` package has been updated to v1.6.0, which includes breaking changes. Check out the changelog of [v1.5.0](https://github.com/jtroo/kanata/releases/tag/v1.5.0) and [v1.6.0](https://github.com/jtroo/kanata/releases/tag/v1.6.0) for details. -- The `craftos-pc` package has been updated to v2.8, which includes [breaking changes](https://github.com/MCJack123/craftos2/releases/tag/v2.8). +- `craftos-pc` package has been updated to v2.8, which includes [breaking changes](https://github.com/MCJack123/craftos2/releases/tag/v2.8). - Files are now handled in binary mode; this could break programs with embedded UTF-8 characters. - The ROM was updated to match ComputerCraft version v1.109.2. - The bundled Lua was updated to Lua v5.2, which includes breaking changes. See the [Lua manual](https://www.lua.org/manual/5.2/manual.html#8) for more information. - The WebSocket API [was rewritten](https://github.com/MCJack123/craftos2/issues/337), which introduced breaking changes. -- The `gtest` package has been updated past v1.13.0, which requires C++14 or higher. +- `gtest` package has been updated past v1.13.0, which requires C++14 or higher. + +- Nextcloud 26 has been removed since it's not maintained anymore by upstream. -- The latest available version of Nextcloud is v28 (available as `pkgs.nextcloud28`). The installation logic is as follows: +- The latest available version of Nextcloud is v29 (available as `pkgs.nextcloud29`). The installation logic is as follows: - If [`services.nextcloud.package`](#opt-services.nextcloud.package) is specified explicitly, this package will be installed (**recommended**) - - If [`system.stateVersion`](#opt-system.stateVersion) is >=24.05, `pkgs.nextcloud28` will be installed by default. + - If [`system.stateVersion`](#opt-system.stateVersion) is >=24.05, `pkgs.nextcloud29` will be installed by default. - If [`system.stateVersion`](#opt-system.stateVersion) is >=23.11, `pkgs.nextcloud27` will be installed by default. - - Please note that an upgrade from v26 (or older) to v28 directly is not possible. Please upgrade to `nextcloud27` (or earlier) first. Nextcloud prohibits skipping major versions while upgrading. You can upgrade by declaring [`services.nextcloud.package = pkgs.nextcloud27;`](options.html#opt-services.nextcloud.package). + - Please note that an upgrade from v27 (or older) to v29 directly is not possible. Please upgrade to `nextcloud28` (or earlier) first. Nextcloud prohibits skipping major versions while upgrading. You can upgrade by declaring [`services.nextcloud.package = pkgs.nextcloud28;`](options.html#opt-services.nextcloud.package). + - Known warnings after the upgrade are documented in [](#module-services-nextcloud-known-warnings). - The vendored third party libraries have been mostly removed from `cudaPackages.nsight_systems`, which we now only ship for `cudaPackages_11_8` and later due to outdated dependencies. Users comfortable with the vendored dependencies may use `overrideAttrs` to amend the `postPatch` phase and the `meta.broken` correspondingly. Alternatively, one could package the deprecated `boost170` locally, as required for `cudaPackages_11_4.nsight_systems`. -- The `cudaPackages` package scope has been updated to `cudaPackages_12`. +- `cudaPackages` package scope has been updated to `cudaPackages_12`. - The deprecated `cudaPackages.cudatoolkit` has been replaced with a symlink-based wrapper for the splayed redistributable CUDA packages. The @@ -347,7 +378,9 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m like e.g. tensorflow. The original runfile-based `cudatoolkit` is still available as `cudatoolkit-legacy-runfile`. -- The `halloy` package was updated past 2024.5 which introduced a breaking change by switching the config format from YAML to TOML. See https://github.com/squidowl/halloy/releases/tag/2024.5 for details. +- `halloy` package was updated past 2024.5 which introduced a breaking change by switching the config format from YAML to TOML. See https://github.com/squidowl/halloy/releases/tag/2024.5 for details. + +- The `wpaperd` package has a breaking change moving to 1.0.1, previous version 0.3.0 had 2 different configuration files, one for wpaperd and one for the wallpapers. Remove the former and move the latter (`wallpaper.toml`) to `config.toml`. - Ada packages (libraries and tools) have been moved into the `gnatPackages` scope. `gnatPackages` uses the default GNAT compiler, `gnat12Packages` and `gnat13Packages` use the respective matching compiler version. @@ -367,10 +400,12 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `xxd` has been moved from `vim` default output to its own output to reduce closure size. The canonical way to reference it across all platforms is `unixtools.xxd`. -- The `stalwart-mail` package has been updated to v0.5.3, which includes [breaking changes](https://github.com/stalwartlabs/mail-server/blob/v0.5.3/UPGRADING.md). +- `stalwart-mail` package has been updated to v0.5.3, which includes [breaking changes](https://github.com/stalwartlabs/mail-server/blob/v0.5.3/UPGRADING.md). - `services.zope2` has been removed as `zope2` is unmaintained and was relying on Python2. +- `services.oauth2_proxy` was renamed to `services.oauth2-proxy`. Also the corresponding service, user and group were renamed. + - `services.avahi.nssmdns` got split into `services.avahi.nssmdns4` and `services.avahi.nssmdns6` which enable the mDNS NSS switch for IPv4 and IPv6 respectively. Since most mDNS responders only register IPv4 addresses, most users want to keep the IPv6 support disabled to avoid long timeouts. @@ -401,14 +436,18 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m upgrade NetBox by changing `services.netbox.package`. Database migrations will be run automatically. -- The executable file names for `firefox-devedition`, `firefox-beta`, `firefox-esr` now matches their package names, which is consistent with the `firefox-*-bin` packages. The desktop entries are also updated so that you can have multiple editions of firefox in your app launcher. +- `gauge` now supports installing plugins using nix. For the old imperative approach, switch to `gauge-unwrapped`. + You can load plugins from an existing gauge manifest file using `gauge.fromManifest ./path/to/manifest.json` or + specify plugins in nix using `gauge.withPlugins (p: with p; [ js html-report xml-report ])`. + +- `firefox-devedition`, `firefox-beta`, `firefox-esr` executable file names for now match their package names, which is consistent with the `firefox-*-bin` packages. The desktop entries are also updated so that you can have multiple editions of firefox in your app launcher. - switch-to-configuration does not directly call systemd-tmpfiles anymore. Instead, the new artificial sysinit-reactivation.target is introduced which allows to restart multiple services that are ordered before sysinit.target and respect the ordering between the services. -- The `systemd.oomd` module behavior is changed as: +- `systemd.oomd` module behavior is changed as: - Raise ManagedOOMMemoryPressureLimit from 50% to 80%. This should make systemd-oomd kill things less often, and fix issues like [this](https://pagure.io/fedora-workstation/issue/358). Reference: [commit](https://src.fedoraproject.org/rpms/systemd/c/806c95e1c70af18f81d499b24cd7acfa4c36ffd6?branch=806c95e1c70af18f81d499b24cd7acfa4c36ffd6) @@ -428,7 +467,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [watchdogd](https://troglobit.com/projects/watchdogd/), a system and process supervisor using watchdog timers. Available as [services.watchdogd](#opt-services.watchdogd.enable). -- The `jdt-language-server` package now uses upstream's provided python wrapper instead of our own custom wrapper. This results in the following breaking and notable changes: +- `jdt-language-server` package now uses upstream's provided python wrapper instead of our own custom wrapper. This results in the following breaking and notable changes: - The main binary for the package is now named `jdtls` instead of `jdt-language-server`, equivalent to what most editors expect the binary to be named. @@ -450,21 +489,23 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - Ruby plugin support has been disabled in DFHack. Many of the Ruby plugins have been converted to Lua, and support was removed upstream due to frequent crashes. -- The `livebook` package is now built as a `mix release` instead of an `escript`. +- `livebook` package is now built as a `mix release` instead of an `escript`. This means that configuration now has to be done using [environment variables](https://hexdocs.pm/livebook/readme.html#environment-variables) instead of command line arguments. This has the further implication that the `livebook` service configuration has changed: -- The `erlang_node_short_name`, `erlang_node_name`, `port` and `options` configuration parameters are gone, and have been replaced with an `environment` parameter. +- `erlang_node_short_name`, `erlang_node_name`, `port` and `options` configuration parameters are gone, and have been replaced with an `environment` parameter. Use the appropriate [environment variables](https://hexdocs.pm/livebook/readme.html#environment-variables) inside `environment` to configure the service instead. - `akkoma` now requires explicitly setting the base URL for uploaded media (`settings."Pleroma.Upload".base_url`), as well as for the media proxy if enabled (`settings."Media"`). This is recommended to be a separate (sub)domain to the one Akkoma is hosted at. See [here](https://meta.akkoma.dev/t/akkoma-stable-2024-03-securer-i-barely-know-her/681#explicit-upload-and-media-proxy-domains-5) for more details. -- The `crystal` package has been updated to 1.11.x, which has some breaking changes. +- `crystal` package has been updated to 1.11.x, which has some breaking changes. Refer to crystal's changelog for more information. ([v1.10](https://github.com/crystal-lang/crystal/blob/master/CHANGELOG.md#1100-2023-10-09), [v1.11](https://github.com/crystal-lang/crystal/blob/master/CHANGELOG.md#1110-2024-01-08)) -- The `erlang-ls` package no longer ships the `els_dap` binary as of v0.51.0. +- `erlang-ls` package no longer ships the `els_dap` binary as of v0.51.0. + +- `icu` no longer includes `install-sh` and `mkinstalldirs` in the shared folder. ## Other Notable Changes {#sec-release-24.05-notable-changes} @@ -472,14 +513,14 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `addDriverRunpath` has been added to facilitate the deprecation of the old `addOpenGLRunpath` setuphook. This change is motivated by the evolution of the setuphook to include all hardware acceleration. -- Cinnamon has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release and could potentially [affect Xorg sessions](https://blog.linuxmint.com/?p=4639). We suggest a reboot when switching between sessions. +- `cinnamon` has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release and could potentially [affect Xorg sessions](https://blog.linuxmint.com/?p=4639). We suggest a reboot when switching between sessions. -- MATE has been updated to 1.28. +- (TODO awaiting feedback on code-casing package names) MATE has been updated to 1.28. - To properly support panel plugins built with Wayland (in-process) support, we are introducing `services.xserver.desktopManager.mate.extraPanelApplets` option, please use that for installing panel applets. - Similarly, please use `services.xserver.desktopManager.mate.extraCajaExtensions` option for installing Caja extensions. - To use the Wayland session, enable `services.xserver.desktopManager.mate.enableWaylandSession`. This is opt-in for now as it is in early stage and introduces a new set of Wayfire closure. Due to [known issues with LightDM](https://github.com/canonical/lightdm/issues/63), we suggest using SDDM for display manager. -- The Budgie module installs gnome-terminal by default (instead of mate-terminal). +- `services.xserver.desktopManager.budgie` installs `gnome.gnome-terminal` by default (instead of `mate.mate-terminal`). - New `boot.loader.systemd-boot.xbootldrMountPoint` allows setting up a separate [XBOOTLDR partition](https://uapi-group.org/specifications/specs/boot_loader_specification/) to store boot files. Useful on systems with a small EFI System partition that cannot be easily repartitioned. @@ -488,19 +529,21 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `services.postgresql.extraPlugins` changed its type from just a list of packages to also a function that returns such a list. For example a config line like ``services.postgresql.extraPlugins = with pkgs.postgresql_11.pkgs; [ postgis ];`` is recommended to be changed to ``services.postgresql.extraPlugins = ps: with ps; [ postgis ];``; -- The Matrix homeserver [Synapse](https://element-hq.github.io/synapse/) module now supports configuring UNIX domain socket [listeners](#opt-services.matrix-synapse.settings.listeners) through the `path` option. +- [`matrix-synapse`](https://element-hq.github.io/synapse/) homeserver module now supports configuring UNIX domain socket [`listeners`](#opt-services.matrix-synapse.settings.listeners) through the `path` option. The default replication worker on the main instance has been migrated away from TCP sockets to UNIX domain sockets. -- The initrd ssh daemon module got a new option to add authorized keys via a list of files using `boot.initrd.network.ssh.authorizedKeyFiles`. +- `boot.initrd.network.ssh.authorizedKeyFiles` is a new option in the initrd ssh daemon module, for adding authorized keys via list of files. + +- `appimage`, `appimageTools.wrapAppImage` and `buildFHSEnvBubblewrap` now properly accepts `pname` and `version`. - Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles. The `nimPackages` and `nim2Packages` sets have been removed. See https://nixos.org/manual/nixpkgs/unstable#nim for more information. -- Programs written in [D](https://dlang.org/) using the `dub` build system and package manager can now be built using `buildDubPackage` utilizing lockfiles provided by the new `dub-to-nix` helper program. +- [TODO: reword to place an attribute at the front] Programs written in [D](https://dlang.org/) using the `dub` build system and package manager can now be built using `buildDubPackage` utilizing lockfiles provided by the new `dub-to-nix` helper program. See the [D section](https://nixos.org/manual/nixpkgs/unstable#dlang) in the manual for more information. -- [Portunus](https://github.com/majewsky/portunus) has been updated to major version 2. +- [`portunus`](https://github.com/majewsky/portunus) has been updated to major version 2. This version of Portunus supports strong password hashes, but the legacy hash SHA-256 is also still supported to ensure a smooth migration of existing user accounts. After upgrading, follow the instructions on the [upstream release notes](https://github.com/majewsky/portunus/releases/tag/v2.0.0) to upgrade all user accounts to strong password hashes. Support for weak password hashes will be removed in NixOS 24.11. @@ -509,11 +552,11 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `libass` now uses the native CoreText backend on Darwin, which may fix subtitle rendering issues with `mpv`, `ffmpeg`, etc. -- [Lilypond](https://lilypond.org/index.html) and [Denemo](https://www.denemo.org) are now compiled with Guile 3.0. +- [`lilypond`](https://lilypond.org/index.html) and [`denemo`](https://www.denemo.org) are now compiled with Guile 3.0. -- Garage has been updated to v1.x.x. Users should read the [upstream release notes](https://git.deuxfleurs.fr/Deuxfleurs/garage/releases/tag/v1.0.0) and follow the documentation when changing over their `services.garage.package` and performing this manual upgrade. +- `garage` has been updated to v1.x.x. Users should read the [upstream release notes](https://git.deuxfleurs.fr/Deuxfleurs/garage/releases/tag/v1.0.0) and follow the documentation when changing over their `services.garage.package` and performing this manual upgrade. -- The EC2 image module now enables the [Amazon SSM Agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html) by default. +- [TODO: reword to place an attribute at the front] The EC2 image module now enables the [Amazon SSM Agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html) by default. - The following options of the Nextcloud module were moved into [`services.nextcloud.settings`](#opt-services.nextcloud.settings) and renamed to match the name from Nextcloud's `config.php`: - `logLevel` -> [`loglevel`](#opt-services.nextcloud.settings.loglevel), @@ -525,7 +568,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `extraTrustedDomains` -> [`trusted_domains`](#opt-services.nextcloud.settings.trusted_domains) and - `trustedProxies` -> [`trusted_proxies`](#opt-services.nextcloud.settings.trusted_proxies). -- The option [`services.nextcloud.config.dbport`] of the Nextcloud module was removed to match upstream. +- `services.nextcloud.config.dbport` option of the Nextcloud module was removed to match upstream. The port can be specified in [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost). - A new abstraction to create both read-only as well as writable overlay file @@ -533,7 +576,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m [fileSystems.overlay](#opt-fileSystems._name_.overlay.lowerdir). See also the [NixOS docs](#sec-overlayfs). -- systemd units can now specify the `Upholds=` and `UpheldBy=` unit dependencies via the aptly +- `systemd` units can now specify the `Upholds=` and `UpheldBy=` unit dependencies via the aptly named `upholds` and `upheldBy` options. These options get systemd to enforce that the dependencies remain continuosly running for as long as the dependent unit is in a running state. @@ -546,33 +589,27 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - New options were added to the dnsdist module to enable and configure a DNSCrypt endpoint (see `services.dnsdist.dnscrypt.enable`, etc.). The module can generate the DNSCrypt provider key pair, certificates and also performs their rotation automatically with no downtime. -- With a bump to `sonarr` v4, existing config database files will be upgraded automatically, but note that some old apparently-working configs [might actually be corrupt and fail to upgrade cleanly](https://forums.sonarr.tv/t/sonarr-v4-released/33089). +- `sonarr` version bumped to from 3.0.10 to 4.0.3. Consequently existing config database files will be upgraded automatically, but note that some old apparently-working configs [might actually be corrupt and fail to upgrade cleanly](https://forums.sonarr.tv/t/sonarr-v4-released/33089). -- The Yama LSM is now enabled by default in the kernel, which prevents ptracing +- [TODO: reword to place an attribute at the front] The Yama LSM is now enabled by default in the kernel, which prevents ptracing non-child processes. This means you will not be able to attach gdb to an existing process, but will need to start that process from gdb (so it is a child). Or you can set `boot.kernel.sysctl."kernel.yama.ptrace_scope"` to 0. -- The netbird module now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.tunnels). +- `netbird` module now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.tunnels). - [Nginx virtual hosts](#opt-services.nginx.virtualHosts) using `forceSSL` or - `globalRedirect` can now have redirect codes other than 301 through + `globalRedirect` can now have redirect codes other than 301 through `redirectCode`. - `bacula` now allows to configure `TLS` for encrypted communication. - `redirectCode`. - -- `libjxl` 0.9.0 [dropped support for the butteraugli API](https://github.com/libjxl/libjxl/pull/2576). You will no longer be able to set `enableButteraugli` on `libaom`. - -- The source of the `mockgen` package has changed to the [go.uber.org/mock](https://github.com/uber-go/mock) fork because [the original repository is no longer maintained](https://github.com/golang/mock#gomock). +- `libjxl` version bumped from 0.8.2 to 0.9.1 [dropped support for the butteraugli API](https://github.com/libjxl/libjxl/pull/2576). You will no longer be able to set `enableButteraugli` on `libaom`. -- `security.pam.enableSSHAgentAuth` was renamed to `security.pam.sshAgentAuth.enable` and an `authorizedKeysFiles` - option was added, to control which `authorized_keys` files are trusted. It defaults to the previous behaviour, - **which is insecure**: see [#31611](https://github.com/NixOS/nixpkgs/issues/31611). +- `mockgen` package source has changed to the [go.uber.org/mock](https://github.com/uber-go/mock) fork because [the original repository is no longer maintained](https://github.com/golang/mock#gomock). - [](#opt-boot.kernel.sysctl._net.core.wmem_max_) changed from a string to an integer because of the addition of a custom merge option (taking the highest value defined to avoid conflicts between 2 services trying to set that value), just as [](#opt-boot.kernel.sysctl._net.core.rmem_max_) since 22.11. -- A new top-level package set, `pkgsExtraHardening` is added. This is a set of packages built with stricter hardening flags - those that have not yet received enough testing to be applied universally, those that are more likely to cause build failures or those that have drawbacks to their use (e.g. performance or required hardware features). +- [TODO: reword to place an attribute at the front] A new top-level package set, `pkgsExtraHardening` is added. This is a set of packages built with stricter hardening flags - those that have not yet received enough testing to be applied universally, those that are more likely to cause build failures or those that have drawbacks to their use (e.g. performance or required hardware features). - `services.zfs.zed.enableMail` now uses the global `sendmail` wrapper defined by an email module (such as msmtp or Postfix). It no longer requires using a special ZFS build with email support. @@ -581,59 +618,59 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `nextcloud-setup.service` no longer changes the group of each file & directory inside `/var/lib/nextcloud/{config,data,store-apps}` if one of these directories has the wrong owner group. This was part of transitioning the group used for `/var/lib/nextcloud`, but isn't necessary anymore. -- `services.kavita` now uses the freeform option `services.kavita.settings` for the application settings file. +- `services.kavita` now uses the free-form option `services.kavita.settings` for the application settings file. The options `services.kavita.ipAdresses` and `services.kavita.port` now exist at `services.kavita.settings.IpAddresses` and `services.kavita.settings.IpAddresses`. The file at `services.kavita.tokenKeyFile` now needs to contain a secret with 512+ bits instead of 128+ bits. - `kavita` has been updated to 0.8.0, requiring a manual forced library scan on all libraries for migration. Refer to upstream's [release notes](https://github.com/Kareadita/Kavita/releases/tag/v0.8.0) for details. -- The `krb5` module has been rewritten and moved to `security.krb5`, moving all options but `security.krb5.enable` and `security.krb5.package` into `security.krb5.settings`. +- `krb5` module has been rewritten and moved to `security.krb5`, moving all options but `security.krb5.enable` and `security.krb5.package` into `security.krb5.settings`. - `services.soju` now has a wrapper for the `sojuctl` command, pointed at the service config file. It also has the new option `adminSocket.enable`, which creates a unix admin socket at `/run/soju/admin`. -- Gitea 1.21 upgrade has several breaking changes, including: +- `gitea` upgrade to 1.21 has several breaking changes, including: - Custom themes and other assets that were previously stored in `custom/public/*` now belong in `custom/public/assets/*` - New instances of Gitea using MySQL now ignore the `[database].CHARSET` config option and always use the `utf8mb4` charset, existing instances should migrate via the `gitea doctor convert` CLI command. -- The `services.paperless` module no longer uses the previously downloaded NLTK data stored in `/var/cache/paperless/nltk`. This directory can be removed. +- `services.paperless` module no longer uses the previously downloaded NLTK data stored in `/var/cache/paperless/nltk`. This directory can be removed. -- The `services.teeworlds` module now has a wealth of configuration options, including a new `package` option. +- `services.teeworlds` module now has a wealth of configuration options, including a new `package` option. -- The `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399). +- `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399). -- The `services.networkmanager.extraConfig` was renamed to `services.networkmanager.settings` and was changed to use the ini type instead of using a multiline string. +- `services.networkmanager.extraConfig` was renamed to `services.networkmanager.settings` and was changed to use the ini type instead of using a multiline string. -- The module `services.github-runner` has been removed. To configure a single GitHub Actions Runner refer to `services.github-runners.*`. Note that this will trigger a new runner registration. +- `services.github-runner` module has been removed. To configure a single GitHub Actions Runner refer to `services.github-runners.*`. Note that this will trigger a new runner registration. -- The `services.slskd` has been refactored to include more configuation options in - the freeform `services.slskd.settings` option, and some defaults (including listen ports) +- `services.slskd` has been refactored to include more configuation options in + the free-form `services.slskd.settings` option, and some defaults (including listen ports) have been changed to match the upstream defaults. Additionally, disk logging is now disabled by default, and the log rotation timer has been removed. The nginx virtualhost option is now of the `vhost-options` type. -- The `btrbk` module now automatically selects and provides required compression +- `services.btrbk` now automatically selects and provides required compression program depending on the configured `stream_compress` option. Since this replaces the need for the `extraPackages` option, this option will be deprecated in future releases. -- The `mpich` package expression now requires `withPm` to be a list, e.g. `"hydra:gforker"` becomes `[ "hydra" "gforker" ]`. +- `mpich` package expression now requires `withPm` to be a list, e.g. `"hydra:gforker"` becomes `[ "hydra" "gforker" ]`. -- When merging systemd unit options (of type `unitOption`), +- `systemd`: when merging unit options (of type `unitOption`), if at least one definition is a list, all those which aren't are now lifted into a list, making it possible to accumulate definitions without resorting to `mkForce`, hence to retain the definitions not anticipating that need. -- YouTrack is bumped to 2023.3. The update is not performed automatically, it requires manual interaction. See the YouTrack section in the manual for details. +- `youtrack` is bumped to 2023.3. The update is not performed automatically, it requires manual interaction. See the YouTrack section in the manual for details. - QtMultimedia has changed its default backend to `QT_MEDIA_BACKEND=ffmpeg` (previously `gstreamer` on Linux or `darwin` on MacOS). The previous native backends remain available but are now minimally maintained. Refer to [upstream documentation](https://doc.qt.io/qt-6/qtmultimedia-index.html#ffmpeg-as-the-default-backend) for further details about each platform. -- The `drbd` out-of-tree Linux kernel driver has been added in version `9.2.7`. With it the DRBD 9.x features can be used instead of the 8.x features provided by the `8.4.11` in-tree driver. +- `drbd` out-of-tree Linux kernel driver has been added in version 9.2.7. With it the DRBD 9.x features can be used instead of the 8.x features provided by the 8.4.11 in-tree driver. -- The oil shell's c++ version is now available as `oils-for-unix`. The python version is still available as `oil` +- [TODO: reword to place an attribute at the front] The oil shell's c++ version is now available as `oils-for-unix`. The python version is still available as `oil` - `documentation.man.mandoc` now by default uses `MANPATH` to set the directories where mandoc will search for manual pages. This enables mandoc to find manual pages in Nix profiles. To set the manual search paths via the `mandoc.conf` configuration file like before, use `documentation.man.mandoc.settings.manpath` instead. -- The `grafana-loki` package was updated to 3.0.0 which includes [breaking changes](https://github.com/grafana/loki/releases/tag/v3.0.0) +- `grafana-loki` package was updated to 3.0.0 which includes [breaking changes](https://github.com/grafana/loki/releases/tag/v3.0.0) diff --git a/nixos/lib/qemu-common.nix b/nixos/lib/qemu-common.nix index b946f62d93dc3..f1e19c5b3b720 100644 --- a/nixos/lib/qemu-common.nix +++ b/nixos/lib/qemu-common.nix @@ -35,6 +35,8 @@ rec { aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -machine virt,gic-version=max,accel=kvm:tcg -cpu max"; powerpc64le-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv"; powerpc64-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv"; + riscv32-linux = "${qemuPkg}/bin/qemu-system-riscv32 -machine virt"; + riscv64-linux = "${qemuPkg}/bin/qemu-system-riscv64 -machine virt"; x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max"; }; otherHostGuestMatrix = { diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix index 54ca88d4a9a0c..eef49f8c4ef38 100644 --- a/nixos/lib/systemd-lib.nix +++ b/nixos/lib/systemd-lib.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs }: +{ config, lib, pkgs, utils }: let inherit (lib) @@ -396,8 +396,41 @@ in rec { }; }; - serviceConfig = { config, ... }: { - config.environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}"; + serviceConfig = { name, config, ... }: { + config = { + name = "${name}.service"; + environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}"; + }; + }; + + pathConfig = { name, config, ... }: { + config = { + name = "${name}.path"; + }; + }; + + socketConfig = { name, config, ... }: { + config = { + name = "${name}.socket"; + }; + }; + + sliceConfig = { name, config, ... }: { + config = { + name = "${name}.slice"; + }; + }; + + targetConfig = { name, config, ... }: { + config = { + name = "${name}.target"; + }; + }; + + timerConfig = { name, config, ... }: { + config = { + name = "${name}.timer"; + }; }; stage2ServiceConfig = { @@ -416,6 +449,7 @@ in rec { mountConfig = { config, ... }: { config = { + name = "${utils.escapeSystemdPath config.where}.mount"; mountConfig = { What = config.what; Where = config.where; @@ -429,6 +463,7 @@ in rec { automountConfig = { config, ... }: { config = { + name = "${utils.escapeSystemdPath config.where}.automount"; automountConfig = { Where = config.where; }; @@ -444,8 +479,8 @@ in rec { WantedBy=${concatStringsSep " " def.wantedBy} ''; - targetToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + targetToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = '' [Unit] @@ -453,8 +488,8 @@ in rec { ''; }; - serviceToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + serviceToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def ('' [Service] '' + (let env = cfg.globalEnvironment // def.environment; @@ -463,7 +498,7 @@ in rec { "Environment=${toJSON "${n}=${env.${n}}"}\n"; # systemd max line length is now 1MiB # https://github.com/systemd/systemd/commit/e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af - in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)) + in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${def.name}.service’ is too long." else s) (attrNames env)) + (if def ? reloadIfChanged && def.reloadIfChanged then '' X-ReloadIfChanged=true '' else if (def ? restartIfChanged && !def.restartIfChanged) then '' @@ -474,8 +509,8 @@ in rec { '' + attrsToSection def.serviceConfig); }; - socketToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + socketToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Socket] ${attrsToSection def.socketConfig} @@ -484,40 +519,40 @@ in rec { ''; }; - timerToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + timerToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Timer] ${attrsToSection def.timerConfig} ''; }; - pathToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + pathToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Path] ${attrsToSection def.pathConfig} ''; }; - mountToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + mountToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Mount] ${attrsToSection def.mountConfig} ''; }; - automountToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + automountToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Automount] ${attrsToSection def.automountConfig} ''; }; - sliceToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + sliceToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Slice] ${attrsToSection def.sliceConfig} diff --git a/nixos/lib/systemd-types.nix b/nixos/lib/systemd-types.nix index c4c5771cff822..f3bc8e06d9cb9 100644 --- a/nixos/lib/systemd-types.nix +++ b/nixos/lib/systemd-types.nix @@ -5,8 +5,13 @@ let automountConfig makeUnit mountConfig + pathConfig + sliceConfig + socketConfig stage1ServiceConfig stage2ServiceConfig + targetConfig + timerConfig unitConfig ; @@ -48,29 +53,32 @@ let ; in -rec { +{ units = attrsOf (submodule ({ name, config, ... }: { options = concreteUnitOptions; - config = { unit = mkDefault (makeUnit name config); }; + config = { + name = mkDefault name; + unit = mkDefault (makeUnit name config); + }; })); services = attrsOf (submodule [ stage2ServiceOptions unitConfig stage2ServiceConfig ]); initrdServices = attrsOf (submodule [ stage1ServiceOptions unitConfig stage1ServiceConfig ]); - targets = attrsOf (submodule [ stage2CommonUnitOptions unitConfig ]); - initrdTargets = attrsOf (submodule [ stage1CommonUnitOptions unitConfig ]); + targets = attrsOf (submodule [ stage2CommonUnitOptions unitConfig targetConfig ]); + initrdTargets = attrsOf (submodule [ stage1CommonUnitOptions unitConfig targetConfig ]); - sockets = attrsOf (submodule [ stage2SocketOptions unitConfig ]); - initrdSockets = attrsOf (submodule [ stage1SocketOptions unitConfig ]); + sockets = attrsOf (submodule [ stage2SocketOptions unitConfig socketConfig]); + initrdSockets = attrsOf (submodule [ stage1SocketOptions unitConfig socketConfig ]); - timers = attrsOf (submodule [ stage2TimerOptions unitConfig ]); - initrdTimers = attrsOf (submodule [ stage1TimerOptions unitConfig ]); + timers = attrsOf (submodule [ stage2TimerOptions unitConfig timerConfig ]); + initrdTimers = attrsOf (submodule [ stage1TimerOptions unitConfig timerConfig ]); - paths = attrsOf (submodule [ stage2PathOptions unitConfig ]); - initrdPaths = attrsOf (submodule [ stage1PathOptions unitConfig ]); + paths = attrsOf (submodule [ stage2PathOptions unitConfig pathConfig ]); + initrdPaths = attrsOf (submodule [ stage1PathOptions unitConfig pathConfig ]); - slices = attrsOf (submodule [ stage2SliceOptions unitConfig ]); - initrdSlices = attrsOf (submodule [ stage1SliceOptions unitConfig ]); + slices = attrsOf (submodule [ stage2SliceOptions unitConfig sliceConfig ]); + initrdSlices = attrsOf (submodule [ stage1SliceOptions unitConfig sliceConfig ]); mounts = listOf (submodule [ stage2MountOptions unitConfig mountConfig ]); initrdMounts = listOf (submodule [ stage1MountOptions unitConfig mountConfig ]); diff --git a/nixos/lib/systemd-unit-options.nix b/nixos/lib/systemd-unit-options.nix index fc990a87f0c20..160f2bf9483ae 100644 --- a/nixos/lib/systemd-unit-options.nix +++ b/nixos/lib/systemd-unit-options.nix @@ -65,6 +65,14 @@ in rec { ''; }; + name = lib.mkOption { + type = lib.types.str; + description = '' + The name of this systemd unit, including its extension. + This can be used to refer to this unit from other systemd units. + ''; + }; + overrideStrategy = mkOption { default = "asDropinIfExists"; type = types.enum [ "asDropinIfExists" "asDropin" ]; diff --git a/nixos/lib/utils.nix b/nixos/lib/utils.nix index 4992113bdbd25..c1c1828a2c12c 100644 --- a/nixos/lib/utils.nix +++ b/nixos/lib/utils.nix @@ -35,7 +35,8 @@ let inherit (lib.strings) toJSON normalizePath escapeC; in -rec { +let +utils = rec { # Copy configuration files to avoid having the entire sources in the system closure copyFile = filePath: pkgs.runCommand (builtins.unsafeDiscardStringContext (baseNameOf filePath)) {} '' @@ -262,11 +263,12 @@ rec { filter (x: !(elem (getName x) namesToRemove)) packages; systemdUtils = { - lib = import ./systemd-lib.nix { inherit lib config pkgs; }; + lib = import ./systemd-lib.nix { inherit lib config pkgs utils; }; unitOptions = import ./systemd-unit-options.nix { inherit lib systemdUtils; }; types = import ./systemd-types.nix { inherit lib systemdUtils pkgs; }; network = { units = import ./systemd-network-units.nix { inherit lib systemdUtils; }; }; }; -} +}; +in utils diff --git a/nixos/modules/config/malloc.nix b/nixos/modules/config/malloc.nix index 4214ae5983156..e414970b0be5a 100644 --- a/nixos/modules/config/malloc.nix +++ b/nixos/modules/config/malloc.nix @@ -9,8 +9,23 @@ let graphene-hardened = { libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc.so"; description = '' - An allocator designed to mitigate memory corruption attacks, such as - those caused by use-after-free bugs. + Hardened memory allocator coming from GrapheneOS project. + The default configuration template has all normal optional security + features enabled and is quite aggressive in terms of sacrificing + performance and memory usage for security. + ''; + }; + + graphene-hardened-light = { + libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc-light.so"; + description = '' + Hardened memory allocator coming from GrapheneOS project. + The light configuration template disables the slab quarantines, + write after free check, slot randomization and raises the guard + slab interval from 1 to 8 but leaves zero-on-free and slab canaries enabled. + The light configuration has solid performance and memory usage while still + being far more secure than mainstream allocators with much better security + properties. ''; }; diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix index c9a133d0558a5..1d7976cef36a2 100644 --- a/nixos/modules/config/no-x-libs.nix +++ b/nixos/modules/config/no-x-libs.nix @@ -31,8 +31,11 @@ with lib; cairo = super.cairo.override { x11Support = false; }; dbus = super.dbus.override { x11Support = false; }; fastfetch = super.fastfetch.override { vulkanSupport = false; waylandSupport = false; x11Support = false; }; + ffmpeg = super.ffmpeg.override { ffmpegVariant = "headless"; }; ffmpeg_4 = super.ffmpeg_4.override { ffmpegVariant = "headless"; }; ffmpeg_5 = super.ffmpeg_5.override { ffmpegVariant = "headless"; }; + ffmpeg_6 = super.ffmpeg_6.override { ffmpegVariant = "headless"; }; + ffmpeg_7 = super.ffmpeg_7.override { ffmpegVariant = "headless"; }; # dep of graphviz, libXpm is optional for Xpm support gd = super.gd.override { withXorg = false; }; ghostscript = super.ghostscript.override { cupsSupport = false; x11Support = false; }; @@ -44,7 +47,7 @@ with lib; gst_all_1 = super.gst_all_1 // { gst-plugins-bad = super.gst_all_1.gst-plugins-bad.override { guiSupport = false; }; gst-plugins-base = super.gst_all_1.gst-plugins-base.override { enableWayland = false; enableX11 = false; }; - gst-plugins-good = super.gst_all_1.gst-plugins-good.override { enableX11 = false; }; + gst-plugins-good = super.gst_all_1.gst-plugins-good.override { enableWayland = false; enableX11 = false; gtkSupport = false; qt5Support = false; qt6Support = false; }; }; imagemagick = super.imagemagick.override { libX11Support = false; libXtSupport = false; }; imagemagickBig = super.imagemagickBig.override { libX11Support = false; libXtSupport = false; }; diff --git a/nixos/modules/hardware/openrazer.nix b/nixos/modules/hardware/openrazer.nix index 99b5510543233..5ba6abfdb3d7e 100644 --- a/nixos/modules/hardware/openrazer.nix +++ b/nixos/modules/hardware/openrazer.nix @@ -19,7 +19,9 @@ let [Startup] sync_effects_enabled = ${toPyBoolStr cfg.syncEffectsEnabled} devices_off_on_screensaver = ${toPyBoolStr cfg.devicesOffOnScreensaver} - mouse_battery_notifier = ${toPyBoolStr cfg.mouseBatteryNotifier} + battery_notifier = ${toPyBoolStr (cfg.mouseBatteryNotifier || cfg.batteryNotifier.enable)} + battery_notifier_freq = ${builtins.toString cfg.batteryNotifier.frequency} + battery_notifier_percent = ${builtins.toString cfg.batteryNotifier.percentage} [Statistics] key_statistics = ${toPyBoolStr cfg.keyStatistics} @@ -86,6 +88,41 @@ in ''; }; + batteryNotifier = mkOption { + description = '' + Settings for device battery notifications. + ''; + default = {}; + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = true; + description = '' + Mouse battery notifier. + ''; + }; + frequency = mkOption { + type = types.int; + default = 600; + description = '' + How often battery notifications should be shown (in seconds). + A value of 0 disables notifications. + ''; + }; + + percentage = mkOption { + type = types.int; + default = 33; + description = '' + At what battery percentage the device should reach before + sending notifications. + ''; + }; + }; + }; + }; + keyStatistics = mkOption { type = types.bool; default = false; @@ -107,6 +144,13 @@ in }; config = mkIf cfg.enable { + warnings = flatten [ + (optional cfg.mouseBatteryNotifier '' + The option openrazer.mouseBatteryNotifier is deprecated. + Please use openrazer.batteryNotifier instead to enable and configure battery notifications. + '') + ]; + boot.extraModulePackages = [ kernelPackages.openrazer ]; boot.kernelModules = drivers; @@ -127,15 +171,15 @@ in systemd.user.services.openrazer-daemon = { description = "Daemon to manage razer devices in userspace"; unitConfig.Documentation = "man:openrazer-daemon(8)"; - # Requires a graphical session so the daemon knows when the screensaver - # starts. See the 'devicesOffOnScreensaver' option. - wantedBy = [ "graphical-session.target" ]; - partOf = [ "graphical-session.target" ]; - serviceConfig = { - Type = "dbus"; - BusName = "org.razer"; - ExecStart = "${daemonExe} --foreground"; - Restart = "always"; + # Requires a graphical session so the daemon knows when the screensaver + # starts. See the 'devicesOffOnScreensaver' option. + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + serviceConfig = { + Type = "dbus"; + BusName = "org.razer"; + ExecStart = "${daemonExe} --foreground"; + Restart = "always"; }; }; }; diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix index e7f9990e9632e..7f16b97440c1c 100644 --- a/nixos/modules/installer/tools/tools.nix +++ b/nixos/modules/installer/tools/tools.nix @@ -185,7 +185,7 @@ in # }; # Enable touchpad support (enabled default in most desktopManager). - # services.xserver.libinput.enable = true; + # services.libinput.enable = true; # Define a user account. Don't forget to set a password with ‘passwd’. # users.users.alice = { diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 511d991e919cd..111b5c129cb3c 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -325,6 +325,7 @@ ./security/duosec.nix ./security/google_oslogin.nix ./security/ipa.nix + ./security/isolate.nix ./security/krb5 ./security/lock-kernel-modules.nix ./security/misc.nix @@ -558,8 +559,9 @@ ./services/hardware/joycond.nix ./services/hardware/kanata.nix ./services/hardware/lcd.nix + ./services/hardware/libinput.nix ./services/hardware/lirc.nix - ./services/hardware/nvidia-container-toolkit-cdi-generator + ./services/hardware/nvidia-container-toolkit ./services/hardware/monado.nix ./services/hardware/nvidia-optimus.nix ./services/hardware/openrgb.nix @@ -944,6 +946,7 @@ ./services/networking/charybdis.nix ./services/networking/chisel-server.nix ./services/networking/cjdns.nix + ./services/networking/clatd.nix ./services/networking/cloudflare-dyndns.nix ./services/networking/cloudflared.nix ./services/networking/cntlm.nix @@ -1027,6 +1030,7 @@ ./services/networking/jigasi.nix ./services/networking/jitsi-videobridge.nix ./services/networking/jool.nix + ./services/networking/jotta-cli.nix ./services/networking/kea.nix ./services/networking/keepalived/default.nix ./services/networking/keybase.nix @@ -1254,8 +1258,8 @@ ./services/security/kanidm.nix ./services/security/munge.nix ./services/security/nginx-sso.nix - ./services/security/oauth2_proxy.nix - ./services/security/oauth2_proxy_nginx.nix + ./services/security/oauth2-proxy.nix + ./services/security/oauth2-proxy-nginx.nix ./services/security/opensnitch.nix ./services/security/pass-secret-service.nix ./services/security/physlock.nix @@ -1472,7 +1476,6 @@ ./services/x11/gdk-pixbuf.nix ./services/x11/hardware/cmt.nix ./services/x11/hardware/digimend.nix - ./services/x11/hardware/libinput.nix ./services/x11/hardware/synaptics.nix ./services/x11/hardware/wacom.nix ./services/x11/imwheel.nix diff --git a/nixos/modules/profiles/graphical.nix b/nixos/modules/profiles/graphical.nix index 8cc31652f8075..72b865c584f07 100644 --- a/nixos/modules/profiles/graphical.nix +++ b/nixos/modules/profiles/graphical.nix @@ -7,10 +7,12 @@ services.xserver = { enable = true; desktopManager.plasma5.enable = true; - libinput.enable = true; # for touchpad support on many laptops }; - services.displayManager.sddm.enable = true; + services = { + displayManager.sddm.enable = true; + libinput.enable = true; # for touchpad support on many laptops + }; # Enable sound in virtualbox appliances. hardware.pulseaudio.enable = true; diff --git a/nixos/modules/programs/evince.nix b/nixos/modules/programs/evince.nix index cffc5127f10a8..a27e75e6626de 100644 --- a/nixos/modules/programs/evince.nix +++ b/nixos/modules/programs/evince.nix @@ -2,28 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.programs.evince; in { - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "evince" "enable" ] - [ "programs" "evince" "enable" ]) - ]; - ###### interface options = { programs.evince = { - enable = mkEnableOption "Evince, the GNOME document viewer"; + enable = lib.mkEnableOption "Evince, the GNOME document viewer"; - package = mkPackageOption pkgs "evince" { }; + package = lib.mkPackageOption pkgs "evince" { }; }; @@ -32,7 +23,7 @@ in { ###### implementation - config = mkIf config.programs.evince.enable { + config = lib.mkIf config.programs.evince.enable { environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/programs/file-roller.nix b/nixos/modules/programs/file-roller.nix index 4799f42d630b1..f64bd732855bf 100644 --- a/nixos/modules/programs/file-roller.nix +++ b/nixos/modules/programs/file-roller.nix @@ -2,28 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.programs.file-roller; in { - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "file-roller" "enable" ] - [ "programs" "file-roller" "enable" ]) - ]; - ###### interface options = { programs.file-roller = { - enable = mkEnableOption "File Roller, an archive manager for GNOME"; + enable = lib.mkEnableOption "File Roller, an archive manager for GNOME"; - package = mkPackageOption pkgs [ "gnome" "file-roller" ] { }; + package = lib.mkPackageOption pkgs [ "gnome" "file-roller" ] { }; }; @@ -32,7 +23,7 @@ in { ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/programs/gnome-disks.nix b/nixos/modules/programs/gnome-disks.nix index 4b128b4712650..954f1fd9bc078 100644 --- a/nixos/modules/programs/gnome-disks.nix +++ b/nixos/modules/programs/gnome-disks.nix @@ -2,29 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-disks" "enable" ] - [ "programs" "gnome-disks" "enable" ]) - ]; - ###### interface options = { programs.gnome-disks = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Disks daemon, a program designed to @@ -39,7 +30,7 @@ with lib; ###### implementation - config = mkIf config.programs.gnome-disks.enable { + config = lib.mkIf config.programs.gnome-disks.enable { environment.systemPackages = [ pkgs.gnome.gnome-disk-utility ]; diff --git a/nixos/modules/programs/gnome-terminal.nix b/nixos/modules/programs/gnome-terminal.nix index 71a6b217880c5..a5dda83edd11f 100644 --- a/nixos/modules/programs/gnome-terminal.nix +++ b/nixos/modules/programs/gnome-terminal.nix @@ -2,8 +2,6 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.programs.gnome-terminal; @@ -13,21 +11,14 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2019-08-19 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-terminal-server" "enable" ] - [ "programs" "gnome-terminal" "enable" ]) - ]; - options = { - programs.gnome-terminal.enable = mkEnableOption "GNOME Terminal"; + programs.gnome-terminal.enable = lib.mkEnableOption "GNOME Terminal"; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ pkgs.gnome.gnome-terminal ]; services.dbus.packages = [ pkgs.gnome.gnome-terminal ]; systemd.packages = [ pkgs.gnome.gnome-terminal ]; diff --git a/nixos/modules/programs/gpaste.nix b/nixos/modules/programs/gpaste.nix index 1c34c86eb853f..32b81434bdd94 100644 --- a/nixos/modules/programs/gpaste.nix +++ b/nixos/modules/programs/gpaste.nix @@ -1,22 +1,13 @@ # GPaste. { config, lib, pkgs, ... }: -with lib; - { - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gpaste" "enable" ] - [ "programs" "gpaste" "enable" ]) - ]; - ###### interface options = { programs.gpaste = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GPaste, a clipboard manager. @@ -26,7 +17,7 @@ with lib; }; ###### implementation - config = mkIf config.programs.gpaste.enable { + config = lib.mkIf config.programs.gpaste.enable { environment.systemPackages = [ pkgs.gnome.gpaste ]; services.dbus.packages = [ pkgs.gnome.gpaste ]; systemd.packages = [ pkgs.gnome.gpaste ]; diff --git a/nixos/modules/programs/seahorse.nix b/nixos/modules/programs/seahorse.nix index c0a356bff57c1..53fff50e0a8b9 100644 --- a/nixos/modules/programs/seahorse.nix +++ b/nixos/modules/programs/seahorse.nix @@ -2,25 +2,15 @@ { config, pkgs, lib, ... }: -with lib; - { - # Added 2019-08-27 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "seahorse" "enable" ] - [ "programs" "seahorse" "enable" ]) - ]; - - ###### interface options = { programs.seahorse = { - enable = mkEnableOption "Seahorse, a GNOME application for managing encryption keys and passwords in the GNOME Keyring"; + enable = lib.mkEnableOption "Seahorse, a GNOME application for managing encryption keys and passwords in the GNOME Keyring"; }; @@ -29,9 +19,9 @@ with lib; ###### implementation - config = mkIf config.programs.seahorse.enable { + config = lib.mkIf config.programs.seahorse.enable { - programs.ssh.askPassword = mkDefault "${pkgs.gnome.seahorse}/libexec/seahorse/ssh-askpass"; + programs.ssh.askPassword = lib.mkDefault "${pkgs.gnome.seahorse}/libexec/seahorse/ssh-askpass"; environment.systemPackages = [ pkgs.gnome.seahorse diff --git a/nixos/modules/programs/singularity.nix b/nixos/modules/programs/singularity.nix index 981417389eb22..f4c0a6fe487e6 100644 --- a/nixos/modules/programs/singularity.nix +++ b/nixos/modules/programs/singularity.nix @@ -1,4 +1,9 @@ -{ config, pkgs, lib, ... }: +{ + config, + pkgs, + lib, + ... +}: with lib; let @@ -12,9 +17,7 @@ in Whether to install Singularity/Apptainer with system-level overriding such as SUID support. ''; }; - package = mkPackageOption pkgs "singularity" { - example = "apptainer"; - }; + package = mkPackageOption pkgs "singularity" { example = "apptainer"; }; packageOverriden = mkOption { type = types.nullOr types.package; default = null; @@ -75,17 +78,19 @@ in }; config = mkIf cfg.enable { - programs.singularity.packageOverriden = (cfg.package.override ( - optionalAttrs cfg.enableExternalLocalStateDir { - externalLocalStateDir = "/var/lib"; - } // optionalAttrs cfg.enableFakeroot { - newuidmapPath = "/run/wrappers/bin/newuidmap"; - newgidmapPath = "/run/wrappers/bin/newgidmap"; - } // optionalAttrs cfg.enableSuid { - enableSuid = true; - starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid"; - } - )); + programs.singularity.packageOverriden = ( + cfg.package.override ( + optionalAttrs cfg.enableExternalLocalStateDir { externalLocalStateDir = "/var/lib"; } + // optionalAttrs cfg.enableFakeroot { + newuidmapPath = "/run/wrappers/bin/newuidmap"; + newgidmapPath = "/run/wrappers/bin/newgidmap"; + } + // optionalAttrs cfg.enableSuid { + enableSuid = true; + starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid"; + } + ) + ); environment.systemPackages = [ cfg.packageOverriden ]; security.wrappers."${cfg.packageOverriden.projectName}-suid" = mkIf cfg.enableSuid { setuid = true; @@ -97,5 +102,4 @@ in "d /var/lib/${cfg.packageOverriden.projectName}/mnt/session 0770 root root -" ]; }; - } diff --git a/nixos/modules/programs/wayland/hyprland.nix b/nixos/modules/programs/wayland/hyprland.nix index 5891ff25e4375..e648eaa1b68e4 100644 --- a/nixos/modules/programs/wayland/hyprland.nix +++ b/nixos/modules/programs/wayland/hyprland.nix @@ -42,6 +42,15 @@ in xwayland.enable = mkEnableOption ("XWayland") // { default = true; }; + envVars.enable = mkEnableOption null // { + default = true; + example = false; + description = '' + Set environment variables for Hyprland to work properly. + Enabled by default. + ''; + }; + systemd.setPath.enable = mkEnableOption null // { default = true; example = false; @@ -74,6 +83,15 @@ in configPackages = mkDefault [ cfg.finalPackage ]; }; + environment.sessionVariables = mkIf cfg.envVars.enable { + XDG_CURRENT_DESKTOP = "Hyprland"; + XDG_SESSION_DESKTOP = "Hyprland"; + XDG_SESSION_TYPE = "wayland"; + GDK_BACKEND = "wayland,x11"; + QT_QPA_PLATFORM = "wayland;xcb"; + _JAVA_AWT_WM_NONREPARENTING = "1"; # Fix for Java applications on tiling window managers + }; + systemd = mkIf cfg.systemd.setPath.enable { user.extraConfig = '' DefaultEnvironment="PATH=$PATH:/run/current-system/sw/bin:/etc/profiles/per-user/%u/bin:/run/wrappers/bin" diff --git a/nixos/modules/programs/wshowkeys.nix b/nixos/modules/programs/wshowkeys.nix index f7b71d2bb0c89..1fef33e047175 100644 --- a/nixos/modules/programs/wshowkeys.nix +++ b/nixos/modules/programs/wshowkeys.nix @@ -1,27 +1,31 @@ -{ config, lib, pkgs, ... }: - -with lib; - +{ + config, + lib, + pkgs, + ... +}: let cfg = config.programs.wshowkeys; -in { - meta.maintainers = with maintainers; [ primeos ]; - +in +{ options = { programs.wshowkeys = { - enable = mkEnableOption '' + enable = lib.mkEnableOption '' wshowkeys (displays keypresses on screen on supported Wayland compositors). It requires root permissions to read input events, but these permissions are dropped after startup''; + package = lib.mkPackageOption pkgs "wshowkeys" { }; }; }; - config = mkIf cfg.enable { - security.wrappers.wshowkeys = - { setuid = true; - owner = "root"; - group = "root"; - source = "${pkgs.wshowkeys}/bin/wshowkeys"; - }; + config = lib.mkIf cfg.enable { + security.wrappers.wshowkeys = { + setuid = true; + owner = "root"; + group = "root"; + source = lib.getExe cfg.package; + }; }; + + meta.maintainers = with lib.maintainers; [ primeos ]; } diff --git a/nixos/modules/security/isolate.nix b/nixos/modules/security/isolate.nix new file mode 100644 index 0000000000000..3cc0176f3db30 --- /dev/null +++ b/nixos/modules/security/isolate.nix @@ -0,0 +1,133 @@ +{ config, lib, pkgs, ... }: + +let + inherit (lib) mkEnableOption mkPackageOption mkOption types mkIf maintainers; + + cfg = config.security.isolate; + configFile = pkgs.writeText "isolate-config.cf" '' + box_root=${cfg.boxRoot} + lock_root=${cfg.lockRoot} + cg_root=${cfg.cgRoot} + first_uid=${toString cfg.firstUid} + first_gid=${toString cfg.firstGid} + num_boxes=${toString cfg.numBoxes} + restricted_init=${if cfg.restrictedInit then "1" else "0"} + ${cfg.extraConfig} + ''; + isolate = pkgs.symlinkJoin { + name = "isolate-wrapped-${pkgs.isolate.version}"; + + paths = [ pkgs.isolate ]; + + nativeBuildInputs = [ pkgs.makeWrapper ]; + + postBuild = '' + wrapProgram $out/bin/isolate \ + --set ISOLATE_CONFIG_FILE ${configFile} + + wrapProgram $out/bin/isolate-cg-keeper \ + --set ISOLATE_CONFIG_FILE ${configFile} + ''; + }; +in +{ + options.security.isolate = { + enable = mkEnableOption '' + Sandbox for securely executing untrusted programs + ''; + + package = mkPackageOption pkgs "isolate-unwrapped" { }; + + boxRoot = mkOption { + type = types.path; + default = "/var/lib/isolate/boxes"; + description = '' + All sandboxes are created under this directory. + To avoid symlink attacks, this directory and all its ancestors + must be writeable only by root. + ''; + }; + + lockRoot = mkOption { + type = types.path; + default = "/run/isolate/locks"; + description = '' + Directory where lock files are created. + ''; + }; + + cgRoot = mkOption { + type = types.str; + default = "auto:/run/isolate/cgroup"; + description = '' + Control group which subgroups are placed under. + Either an explicit path to a subdirectory in cgroupfs, or "auto:file" to read + the path from "file", where it is put by `isolate-cg-helper`. + ''; + }; + + firstUid = mkOption { + type = types.numbers.between 1000 65533; + default = 60000; + description = '' + Start of block of UIDs reserved for sandboxes. + ''; + }; + + firstGid = mkOption { + type = types.numbers.between 1000 65533; + default = 60000; + description = '' + Start of block of GIDs reserved for sandboxes. + ''; + }; + + numBoxes = mkOption { + type = types.numbers.between 1000 65533; + default = 1000; + description = '' + Number of UIDs and GIDs to reserve, starting from + {option}`firstUid` and {option}`firstGid`. + ''; + }; + + restrictedInit = mkOption { + type = types.bool; + default = false; + description = '' + If true, only root can create sandboxes. + ''; + }; + + extraConfig = mkOption { + type = types.str; + default = ""; + description = '' + Extra configuration to append to the configuration file. + ''; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ + isolate + ]; + + systemd.services.isolate = { + description = "Isolate control group hierarchy daemon"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "notify"; + ExecStart = "${isolate}/bin/isolate-cg-keeper"; + Slice = "isolate.slice"; + Delegate = true; + }; + }; + + systemd.slices.isolate = { + description = "Isolate sandbox slice"; + }; + + meta.maintainers = with maintainers; [ virchau13 ]; + }; +} diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index a9bd28b154794..5d3bed2fb02c8 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -1044,9 +1044,7 @@ in See [issue #31611](https://github.com/NixOS/nixpkgs/issues/31611) ::: ''; - example = [ "/etc/ssh/authorized_keys.d/%u" ]; - default = config.services.openssh.authorizedKeysFiles; - defaultText = literalExpression "config.services.openssh.authorizedKeysFiles"; + default = [ "/etc/ssh/authorized_keys.d/%u" ]; }; }; diff --git a/nixos/modules/services/backup/znapzend.nix b/nixos/modules/services/backup/znapzend.nix index 71e5977c44640..7f2c89edbf374 100644 --- a/nixos/modules/services/backup/znapzend.nix +++ b/nixos/modules/services/backup/znapzend.nix @@ -315,6 +315,14 @@ in ''; }; + mailErrorSummaryTo = mkOption { + type = singleLineStr; + default = ""; + description = '' + Email address to send a summary to if "send task(s) failed". + ''; + }; + noDestroy = mkOption { type = bool; default = false; @@ -455,6 +463,8 @@ in "--loglevel=${cfg.logLevel}" (optionalString cfg.noDestroy "--nodestroy") (optionalString cfg.autoCreation "--autoCreation") + (optionalString (cfg.mailErrorSummaryTo != "") + "--mailErrorSummaryTo=${cfg.mailErrorSummaryTo}") (optionalString (enabledFeatures != []) "--features=${concatStringsSep "," enabledFeatures}") ]; in "${pkgs.znapzend}/bin/znapzend ${args}"; diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index 8a386b4848b91..8a9d8c210b34d 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -1,8 +1,31 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) + attrValues + concatMapStrings + concatStringsSep + const + elem + filterAttrs + isString + literalExpression + mapAttrs + mapAttrsToList + mkAfter + mkBefore + mkDefault + mkEnableOption + mkIf + mkMerge + mkOption + mkPackageOption + mkRemovedOptionModule + mkRenamedOptionModule + optionalString + types + versionAtLeast + ; cfg = config.services.postgresql; @@ -14,7 +37,7 @@ let # package = pkgs.postgresql_<major>; # }; # works. - base = if cfg.enableJIT then cfg.package.withJIT else cfg.package; + base = if cfg.enableJIT then cfg.package.withJIT else cfg.package.withoutJIT; in if cfg.extraPlugins == [] then base @@ -24,7 +47,7 @@ let if true == value then "yes" else if false == value then "no" else if isString value then "'${lib.replaceStrings ["'"] ["''"] value}'" - else toString value; + else builtins.toString value; # The main PostgreSQL configuration file. configFile = pkgs.writeTextDir "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") (filterAttrs (const (x: x != null)) cfg.settings))); @@ -439,7 +462,7 @@ in config = mkIf cfg.enable { assertions = map ({ name, ensureDBOwnership, ... }: { - assertion = ensureDBOwnership -> builtins.elem name cfg.ensureDatabases; + assertion = ensureDBOwnership -> elem name cfg.ensureDatabases; message = '' For each database user defined with `services.postgresql.ensureUsers` and `ensureDBOwnership = true;`, a database with the same name must be defined @@ -537,7 +560,7 @@ in # Wait for PostgreSQL to be ready to accept connections. postStart = '' - PSQL="psql --port=${toString cfg.settings.port}" + PSQL="psql --port=${builtins.toString cfg.settings.port}" while ! $PSQL -d postgres -c "" 2> /dev/null; do if ! kill -0 "$MAINPID"; then exit 1; fi diff --git a/nixos/modules/services/databases/redis.nix b/nixos/modules/services/databases/redis.nix index 1da2fa9f11604..ad88a4f589a20 100644 --- a/nixos/modules/services/databases/redis.nix +++ b/nixos/modules/services/databases/redis.nix @@ -57,9 +57,9 @@ in { package = mkPackageOption pkgs "redis" { }; vmOverCommit = mkEnableOption '' - setting of vm.overcommit_memory to 1 + set `vm.overcommit_memory` sysctl to 1 (Suggested for Background Saving: <https://redis.io/docs/get-started/faq/>) - ''; + '' // { default = true; }; servers = mkOption { type = with types; attrsOf (submodule ({ config, name, ... }: { @@ -312,10 +312,9 @@ in { ''; }) enabledServers); - boot.kernel.sysctl = mkMerge [ - { "vm.nr_hugepages" = "0"; } - ( mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; } ) - ]; + boot.kernel.sysctl = mkIf cfg.vmOverCommit { + "vm.overcommit_memory" = "1"; + }; networking.firewall.allowedTCPPorts = concatMap (conf: optional conf.openFirewall conf.port diff --git a/nixos/modules/services/desktop-managers/plasma6.nix b/nixos/modules/services/desktop-managers/plasma6.nix index 856d36b8a3030..08507b4d370a7 100644 --- a/nixos/modules/services/desktop-managers/plasma6.nix +++ b/nixos/modules/services/desktop-managers/plasma6.nix @@ -238,7 +238,7 @@ in { services.system-config-printer.enable = mkIf config.services.printing.enable (mkDefault true); services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; # Extra UDEV rules used by Solid services.udev.packages = [ diff --git a/nixos/modules/services/desktops/gnome/at-spi2-core.nix b/nixos/modules/services/desktops/gnome/at-spi2-core.nix index 446f363fce83f..6ed5b198fe4f8 100644 --- a/nixos/modules/services/desktops/gnome/at-spi2-core.nix +++ b/nixos/modules/services/desktops/gnome/at-spi2-core.nix @@ -2,30 +2,19 @@ { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; ###### interface - - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "at-spi2-core" "enable" ] - [ "services" "gnome" "at-spi2-core" "enable" ] - ) - ]; - options = { services.gnome.at-spi2-core = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable at-spi2-core, a service for the Assistive Technologies @@ -43,14 +32,14 @@ with lib; ###### implementation - config = mkMerge [ - (mkIf config.services.gnome.at-spi2-core.enable { + config = lib.mkMerge [ + (lib.mkIf config.services.gnome.at-spi2-core.enable { environment.systemPackages = [ pkgs.at-spi2-core ]; services.dbus.packages = [ pkgs.at-spi2-core ]; systemd.packages = [ pkgs.at-spi2-core ]; }) - (mkIf (!config.services.gnome.at-spi2-core.enable) { + (lib.mkIf (!config.services.gnome.at-spi2-core.enable) { environment.sessionVariables = { NO_AT_BRIDGE = "1"; GTK_A11Y = "none"; diff --git a/nixos/modules/services/desktops/gnome/evolution-data-server.nix b/nixos/modules/services/desktops/gnome/evolution-data-server.nix index 34a91170d424f..a43e8dadb4212 100644 --- a/nixos/modules/services/desktops/gnome/evolution-data-server.nix +++ b/nixos/modules/services/desktops/gnome/evolution-data-server.nix @@ -2,44 +2,30 @@ { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "evolution-data-server" "enable" ] - [ "services" "gnome" "evolution-data-server" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "gnome3" "evolution-data-server" "plugins" ] - [ "services" "gnome" "evolution-data-server" "plugins" ] - ) - ]; - ###### interface options = { services.gnome.evolution-data-server = { - enable = mkEnableOption "Evolution Data Server, a collection of services for storing addressbooks and calendars"; - plugins = mkOption { - type = types.listOf types.package; + enable = lib.mkEnableOption "Evolution Data Server, a collection of services for storing addressbooks and calendars"; + plugins = lib.mkOption { + type = lib.types.listOf lib.types.package; default = [ ]; description = "Plugins for Evolution Data Server."; }; }; programs.evolution = { - enable = mkEnableOption "Evolution, a Personal information management application that provides integrated mail, calendaring and address book functionality"; - plugins = mkOption { - type = types.listOf types.package; + enable = lib.mkEnableOption "Evolution, a Personal information management application that provides integrated mail, calendaring and address book functionality"; + plugins = lib.mkOption { + type = lib.types.listOf lib.types.package; default = [ ]; - example = literalExpression "[ pkgs.evolution-ews ]"; + example = lib.literalExpression "[ pkgs.evolution-ews ]"; description = "Plugins for Evolution."; }; @@ -52,15 +38,15 @@ with lib; let bundle = pkgs.evolutionWithPlugins.override { inherit (config.services.gnome.evolution-data-server) plugins; }; in - mkMerge [ - (mkIf config.services.gnome.evolution-data-server.enable { + lib.mkMerge [ + (lib.mkIf config.services.gnome.evolution-data-server.enable { environment.systemPackages = [ bundle ]; services.dbus.packages = [ bundle ]; systemd.packages = [ bundle ]; }) - (mkIf config.programs.evolution.enable { + (lib.mkIf config.programs.evolution.enable { services.gnome.evolution-data-server = { enable = true; plugins = [ pkgs.evolution ] ++ config.programs.evolution.plugins; diff --git a/nixos/modules/services/desktops/gnome/glib-networking.nix b/nixos/modules/services/desktops/gnome/glib-networking.nix index 1039605391ab6..905901f470841 100644 --- a/nixos/modules/services/desktops/gnome/glib-networking.nix +++ b/nixos/modules/services/desktops/gnome/glib-networking.nix @@ -2,29 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "glib-networking" "enable" ] - [ "services" "gnome" "glib-networking" "enable" ] - ) - ]; - ###### interface options = { services.gnome.glib-networking = { - enable = mkEnableOption "network extensions for GLib"; + enable = lib.mkEnableOption "network extensions for GLib"; }; @@ -32,7 +22,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.glib-networking.enable { + config = lib.mkIf config.services.gnome.glib-networking.enable { services.dbus.packages = [ pkgs.glib-networking ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix index 34fc24f7d5746..4f0c36883a3f5 100644 --- a/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix +++ b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix @@ -9,19 +9,6 @@ in maintainers = teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "chrome-gnome-shell" "enable" ] - [ "services" "gnome" "gnome-browser-connector" "enable" ] - ) - # Added 2022-07-25 - (mkRenamedOptionModule - [ "services" "gnome" "chrome-gnome-shell" "enable" ] - [ "services" "gnome" "gnome-browser-connector" "enable" ] - ) - ]; - options = { services.gnome.gnome-browser-connector.enable = mkEnableOption '' native host connector for the GNOME Shell browser extension, a DBus service diff --git a/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix b/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix index ceda49337472f..8deb12ec18bf3 100644 --- a/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix +++ b/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix @@ -2,8 +2,6 @@ { config, pkgs, lib, ... }: -with lib; - let # GNOME initial setup's run is conditioned on whether @@ -45,24 +43,16 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-initial-setup" "enable" ] - [ "services" "gnome" "gnome-initial-setup" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-initial-setup = { - enable = mkEnableOption "GNOME Initial Setup, a Simple, easy, and safe way to prepare a new system"; + enable = lib.mkEnableOption "GNOME Initial Setup, a Simple, easy, and safe way to prepare a new system"; }; @@ -71,12 +61,12 @@ in ###### implementation - config = mkIf config.services.gnome.gnome-initial-setup.enable { + config = lib.mkIf config.services.gnome.gnome-initial-setup.enable { environment.systemPackages = [ pkgs.gnome.gnome-initial-setup ] - ++ optional (versionOlder config.system.stateVersion "20.03") createGisStampFilesAutostart + ++ lib.optional (lib.versionOlder config.system.stateVersion "20.03") createGisStampFilesAutostart ; systemd.packages = [ diff --git a/nixos/modules/services/desktops/gnome/gnome-keyring.nix b/nixos/modules/services/desktops/gnome/gnome-keyring.nix index d821da164beb1..79bce0ade2fc5 100644 --- a/nixos/modules/services/desktops/gnome/gnome-keyring.nix +++ b/nixos/modules/services/desktops/gnome/gnome-keyring.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-keyring" "enable" ] - [ "services" "gnome" "gnome-keyring" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-keyring = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Keyring daemon, a service designed to @@ -41,7 +31,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-keyring.enable { + config = lib.mkIf config.services.gnome.gnome-keyring.enable { environment.systemPackages = [ pkgs.gnome.gnome-keyring ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix b/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix index 01f7e3695cf04..de3c3789594a8 100644 --- a/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix +++ b/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-online-accounts" "enable" ] - [ "services" "gnome" "gnome-online-accounts" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-online-accounts = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Online Accounts daemon, a service that provides @@ -40,7 +30,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-online-accounts.enable { + config = lib.mkIf config.services.gnome.gnome-online-accounts.enable { environment.systemPackages = [ pkgs.gnome-online-accounts ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-online-miners.nix b/nixos/modules/services/desktops/gnome/gnome-online-miners.nix index 5f9039f68c4ee..9496752ed3a24 100644 --- a/nixos/modules/services/desktops/gnome/gnome-online-miners.nix +++ b/nixos/modules/services/desktops/gnome/gnome-online-miners.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-online-miners" "enable" ] - [ "services" "gnome" "gnome-online-miners" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-online-miners = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Online Miners, a service that @@ -40,7 +30,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-online-miners.enable { + config = lib.mkIf config.services.gnome.gnome-online-miners.enable { environment.systemPackages = [ pkgs.gnome.gnome-online-miners ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix b/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix index b5573d2fc21bc..d81a9edfa1266 100644 --- a/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix +++ b/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix @@ -1,32 +1,36 @@ # Remote desktop daemon using Pipewire. { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-remote-desktop" "enable" ] - [ "services" "gnome" "gnome-remote-desktop" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-remote-desktop = { - enable = mkEnableOption "Remote Desktop support using Pipewire"; + enable = lib.mkEnableOption "Remote Desktop support using Pipewire"; }; }; ###### implementation - config = mkIf config.services.gnome.gnome-remote-desktop.enable { + config = lib.mkIf config.services.gnome.gnome-remote-desktop.enable { services.pipewire.enable = true; + services.dbus.packages = [ pkgs.gnome.gnome-remote-desktop ]; + + environment.systemPackages = [ pkgs.gnome.gnome-remote-desktop ]; systemd.packages = [ pkgs.gnome.gnome-remote-desktop ]; + systemd.tmpfiles.packages = [ pkgs.gnome.gnome-remote-desktop ]; + + # TODO: if possible, switch to using provided g-r-d sysusers.d + users = { + users.gnome-remote-desktop = { + isSystemUser = true; + group = "gnome-remote-desktop"; + home = "/var/lib/gnome-remote-desktop"; + }; + groups.gnome-remote-desktop = { }; + }; }; } diff --git a/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix b/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix index 9c68c9b76e9ee..30b35f6690921 100644 --- a/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix +++ b/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix @@ -2,8 +2,6 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.services.gnome.gnome-settings-daemon; @@ -13,28 +11,16 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - (mkRemovedOptionModule - ["services" "gnome3" "gnome-settings-daemon" "package"] - "") - - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-settings-daemon" "enable" ] - [ "services" "gnome" "gnome-settings-daemon" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-settings-daemon = { - enable = mkEnableOption "GNOME Settings Daemon"; + enable = lib.mkEnableOption "GNOME Settings Daemon"; }; @@ -43,7 +29,7 @@ in ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ pkgs.gnome.gnome-settings-daemon diff --git a/nixos/modules/services/desktops/gnome/gnome-user-share.nix b/nixos/modules/services/desktops/gnome/gnome-user-share.nix index 38256af309cc5..2c6d94b7bdfc6 100644 --- a/nixos/modules/services/desktops/gnome/gnome-user-share.nix +++ b/nixos/modules/services/desktops/gnome/gnome-user-share.nix @@ -2,29 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-user-share" "enable" ] - [ "services" "gnome" "gnome-user-share" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-user-share = { - enable = mkEnableOption "GNOME User Share, a user-level file sharing service for GNOME"; + enable = lib.mkEnableOption "GNOME User Share, a user-level file sharing service for GNOME"; }; @@ -33,7 +23,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-user-share.enable { + config = lib.mkIf config.services.gnome.gnome-user-share.enable { environment.systemPackages = [ pkgs.gnome.gnome-user-share diff --git a/nixos/modules/services/desktops/gnome/rygel.nix b/nixos/modules/services/desktops/gnome/rygel.nix index 8932d438cf1ec..c980b239d521e 100644 --- a/nixos/modules/services/desktops/gnome/rygel.nix +++ b/nixos/modules/services/desktops/gnome/rygel.nix @@ -1,38 +1,28 @@ # rygel service. { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "rygel" "enable" ] - [ "services" "gnome" "rygel" "enable" ] - ) - ]; - ###### interface options = { services.gnome.rygel = { - enable = mkOption { + enable = lib.mkOption { default = false; description = '' Whether to enable Rygel UPnP Mediaserver. You will need to also allow UPnP connections in firewall, see the following [comment](https://github.com/NixOS/nixpkgs/pull/45045#issuecomment-416030795). ''; - type = types.bool; + type = lib.types.bool; }; }; }; ###### implementation - config = mkIf config.services.gnome.rygel.enable { + config = lib.mkIf config.services.gnome.rygel.enable { environment.systemPackages = [ pkgs.gnome.rygel ]; services.dbus.packages = [ pkgs.gnome.rygel ]; diff --git a/nixos/modules/services/desktops/gnome/sushi.nix b/nixos/modules/services/desktops/gnome/sushi.nix index 3133a3a0d9854..946030e4bb229 100644 --- a/nixos/modules/services/desktops/gnome/sushi.nix +++ b/nixos/modules/services/desktops/gnome/sushi.nix @@ -2,30 +2,20 @@ { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "sushi" "enable" ] - [ "services" "gnome" "sushi" "enable" ] - ) - ]; - ###### interface options = { services.gnome.sushi = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable Sushi, a quick previewer for nautilus. @@ -39,7 +29,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.sushi.enable { + config = lib.mkIf config.services.gnome.sushi.enable { environment.systemPackages = [ pkgs.gnome.sushi ]; diff --git a/nixos/modules/services/desktops/gnome/tracker-miners.nix b/nixos/modules/services/desktops/gnome/tracker-miners.nix index 9351007d30b5d..d5d42cee9f8b4 100644 --- a/nixos/modules/services/desktops/gnome/tracker-miners.nix +++ b/nixos/modules/services/desktops/gnome/tracker-miners.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "tracker-miners" "enable" ] - [ "services" "gnome" "tracker-miners" "enable" ] - ) - ]; - ###### interface options = { services.gnome.tracker-miners = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable Tracker miners, indexing services for Tracker @@ -39,7 +29,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.tracker-miners.enable { + config = lib.mkIf config.services.gnome.tracker-miners.enable { environment.systemPackages = [ pkgs.tracker-miners ]; diff --git a/nixos/modules/services/desktops/gnome/tracker.nix b/nixos/modules/services/desktops/gnome/tracker.nix index fef399d0112e4..45b679571c707 100644 --- a/nixos/modules/services/desktops/gnome/tracker.nix +++ b/nixos/modules/services/desktops/gnome/tracker.nix @@ -2,33 +2,23 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.services.gnome.tracker; in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "tracker" "enable" ] - [ "services" "gnome" "tracker" "enable" ] - ) - ]; - ###### interface options = { services.gnome.tracker = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable Tracker services, a search engine, @@ -36,8 +26,8 @@ in ''; }; - subcommandPackages = mkOption { - type = types.listOf types.package; + subcommandPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; default = [ ]; internal = true; description = '' @@ -52,7 +42,7 @@ in ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ pkgs.tracker ]; diff --git a/nixos/modules/services/desktops/gvfs.nix b/nixos/modules/services/desktops/gvfs.nix index 09ac06d9f6fe0..8a02cdd4a6508 100644 --- a/nixos/modules/services/desktops/gvfs.nix +++ b/nixos/modules/services/desktops/gvfs.nix @@ -2,8 +2,6 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.services.gvfs; @@ -13,26 +11,19 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2019-08-19 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gvfs" "enable" ] - [ "services" "gvfs" "enable" ]) - ]; - ###### interface options = { services.gvfs = { - enable = mkEnableOption "GVfs, a userspace virtual filesystem"; + enable = lib.mkEnableOption "GVfs, a userspace virtual filesystem"; # gvfs can be built with multiple configurations - package = mkPackageOption pkgs [ "gnome" "gvfs" ] { }; + package = lib.mkPackageOption pkgs [ "gnome" "gvfs" ] { }; }; @@ -41,7 +32,7 @@ in ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/services/desktops/pipewire/wireplumber.nix b/nixos/modules/services/desktops/pipewire/wireplumber.nix index 6ab62eb03c25f..c924801bcd8ba 100644 --- a/nixos/modules/services/desktops/pipewire/wireplumber.nix +++ b/nixos/modules/services/desktops/pipewire/wireplumber.nix @@ -1,18 +1,40 @@ { config, lib, pkgs, ... }: let - inherit (builtins) attrNames concatMap length; + inherit (builtins) concatMap; inherit (lib) maintainers; - inherit (lib.attrsets) attrByPath filterAttrs; + inherit (lib.attrsets) attrByPath mapAttrsToList; inherit (lib.lists) flatten optional; inherit (lib.modules) mkIf; inherit (lib.options) literalExpression mkOption; - inherit (lib.strings) hasPrefix; - inherit (lib.types) bool listOf package; + inherit (lib.strings) concatStringsSep makeSearchPath; + inherit (lib.types) bool listOf attrsOf package lines; + inherit (lib.path) subpath; pwCfg = config.services.pipewire; cfg = pwCfg.wireplumber; pwUsedForAudio = pwCfg.audio.enable; + + json = pkgs.formats.json { }; + + configSectionsToConfFile = path: value: + pkgs.writeTextDir + path + (concatStringsSep "\n" ( + mapAttrsToList + (section: content: "${section} = " + (builtins.toJSON content)) + value + )); + + mapConfigToFiles = config: + mapAttrsToList + (name: value: configSectionsToConfFile "share/wireplumber/wireplumber.conf.d/${name}.conf" value) + config; + + mapScriptsToFiles = scripts: + mapAttrsToList + (relativePath: value: pkgs.writeTextDir (subpath.join ["share/wireplumber/scripts" relativePath]) value) + scripts; in { meta.maintainers = [ maintainers.k900 ]; @@ -33,6 +55,114 @@ in description = "The WirePlumber derivation to use."; }; + extraConfig = mkOption { + # Two layer attrset is necessary before using JSON, because of the whole + # config file not being a JSON object, but a concatenation of JSON objects + # in sections. + type = attrsOf (attrsOf json.type); + default = { }; + example = literalExpression ''{ + "log-level-debug" = { + "context.properties" = { + # Output Debug log messages as opposed to only the default level (Notice) + "log.level" = "D"; + }; + }; + "wh-1000xm3-ldac-hq" = { + "monitor.bluez.rules" = [ + { + matches = [ + { + # Match any bluetooth device with ids equal to that of a WH-1000XM3 + "device.name" = "~bluez_card.*"; + "device.product.id" = "0x0cd3"; + "device.vendor.id" = "usb:054c"; + } + ]; + actions = { + update-props = { + # Set quality to high quality instead of the default of auto + "bluez5.a2dp.ldac.quality" = "hq"; + }; + }; + } + ]; + }; + }''; + description = '' + Additional configuration for the WirePlumber daemon when run in + single-instance mode (the default in nixpkgs and currently the only + supported way to run WirePlumber configured via `extraConfig`). + + See also: + - [The configuration file][docs-the-conf-file] + - [Modifying configuration][docs-modifying-config] + - [Locations of files][docs-file-locations] + - and the [configuration section][docs-config-section] of the docs in general + + Note that WirePlumber (and PipeWire) use dotted attribute names like + `device.product.id`. These are not nested, but flat objects for WirePlumber/PipeWire, + so to write these in nix expressions, remember to quote them like `"device.product.id"`. + Have a look at the example for this. + + [docs-the-conf-file]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/conf_file.html + [docs-modifying-config]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/modifying_configuration.html + [docs-file-locations]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/locations.html + [docs-config-section]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration.html + ''; + }; + + extraScripts = mkOption { + type = attrsOf lines; + default = { }; + example = { + "test/hello-world.lua" = '' + print("Hello, world!") + ''; + }; + description = '' + Additional scripts for WirePlumber to be used by configuration files. + + Every item in this attrset becomes a separate lua file with the path + relative to the `scripts` directory specified in the name of the item. + The scripts get passed to the WirePlumber service via the `XDG_DATA_DIRS` + variable. Scripts specified here are preferred over those shipped with + WirePlumber if they occupy the same relative path. + + For a script to be loaded, it needs to be specified as part of a component, + and that component needs to be required by an active profile (e.g. `main`). + Components can be defined in config files either via `extraConfig` or `configPackages`. + + For the hello-world example, you'd have to add the following `extraConfig`: + ```nix + services.pipewire.wireplumber.extraConfig."99-hello-world" = { + "wireplumber.components" = [ + { + name = "test/hello-world.lua"; + type = "script/lua"; + provides = "custom.hello-world"; + } + ]; + + "wireplumber.profiles" = { + main = { + "custom.hello-world" = "required"; + }; + }; + }; + ``` + + See also: + - [Location of scripts][docs-file-locations-scripts] + - [Components & Profiles][docs-components-profiles] + - [Migration - Loading custom scripts][docs-migration-loading-custom-scripts] + + [docs-file-locations-scripts]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/locations.html#location-of-scripts + [docs-components-profiles]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/components_and_profiles.html + [docs-migration-loading-custom-scripts]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/migration.html#loading-custom-scripts + ''; + }; + configPackages = mkOption { type = listOf package; default = [ ]; @@ -57,7 +187,7 @@ in extraLv2Packages = mkOption { type = listOf package; - default = []; + default = [ ]; example = literalExpression "[ pkgs.lsp-plugins ]"; description = '' List of packages that provide LV2 plugins in `lib/lv2` that should @@ -96,9 +226,22 @@ in } ''; + extraConfigPkg = pkgs.buildEnv { + name = "wireplumber-extra-config"; + paths = mapConfigToFiles cfg.extraConfig; + pathsToLink = [ "/share/wireplumber/wireplumber.conf.d" ]; + }; + + extraScriptsPkg = pkgs.buildEnv { + name = "wireplumber-extra-scrips"; + paths = mapScriptsToFiles cfg.extraScripts; + pathsToLink = [ "/share/wireplumber/scripts" ]; + }; + configPackages = cfg.configPackages - ++ optional (!pwUsedForAudio) pwNotForAudioConfigPkg - ++ optional pwCfg.systemWide systemwideConfigPkg; + ++ [ extraConfigPkg extraScriptsPkg ] + ++ optional (!pwUsedForAudio) pwNotForAudioConfigPkg + ++ optional pwCfg.systemWide systemwideConfigPkg; configs = pkgs.buildEnv { name = "wireplumber-configs"; @@ -110,7 +253,7 @@ in ( concatMap (p: - attrByPath ["passthru" "requiredLv2Packages"] [] p + attrByPath [ "passthru" "requiredLv2Packages" ] [ ] p ) configPackages ); @@ -127,24 +270,10 @@ in assertion = !config.hardware.bluetooth.hsphfpd.enable; message = "Using WirePlumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false"; } - { - assertion = length - (attrNames - ( - filterAttrs - (name: value: - hasPrefix "wireplumber/" name || name == "wireplumber" - ) - config.environment.etc - )) == 1; - message = "Using `environment.etc.\"wireplumber<...>\"` directly is no longer supported in 24.05. Use `services.pipewire.wireplumber.configPackages` instead."; - } ]; environment.systemPackages = [ cfg.package ]; - environment.etc.wireplumber.source = "${configs}/share/wireplumber"; - systemd.packages = [ cfg.package ]; systemd.services.wireplumber.enable = pwCfg.systemWide; @@ -156,10 +285,16 @@ in systemd.services.wireplumber.environment = mkIf pwCfg.systemWide { # Force WirePlumber to use system dbus. DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket"; + + # Make WirePlumber find our config/script files and lv2 plugins required by those + # (but also the configs/scripts shipped with WirePlumber) + XDG_DATA_DIRS = makeSearchPath "share" [ configs cfg.package ]; LV2_PATH = "${lv2Plugins}/lib/lv2"; }; - systemd.user.services.wireplumber.environment.LV2_PATH = - mkIf (!pwCfg.systemWide) "${lv2Plugins}/lib/lv2"; + systemd.user.services.wireplumber.environment = mkIf (!pwCfg.systemWide) { + XDG_DATA_DIRS = makeSearchPath "share" [ configs cfg.package ]; + LV2_PATH = "${lv2Plugins}/lib/lv2"; + }; }; } diff --git a/nixos/modules/services/display-managers/default.nix b/nixos/modules/services/display-managers/default.nix index de3feb500f33b..005ae8f1c8a58 100644 --- a/nixos/modules/services/display-managers/default.nix +++ b/nixos/modules/services/display-managers/default.nix @@ -29,12 +29,6 @@ let fi '') cfg.sessionPackages} ''; - - dmDefault = config.services.xserver.desktopManager.default; - # fallback default for cases when only default wm is set - dmFallbackDefault = if dmDefault != null then dmDefault else "none"; - wmDefault = config.services.xserver.windowManager.default; - defaultSessionFromLegacyOptions = dmFallbackDefault + lib.optionalString (wmDefault != null && wmDefault != "none") "+${wmDefault}"; in { options = { @@ -125,14 +119,7 @@ in ${lib.concatStringsSep "\n " cfg.displayManager.sessionData.sessionNames} ''; }; - default = - if dmDefault != null || wmDefault != null then - defaultSessionFromLegacyOptions - else - null; - defaultText = lib.literalMD '' - Taken from display manager settings or window manager settings, if either is set. - ''; + default = null; example = "gnome"; description = '' Graphical session to pre-select in the session chooser (only effective for GDM, LightDM and SDDM). @@ -192,20 +179,6 @@ in } ]; - warnings = - lib.mkIf (dmDefault != null || wmDefault != null) [ - '' - The following options are deprecated: - ${lib.concatStringsSep "\n " (map ({c, t}: t) (lib.filter ({c, t}: c != null) [ - { c = dmDefault; t = "- services.xserver.desktopManager.default"; } - { c = wmDefault; t = "- services.xserver.windowManager.default"; } - ]))} - Please use - services.displayManager.defaultSession = "${defaultSessionFromLegacyOptions}"; - instead. - '' - ]; - # Make xsessions and wayland sessions available in XDG_DATA_DIRS # as some programs have behavior that depends on them being present environment.sessionVariables.XDG_DATA_DIRS = lib.mkIf (cfg.sessionPackages != [ ]) [ diff --git a/nixos/modules/services/display-managers/sddm.nix b/nixos/modules/services/display-managers/sddm.nix index aaf1f0dcfc65d..a6bfa213fe380 100644 --- a/nixos/modules/services/display-managers/sddm.nix +++ b/nixos/modules/services/display-managers/sddm.nix @@ -111,8 +111,8 @@ let let westonIni = (pkgs.formats.ini { }).generate "weston.ini" { libinput = { - enable-tap = xcfg.libinput.mouse.tapping; - left-handed = xcfg.libinput.mouse.leftHanded; + enable-tap = config.services.libinput.mouse.tapping; + left-handed = config.services.libinput.mouse.leftHanded; }; keyboard = { keymap_model = xcfg.xkb.model; diff --git a/nixos/modules/services/editors/emacs.md b/nixos/modules/services/editors/emacs.md index 885f927422bdc..da10286751554 100644 --- a/nixos/modules/services/editors/emacs.md +++ b/nixos/modules/services/editors/emacs.md @@ -366,44 +366,3 @@ convenient if you regularly edit Nix files. You can use `woman` to get completion of all available man pages. For example, type `M-x woman <RET> nixos-rebuild <RET>.` -### Editing DocBook 5 XML Documents {#sec-emacs-docbook-xml} - -Emacs includes -[nXML](https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html), -a major-mode for validating and editing XML documents. When editing DocBook -5.0 documents, such as [this one](#book-nixos-manual), -nXML needs to be configured with the relevant schema, which is not -included. - -To install the DocBook 5.0 schemas, either add -{var}`pkgs.docbook5` to [](#opt-environment.systemPackages) -([NixOS](#sec-declarative-package-mgmt)), or run -`nix-env -f '<nixpkgs>' -iA docbook5` -([Nix](#sec-ad-hoc-packages)). - -Then customize the variable {var}`rng-schema-locating-files` to -include {file}`~/.emacs.d/schemas.xml` and put the following -text into that file: -::: {.example #ex-emacs-docbook-xml} -### nXML Schema Configuration (`~/.emacs.d/schemas.xml`) - -```xml -<?xml version="1.0"?> -<!-- - To let emacs find this file, evaluate: - (add-to-list 'rng-schema-locating-files "~/.emacs.d/schemas.xml") ---> -<locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0"> - <!-- - Use this variation if pkgs.docbook5 is added to environment.systemPackages - --> - <namespace ns="http://docbook.org/ns/docbook" - uri="/run/current-system/sw/share/xml/docbook-5.0/rng/docbookxi.rnc"/> - <!-- - Use this variation if installing schema with "nix-env -iA pkgs.docbook5". - <namespace ns="http://docbook.org/ns/docbook" - uri="../.nix-profile/share/xml/docbook-5.0/rng/docbookxi.rnc"/> - --> -</locatingRules> -``` -::: diff --git a/nixos/modules/services/x11/hardware/libinput.nix b/nixos/modules/services/hardware/libinput.nix index 54ff7d85a0331..b8aa59035d338 100644 --- a/nixos/modules/services/x11/hardware/libinput.nix +++ b/nixos/modules/services/hardware/libinput.nix @@ -2,7 +2,7 @@ with lib; -let cfg = config.services.xserver.libinput; +let cfg = config.services.libinput; xorgBool = v: if v then "on" else "off"; @@ -223,7 +223,7 @@ let cfg = config.services.xserver.libinput; in { imports = - (map (option: mkRenamedOptionModule ([ "services" "xserver" "libinput" option ]) [ "services" "xserver" "libinput" "touchpad" option ]) [ + (map (option: mkRenamedOptionModule ([ "services" "xserver" "libinput" option ]) [ "services" "libinput" "touchpad" option ]) [ "accelProfile" "accelSpeed" "buttonMapping" @@ -242,11 +242,15 @@ in { "transformationMatrix" "disableWhileTyping" "additionalOptions" - ]); + ]) ++ [ + (mkRenamedOptionModule [ "services" "xserver" "libinput" "enable" ] [ "services" "libinput" "enable" ]) + (mkRenamedOptionModule [ "services" "xserver" "libinput" "mouse" ] [ "services" "libinput" "mouse" ]) + (mkRenamedOptionModule [ "services" "xserver" "libinput" "touchpad" ] [ "services" "libinput" "touchpad" ]) + ]; options = { - services.xserver.libinput = { + services.libinput = { enable = mkEnableOption "libinput" // { default = config.services.xserver.enable; defaultText = lib.literalExpression "config.services.xserver.enable"; diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix b/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix deleted file mode 100644 index 1aaa2d07b9bde..0000000000000 --- a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ - addDriverRunpath, - glibc, - jq, - lib, - nvidia-container-toolkit, - nvidia-driver, - runtimeShell, - writeScriptBin, -}: -let - mountOptions = { options = ["ro" "nosuid" "nodev" "bind"]; }; - mounts = [ - # FIXME: Making /usr mounts optional - { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-control"; - containerPath = "/usr/bin/nvidia-cuda-mps-control"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-server"; - containerPath = "/usr/bin/nvidia-cuda-mps-server"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-debugdump"; - containerPath = "/usr/bin/nvidia-debugdump"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-powerd"; - containerPath = "/usr/bin/nvidia-powerd"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-smi"; - containerPath = "/usr/bin/nvidia-smi"; } - { hostPath = lib.getExe' nvidia-container-toolkit "nvidia-ctk"; - containerPath = "/usr/bin/nvidia-ctk"; } - { hostPath = "${lib.getLib glibc}/lib"; - containerPath = "${lib.getLib glibc}/lib"; } - - # FIXME: use closureinfo - { - hostPath = addDriverRunpath.driverLink; - containerPath = addDriverRunpath.driverLink; - } - { hostPath = "${lib.getLib glibc}/lib"; - containerPath = "${lib.getLib glibc}/lib"; } - { hostPath = "${lib.getLib glibc}/lib64"; - containerPath = "${lib.getLib glibc}/lib64"; } - ]; - jqAddMountExpression = ".containerEdits.mounts[.containerEdits.mounts | length] |= . +"; - mountsToJq = lib.concatMap - (mount: - ["${lib.getExe jq} '${jqAddMountExpression} ${builtins.toJSON (mount // mountOptions)}'"]) - mounts; -in -writeScriptBin "nvidia-cdi-generator" -'' -#! ${runtimeShell} - -function cdiGenerate { - ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} cdi generate \ - --format json \ - --ldconfig-path ${lib.getExe' glibc "ldconfig"} \ - --library-search-path ${lib.getLib nvidia-driver}/lib \ - --nvidia-ctk-path ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} -} - -cdiGenerate | \ - ${lib.concatStringsSep " | " mountsToJq} > $RUNTIME_DIRECTORY/nvidia-container-toolkit.json -'' diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix b/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix deleted file mode 100644 index 5aa3c72ee0a06..0000000000000 --- a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - - options = { - - hardware.nvidia-container-toolkit-cdi-generator.enable = lib.mkOption { - default = false; - internal = true; - visible = false; - type = lib.types.bool; - description = '' - Enable dynamic CDI configuration for NVidia devices by running - nvidia-container-toolkit on boot. - ''; - }; - - }; - - config = { - - systemd.services.nvidia-container-toolkit-cdi-generator = lib.mkIf config.hardware.nvidia-container-toolkit-cdi-generator.enable { - description = "Container Device Interface (CDI) for Nvidia generator"; - wantedBy = [ "multi-user.target" ]; - after = [ "systemd-udev-settle.service" ]; - serviceConfig = { - RuntimeDirectory = "cdi"; - RemainAfterExit = true; - ExecStart = - let - script = pkgs.callPackage ./cdi-generate.nix { nvidia-driver = config.hardware.nvidia.package; }; - in - lib.getExe script; - Type = "oneshot"; - }; - }; - - }; - -} diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit/cdi-generate.nix b/nixos/modules/services/hardware/nvidia-container-toolkit/cdi-generate.nix new file mode 100644 index 0000000000000..ca769cc44e5c9 --- /dev/null +++ b/nixos/modules/services/hardware/nvidia-container-toolkit/cdi-generate.nix @@ -0,0 +1,35 @@ +{ + glibc, + jq, + lib, + mounts, + nvidia-container-toolkit, + nvidia-driver, + runtimeShell, + writeScriptBin, +}: let + mkMount = {hostPath, containerPath, mountOptions}: { + inherit hostPath containerPath; + options = mountOptions; + }; + jqAddMountExpression = ".containerEdits.mounts[.containerEdits.mounts | length] |= . +"; + allJqMounts = lib.concatMap + (mount: + ["${lib.getExe jq} '${jqAddMountExpression} ${builtins.toJSON (mkMount mount)}'"]) + mounts; +in +writeScriptBin "nvidia-cdi-generator" +'' +#! ${runtimeShell} + +function cdiGenerate { + ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} cdi generate \ + --format json \ + --ldconfig-path ${lib.getExe' glibc "ldconfig"} \ + --library-search-path ${lib.getLib nvidia-driver}/lib \ + --nvidia-ctk-path ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} +} + +cdiGenerate | \ + ${lib.concatStringsSep " | " allJqMounts} > $RUNTIME_DIRECTORY/nvidia-container-toolkit.json +'' diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix new file mode 100644 index 0000000000000..6c6bc667e6498 --- /dev/null +++ b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix @@ -0,0 +1,127 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + (lib.mkRenamedOptionModule + [ "virtualisation" "containers" "cdi" "dynamic" "nvidia" "enable" ] + [ "hardware" "nvidia-container-toolkit" "enable" ]) + ]; + + options = let + mountType = { + options = { + hostPath = lib.mkOption { + type = lib.types.str; + description = "Host path."; + }; + containerPath = lib.mkOption { + type = lib.types.str; + description = "Container path."; + }; + mountOptions = lib.mkOption { + default = [ "ro" "nosuid" "nodev" "bind" ]; + type = lib.types.listOf lib.types.str; + description = "Mount options."; + }; + }; + }; + in { + + hardware.nvidia-container-toolkit = { + enable = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Enable dynamic CDI configuration for NVidia devices by running + nvidia-container-toolkit on boot. + ''; + }; + + mounts = lib.mkOption { + type = lib.types.listOf (lib.types.submodule mountType); + default = []; + description = "Mounts to be added to every container under the Nvidia CDI profile."; + }; + + mount-nvidia-executables = lib.mkOption { + default = true; + type = lib.types.bool; + description = '' + Mount executables nvidia-smi, nvidia-cuda-mps-control, nvidia-cuda-mps-server, + nvidia-debugdump, nvidia-powerd and nvidia-ctk on containers. + ''; + }; + + mount-nvidia-docker-1-directories = lib.mkOption { + default = true; + type = lib.types.bool; + description = '' + Mount nvidia-docker-1 directories on containers: /usr/local/nvidia/lib and + /usr/local/nvidia/lib64. + ''; + }; + }; + + }; + + config = { + + virtualisation.docker.daemon.settings = lib.mkIf + (config.hardware.nvidia-container-toolkit.enable && + (lib.versionAtLeast config.virtualisation.docker.package.version "25")) { + features.cdi = true; + }; + + hardware.nvidia-container-toolkit.mounts = let + nvidia-driver = config.hardware.nvidia.package; + in (lib.mkMerge [ + [{ hostPath = pkgs.addDriverRunpath.driverLink; + containerPath = pkgs.addDriverRunpath.driverLink; } + { hostPath = "${lib.getLib pkgs.glibc}/lib"; + containerPath = "${lib.getLib pkgs.glibc}/lib"; } + { hostPath = "${lib.getLib pkgs.glibc}/lib64"; + containerPath = "${lib.getLib pkgs.glibc}/lib64"; }] + (lib.mkIf config.hardware.nvidia-container-toolkit.mount-nvidia-executables + [{ hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-control"; + containerPath = "/usr/bin/nvidia-cuda-mps-control"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-server"; + containerPath = "/usr/bin/nvidia-cuda-mps-server"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-debugdump"; + containerPath = "/usr/bin/nvidia-debugdump"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-powerd"; + containerPath = "/usr/bin/nvidia-powerd"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-smi"; + containerPath = "/usr/bin/nvidia-smi"; }]) + # nvidia-docker 1.0 uses /usr/local/nvidia/lib{,64} + # e.g. + # - https://gitlab.com/nvidia/container-images/cuda/-/blob/e3ff10eab3a1424fe394899df0e0f8ca5a410f0f/dist/12.3.1/ubi9/base/Dockerfile#L44 + # - https://github.com/NVIDIA/nvidia-docker/blob/01d2c9436620d7dde4672e414698afe6da4a282f/src/nvidia/volumes.go#L104-L173 + (lib.mkIf config.hardware.nvidia-container-toolkit.mount-nvidia-docker-1-directories + [{ hostPath = "${lib.getLib nvidia-driver}/lib"; + containerPath = "/usr/local/nvidia/lib"; } + { hostPath = "${lib.getLib nvidia-driver}/lib"; + containerPath = "/usr/local/nvidia/lib64"; }]) + ]); + + systemd.services.nvidia-container-toolkit-cdi-generator = lib.mkIf config.hardware.nvidia-container-toolkit.enable { + description = "Container Device Interface (CDI) for Nvidia generator"; + wantedBy = [ "multi-user.target" ]; + after = [ "systemd-udev-settle.service" ]; + serviceConfig = { + RuntimeDirectory = "cdi"; + RemainAfterExit = true; + ExecStart = + let + script = pkgs.callPackage ./cdi-generate.nix { + inherit (config.hardware.nvidia-container-toolkit) mounts; + nvidia-driver = config.hardware.nvidia.package; + }; + in + lib.getExe script; + Type = "oneshot"; + }; + }; + + }; + +} diff --git a/nixos/modules/services/home-automation/ebusd.nix b/nixos/modules/services/home-automation/ebusd.nix index aaf2ca1d775d5..ac9ec06639c13 100644 --- a/nixos/modules/services/home-automation/ebusd.nix +++ b/nixos/modules/services/home-automation/ebusd.nix @@ -4,41 +4,6 @@ with lib; let cfg = config.services.ebusd; - - package = pkgs.ebusd; - - arguments = [ - "${package}/bin/ebusd" - "--foreground" - "--updatecheck=off" - "--device=${cfg.device}" - "--port=${toString cfg.port}" - "--configpath=${cfg.configpath}" - "--scanconfig=${cfg.scanconfig}" - "--log=all:${cfg.logs.all}" - "--log=main:${cfg.logs.main}" - "--log=network:${cfg.logs.network}" - "--log=bus:${cfg.logs.bus}" - "--log=update:${cfg.logs.update}" - "--log=other:${cfg.logs.other}" - ] ++ lib.optionals cfg.readonly [ - "--readonly" - ] ++ lib.optionals cfg.mqtt.enable [ - "--mqtthost=${cfg.mqtt.host}" - "--mqttport=${toString cfg.mqtt.port}" - "--mqttuser=${cfg.mqtt.user}" - "--mqttpass=${cfg.mqtt.password}" - ] ++ lib.optionals cfg.mqtt.home-assistant [ - "--mqttint=${package}/etc/ebusd/mqtt-hassio.cfg" - "--mqttjson" - ] ++ lib.optionals cfg.mqtt.retain [ - "--mqttretain" - ] ++ cfg.extraArguments; - - usesDev = hasPrefix "/" cfg.device; - - command = concatStringsSep " " arguments; - in { meta.maintainers = with maintainers; [ nathan-gs ]; @@ -46,6 +11,8 @@ in options.services.ebusd = { enable = mkEnableOption "ebusd, a daemon for communication with eBUS heating systems"; + package = mkPackageOptionMD pkgs "ebusd" { }; + device = mkOption { type = types.str; default = ""; @@ -57,7 +24,8 @@ in ens:DEVICE for enhanced high speed serial device (only adapter v3 and newer with firmware since 20220731), DEVICE for serial device (normal speed, for all other serial adapters like adapter v2 as well as adapter v3 in non-enhanced mode), or [udp:]IP:PORT for network device. - https://github.com/john30/ebusd/wiki/2.-Run#device-options + + Source: <https://github.com/john30/ebusd/wiki/2.-Run#device-options> ''; }; @@ -81,7 +49,7 @@ in type = types.str; default = "https://cfg.ebusd.eu/"; description = '' - Read CSV config files from PATH (local folder or HTTPS URL) [https://cfg.ebusd.eu/] + Directory to read CSV config files from. This can be a local folder or a URL. ''; }; @@ -95,65 +63,21 @@ in ''; }; - logs = { - main = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - network = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - bus = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - update = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - other = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - all = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - }; + logs = let + # "all" must come first so it can be overridden by more specific areas + areas = [ "all" "main" "network" "bus" "update" "other" ]; + levels = [ "none" "error" "notice" "info" "debug" ]; + in listToAttrs (map (area: nameValuePair area (mkOption { + type = types.enum levels; + default = "notice"; + example = "debug"; + description = '' + Only write log for matching `AREA`s (${concatStringsSep "|" areas}) below or equal to `LEVEL` (${concatStringsSep "|" levels}) + ''; + })) areas); mqtt = { - - enable = mkOption { - type = types.bool; - default = false; - description = '' - Adds support for MQTT - ''; - }; + enable = mkEnableOption "support for MQTT"; host = mkOption { type = types.str; @@ -179,13 +103,7 @@ in ''; }; - retain = mkOption { - type = types.bool; - default = false; - description = '' - Set the retain flag on all topics instead of only selected global ones - ''; - }; + retain = mkEnableOption "set the retain flag on all topics instead of only selected global ones"; user = mkOption { type = types.str; @@ -200,7 +118,6 @@ in The MQTT password. ''; }; - }; extraArguments = mkOption { @@ -210,25 +127,44 @@ in Extra arguments to the ebus daemon ''; }; - }; - config = mkIf (cfg.enable) { - + config = let + usesDev = hasPrefix "/" cfg.device; + in mkIf cfg.enable { systemd.services.ebusd = { description = "EBUSd Service"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - ExecStart = command; + ExecStart = let + args = cli.toGNUCommandLineShell { } (foldr (a: b: a // b) { } [ + { + inherit (cfg) device port configpath scanconfig readonly; + foreground = true; + updatecheck = "off"; + log = mapAttrsToList (name: value: "${name}:${value}") cfg.logs; + mqttretain = cfg.mqtt.retain; + } + (optionalAttrs cfg.mqtt.enable { + mqtthost = cfg.mqtt.host; + mqttport = cfg.mqtt.port; + mqttuser = cfg.mqtt.user; + mqttpass = cfg.mqtt.password; + }) + (optionalAttrs cfg.mqtt.home-assistant { + mqttint = "${cfg.package}/etc/ebusd/mqtt-hassio.cfg"; + mqttjson = true; + }) + ]); + in "${cfg.package}/bin/ebusd ${args} ${escapeShellArgs cfg.extraArguments}"; + DynamicUser = true; Restart = "on-failure"; # Hardening CapabilityBoundingSet = ""; - DeviceAllow = lib.optionals usesDev [ - cfg.device - ] ; + DeviceAllow = optionals usesDev [ cfg.device ]; DevicePolicy = "closed"; LockPersonality = true; MemoryDenyWriteExecute = false; @@ -254,9 +190,7 @@ in RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; - SupplementaryGroups = [ - "dialout" - ]; + SupplementaryGroups = [ "dialout" ]; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service @pkey" @@ -265,6 +199,5 @@ in UMask = "0077"; }; }; - }; } diff --git a/nixos/modules/services/home-automation/evcc.nix b/nixos/modules/services/home-automation/evcc.nix index cf4043c946fa5..a952437b1b56e 100644 --- a/nixos/modules/services/home-automation/evcc.nix +++ b/nixos/modules/services/home-automation/evcc.nix @@ -63,6 +63,7 @@ in DynamicUser = true; LockPersonality = true; MemoryDenyWriteExecute = true; + Restart = "on-failure"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" diff --git a/nixos/modules/services/home-automation/wyoming/faster-whisper.nix b/nixos/modules/services/home-automation/wyoming/faster-whisper.nix index cbff3ab3e617c..d0fca6a41c7b6 100644 --- a/nixos/modules/services/home-automation/wyoming/faster-whisper.nix +++ b/nixos/modules/services/home-automation/wyoming/faster-whisper.nix @@ -119,6 +119,8 @@ in wantedBy = [ "multi-user.target" ]; + # https://github.com/rhasspy/wyoming-faster-whisper/issues/27 + environment."HF_HUB_CACHE" = "/tmp"; serviceConfig = { DynamicUser = true; User = "wyoming-faster-whisper"; diff --git a/nixos/modules/services/logging/logrotate.nix b/nixos/modules/services/logging/logrotate.nix index 3e29828eba2f2..9344277fc1e02 100644 --- a/nixos/modules/services/logging/logrotate.nix +++ b/nixos/modules/services/logging/logrotate.nix @@ -224,7 +224,7 @@ in and users are replaced by dummy users), so tests are complemented by a logrotate-checkconf service that is enabled by default. This extra check can be disabled by disabling it at the systemd level with the - {option}`services.systemd.services.logrotate-checkconf.enable` option. + {option}`systemd.services.logrotate-checkconf.enable` option. Conversely there are still things that might make this check fail incorrectly (e.g. a file path where we don't have access to intermediate directories): diff --git a/nixos/modules/services/logging/promtail.nix b/nixos/modules/services/logging/promtail.nix index a34bc07b6ab2f..9eccd34cef234 100644 --- a/nixos/modules/services/logging/promtail.nix +++ b/nixos/modules/services/logging/promtail.nix @@ -41,6 +41,10 @@ in { wantedBy = [ "multi-user.target" ]; stopIfChanged = false; + preStart = '' + ${lib.getExe pkgs.promtail} -config.file=${prettyJSON cfg.configuration} -check-syntax + ''; + serviceConfig = { Restart = "on-failure"; TimeoutStopSec = 10; diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix index 7e7ca7e4060ec..180c9800d7345 100644 --- a/nixos/modules/services/mail/mailman.nix +++ b/nixos/modules/services/mail/mailman.nix @@ -534,14 +534,11 @@ in { hyperkittyApiKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64) secretKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64) - mailmanWebCfgTmp=$(mktemp) - jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \ + install -m 0440 -o root -g mailman \ + <(jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \ --arg archiver_key "$hyperkittyApiKey" \ - --arg secret_key "$secretKey" \ - >"$mailmanWebCfgTmp" - chown root:mailman "$mailmanWebCfgTmp" - chmod 440 "$mailmanWebCfgTmp" - mv -n "$mailmanWebCfgTmp" "$mailmanWebCfg" + --arg secret_key "$secretKey") \ + "$mailmanWebCfg" fi hyperkittyApiKey="$(jq -r .MAILMAN_ARCHIVER_KEY "$mailmanWebCfg")" diff --git a/nixos/modules/services/mail/roundcube.nix b/nixos/modules/services/mail/roundcube.nix index 4499532ace897..78f627d33e2df 100644 --- a/nixos/modules/services/mail/roundcube.nix +++ b/nixos/modules/services/mail/roundcube.nix @@ -7,7 +7,7 @@ let fpm = config.services.phpfpm.pools.roundcube; localDB = cfg.database.host == "localhost"; user = cfg.database.username; - phpWithPspell = pkgs.php81.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled); + phpWithPspell = pkgs.php83.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled); in { options.services.roundcube = { @@ -247,14 +247,15 @@ in (mkIf (cfg.database.host == "localhost") { requires = [ "postgresql.service" ]; after = [ "postgresql.service" ]; - path = [ config.services.postgresql.package ]; }) { wants = [ "network-online.target" ]; after = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; + + path = [ config.services.postgresql.package ]; script = let - psql = "${lib.optionalString (!localDB) "PGPASSFILE=${cfg.database.passwordFile}"} ${pkgs.postgresql}/bin/psql ${lib.optionalString (!localDB) "-h ${cfg.database.host} -U ${cfg.database.username} "} ${cfg.database.dbname}"; + psql = "${lib.optionalString (!localDB) "PGPASSFILE=${cfg.database.passwordFile}"} psql ${lib.optionalString (!localDB) "-h ${cfg.database.host} -U ${cfg.database.username} "} ${cfg.database.dbname}"; in '' version="$(${psql} -t <<< "select value from system where name = 'roundcube-version';" || true)" diff --git a/nixos/modules/services/matrix/appservice-irc.nix b/nixos/modules/services/matrix/appservice-irc.nix index 90790169142aa..f4539a90f2e60 100644 --- a/nixos/modules/services/matrix/appservice-irc.nix +++ b/nixos/modules/services/matrix/appservice-irc.nix @@ -214,8 +214,9 @@ in { RestrictRealtime = true; PrivateMounts = true; SystemCallFilter = [ - "@system-service @pkey @chown" + "@system-service @pkey" "~@privileged @resources" + "@chown" ]; SystemCallArchitectures = "native"; # AF_UNIX is required to connect to a postgres socket. diff --git a/nixos/modules/services/matrix/conduit.nix b/nixos/modules/services/matrix/conduit.nix index e6685af562c0a..b1d9b04242956 100644 --- a/nixos/modules/services/matrix/conduit.nix +++ b/nixos/modules/services/matrix/conduit.nix @@ -9,7 +9,7 @@ let configFile = format.generate "conduit.toml" cfg.settings; in { - meta.maintainers = with maintainers; [ pstn piegames ]; + meta.maintainers = with maintainers; [ pstn ]; options.services.matrix-conduit = { enable = mkEnableOption "matrix-conduit"; @@ -102,7 +102,7 @@ in default = {}; description = '' Generates the conduit.toml configuration file. Refer to - <https://gitlab.com/famedly/conduit/-/blob/master/conduit-example.toml> + <https://docs.conduit.rs/configuration.html> for details on supported values. Note that database_path can not be edited because the service's reliance on systemd StateDir. ''; diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix index e76ba0efd4283..a8526688b074f 100644 --- a/nixos/modules/services/misc/gitea.nix +++ b/nixos/modules/services/misc/gitea.nix @@ -722,5 +722,5 @@ in timerConfig.OnCalendar = cfg.dump.interval; }; }; - meta.maintainers = with lib.maintainers; [ srhb ma27 thehedgeh0g ]; + meta.maintainers = with lib.maintainers; [ srhb ma27 pyrox0 ]; } diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index 43568f29dd376..7b96a182f0d94 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -18,6 +18,8 @@ let gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket"; pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url; + gitlabVersionAtLeast = version: lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) version; + databaseConfig = let val = { adapter = "postgresql"; @@ -27,10 +29,16 @@ let encoding = "utf8"; pool = cfg.databasePool; } // cfg.extraDatabaseConfig; - in if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then { - production.main = val; - } else { - production = val; + in { + production = ( + if (gitlabVersionAtLeast "15.0") + then { main = val; } + else val + ) // lib.optionalAttrs (gitlabVersionAtLeast "15.9") { + ci = val // { + database_tasks = false; + }; + }; }; # We only want to create a database if we're actually going to connect to it. @@ -1168,7 +1176,7 @@ in { set -eu PSQL() { - psql --port=${toString pgsql.port} "$@" + psql --port=${toString pgsql.settings.port} "$@" } PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${cfg.databaseName}'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "${cfg.databaseName}" OWNER "${cfg.databaseUsername}"' @@ -1348,7 +1356,7 @@ in { rm -f '${cfg.statePath}/config/database.yml' - ${if cfg.databasePasswordFile != null then '' + ${lib.optionalString (cfg.databasePasswordFile != null) '' db_password="$(<'${cfg.databasePasswordFile}')" export db_password @@ -1356,16 +1364,24 @@ in { >&2 echo "Database password was an empty string!" exit 1 fi + ''} - jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \ - '.${if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then "production.main" else "production"}.password = $ENV.db_password' \ - >'${cfg.statePath}/config/database.yml' - '' - else '' - jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \ - >'${cfg.statePath}/config/database.yml' - '' - } + # GitLab expects the `production.main` section to be the first entry in the file. + jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} '{ + production: [ + ${lib.optionalString (cfg.databasePasswordFile != null) ( + builtins.concatStringsSep "\n " ( + [ ".production${lib.optionalString (gitlabVersionAtLeast "15.0") ".main"}.password = $ENV.db_password" ] + ++ lib.optional (gitlabVersionAtLeast "15.9") "| .production.ci.password = $ENV.db_password" + ++ [ "|" ] + ) + )} .production + | to_entries[] + ] + | sort_by(.key) + | reverse + | from_entries + }' >'${cfg.statePath}/config/database.yml' ${utils.genJqSecretsReplacementSnippet gitlabConfig diff --git a/nixos/modules/services/misc/heisenbridge.nix b/nixos/modules/services/misc/heisenbridge.nix index de109e726633f..54c298f1b5602 100644 --- a/nixos/modules/services/misc/heisenbridge.nix +++ b/nixos/modules/services/misc/heisenbridge.nix @@ -210,5 +210,5 @@ in }; }; - meta.maintainers = [ lib.maintainers.piegames ]; + meta.maintainers = [ ]; } diff --git a/nixos/modules/services/monitoring/parsedmarc.nix b/nixos/modules/services/monitoring/parsedmarc.nix index 9191a4a697e0b..a14ade59c29eb 100644 --- a/nixos/modules/services/monitoring/parsedmarc.nix +++ b/nixos/modules/services/monitoring/parsedmarc.nix @@ -301,7 +301,7 @@ in description = '' The addresses to send outgoing mail to. ''; - apply = x: if x == [] then null else lib.concatStringsSep "," x; + apply = x: if x == [] || x == null then null else lib.concatStringsSep "," x; }; }; @@ -438,7 +438,7 @@ in ]; dashboards.settings.providers = lib.mkIf cfg.provision.grafana.dashboard [{ name = "parsedmarc"; - options.path = "${pkgs.python3Packages.parsedmarc.dashboard}"; + options.path = "${pkgs.parsedmarc.dashboard}"; }]; }; }; @@ -446,7 +446,7 @@ in services.parsedmarc.settings = lib.mkMerge [ (lib.mkIf cfg.provision.elasticsearch { elasticsearch = { - hosts = [ "localhost:9200" ]; + hosts = [ "http://localhost:9200" ]; ssl = false; }; }) @@ -530,7 +530,7 @@ in MemoryDenyWriteExecute = true; LockPersonality = true; SystemCallArchitectures = "native"; - ExecStart = "${pkgs.python3Packages.parsedmarc}/bin/parsedmarc -c /run/parsedmarc/parsedmarc.ini"; + ExecStart = "${lib.getExe pkgs.parsedmarc} -c /run/parsedmarc/parsedmarc.ini"; }; }; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix b/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix index 33a28ba132b8b..f188fe1f68fb8 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.apcupsd; + inherit (lib) mkOption types concatStringsSep; in { port = 9162; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix b/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix index 306726f47e395..e98982c0dd312 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.artifactory; + inherit (lib) mkOption types concatStringsSep; in { port = 9531; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bind.nix b/nixos/modules/services/monitoring/prometheus/exporters/bind.nix index 0f3a13900a274..1c7dcf8b1ef03 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/bind.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/bind.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.bind; + inherit (lib) mkOption types concatStringsSep; in { port = 9119; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bird.nix b/nixos/modules/services/monitoring/prometheus/exporters/bird.nix index a020cd3d54b42..5d91eeed106d4 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/bird.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/bird.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.bird; + inherit (lib) + mkOption + types + concatStringsSep + singleton + ; in { port = 9324; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix b/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix index b2bea158b07fc..e1b7dc91a0d77 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix @@ -1,13 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.bitcoin; + inherit (lib) mkOption types concatStringsSep; in { port = 9332; extraOpts = { + package = lib.mkPackageOption pkgs "prometheus-bitcoin-exporter" { }; + rpcUser = mkOption { type = types.str; default = "bitcoinrpc"; @@ -66,7 +67,7 @@ in serviceOpts = { script = '' export BITCOIN_RPC_PASSWORD=$(cat ${cfg.rpcPasswordFile}) - exec ${pkgs.prometheus-bitcoin-exporter}/bin/bitcoind-monitor.py + exec ${cfg.package}/bin/bitcoind-monitor.py ''; environment = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix b/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix index 80d0cfcc5e451..33a1fdc528053 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix @@ -1,10 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let logPrefix = "services.prometheus.exporter.blackbox"; cfg = config.services.prometheus.exporters.blackbox; + inherit (lib) + mkOption + types + concatStringsSep + escapeShellArg + ; # This ensures that we can deal with string paths, path types and # store-path strings with context. diff --git a/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix b/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix index ff1ee6a517b9c..0af1e33b2c445 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.buildkite-agent; + inherit (lib) + mkOption + types + concatStringsSep + optionalString + literalExpression + ; in { port = 9876; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix b/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix index 339eb8c3f5f46..6f4c936fd4093 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.collectd; + inherit (lib) + mkOption + mkEnableOption + types + optionalString + concatStringsSep + escapeShellArg + ; in { port = 9103; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix b/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix index 0f240cb30bb1d..3674fab1e4f83 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.dmarc; + inherit (lib) mkOption types optionalString; json = builtins.toJSON { inherit (cfg) folders port; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix b/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix index f7ff2665f3d89..ba438ea74a3b6 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.dnsmasq; + inherit (lib) + mkOption + types + concatStringsSep + escapeShellArg + ; in { port = 9153; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/domain.nix b/nixos/modules/services/monitoring/prometheus/exporters/domain.nix index b2c8e6664c0f6..c271a040d288f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/domain.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/domain.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.domain; + inherit (lib) concatStringsSep; in { port = 9222; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix b/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix index ca02f73729161..f11e91fd761a9 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.dovecot; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + ; in { port = 9166; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/flow.nix b/nixos/modules/services/monitoring/prometheus/exporters/flow.nix index a9e2446d01568..7719215952a53 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/flow.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/flow.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.flow; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + optionalString + ; in { port = 9590; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix b/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix index fe1d1834570ac..29470147c13f2 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.fritzbox; + inherit (lib) mkOption types concatStringsSep; in { port = 9133; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix b/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix index 3d1123e18a32d..54696187feb15 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix @@ -1,8 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.idrac; + inherit (lib) mkOption types; configFile = if cfg.configurationPath != null then cfg.configurationPath diff --git a/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix b/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix index c1e2a458f97b3..92d02a3f14635 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.imap-mailstat; valueToString = value: @@ -13,6 +11,15 @@ let else "XXX ${toString value}" ) ); + inherit (lib) + mkOption + types + concatStrings + concatStringsSep + attrValues + mapAttrs + optionalString + ; createConfigFile = accounts: # unfortunately on toTOML yet # https://github.com/NixOS/nix/issues/3929 diff --git a/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix b/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix index 9ac0c35bf816f..3a5680439d4c2 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.influxdb; + inherit (lib) mkOption types concatStringsSep; in { port = 9122; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix b/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix index a51c09d5086c0..51db6059081fb 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix @@ -1,10 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let logPrefix = "services.prometheus.exporter.ipmi"; cfg = config.services.prometheus.exporters.ipmi; + inherit (lib) + mkOption + types + concatStringsSep + optionals + escapeShellArg + ; in { port = 9290; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix b/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix index f6c2d9172f4c4..6a6c003c19776 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.jitsi; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + ; in { port = 9700; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/json.nix b/nixos/modules/services/monitoring/prometheus/exporters/json.nix index 1e4632f9310eb..1c8db0ea3e0b1 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/json.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/json.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.json; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + mkRemovedOptionModule + ; in { port = 7979; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix b/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix index 75b8bb650478a..3519cce6e821b 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.junos-czerwonk; + inherit (lib) + mkOption + types + escapeShellArg + mkIf + concatStringsSep + ; configFile = if cfg.configuration != null then configurationFile else (escapeShellArg cfg.configurationFile); diff --git a/nixos/modules/services/monitoring/prometheus/exporters/kea.nix b/nixos/modules/services/monitoring/prometheus/exporters/kea.nix index 88dc284a8cc63..d0f2eb6b8a3c0 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/kea.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/kea.nix @@ -5,10 +5,14 @@ , ... }: -with lib; - let cfg = config.services.prometheus.exporters.kea; + inherit (lib) + mkOption + types + mkRenamedOptionModule + literalExpression + ; in { imports = [ (mkRenamedOptionModule [ "controlSocketPaths" ] [ "targets" ]) diff --git a/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix b/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix index afdb664a0de5e..44169cce6745e 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.keylight; + inherit (lib) concatStringsSep; in { port = 9288; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/knot.nix b/nixos/modules/services/monitoring/prometheus/exporters/knot.nix index 79d952dfb1641..ed902fc27c152 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/knot.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/knot.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.knot; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + ; in { port = 9433; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix b/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix index cc8db6e1b4e43..edface276f541 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.lnd; + inherit (lib) mkOption types concatStringsSep; in { port = 9092; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/mail.nix b/nixos/modules/services/monitoring/prometheus/exporters/mail.nix index 7ace5c1968fb1..f6dd6f7eb994a 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/mail.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/mail.nix @@ -1,9 +1,19 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.mail; + inherit (lib) + mkOption + types + mapAttrs' + nameValuePair + toLower + filterAttrs + escapeShellArg + literalExpression + mkIf + concatStringsSep + ; configFile = if cfg.configuration != null then configurationFile else (escapeShellArg cfg.configFile); diff --git a/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix b/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix index 9e0a98f0ba64f..cd438f13edd25 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.mikrotik; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + escapeShellArg + ; in { port = 9436; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/minio.nix b/nixos/modules/services/monitoring/prometheus/exporters/minio.nix index e1edd364c8fcb..8faff5908b8a9 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/minio.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/minio.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.minio; + inherit (lib) + mkOption + types + optionalString + concatStringsSep + escapeShellArg + ; in { port = 9290; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix b/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix index 37a2daebd9739..37ff49b27000f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.modemmanager; + inherit (lib) mkOption types concatStringsSep; in { port = 9539; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix b/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix index 10d533a2bbdad..288434e93abb0 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix @@ -1,9 +1,17 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.mongodb; + inherit (lib) + mkOption + types + optionalString + getExe + length + concatStringsSep + concatMapStringsSep + escapeShellArgs + ; in { port = 9216; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nats.nix b/nixos/modules/services/monitoring/prometheus/exporters/nats.nix index 83e60426f5ed2..224ce474d5377 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nats.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nats.nix @@ -1,11 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let - cfg = config.services.prometheus.exporters.nats; - + inherit (lib) mkOption types concatStringsSep; in { port = 7777; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix b/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix index f22c5e2e5cff1..d221bac8421ac 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nextcloud; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + ; in { port = 9205; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix b/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix index d4939c7063a39..091ad2291d2a6 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix @@ -1,9 +1,16 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nginx; + inherit (lib) + mkOption + types + mkMerge + mkRemovedOptionModule + mkRenamedOptionModule + mkIf + concatStringsSep + ; in { port = 9113; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix b/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix index ebb13a8c3ee3b..2b4fd12895a39 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nginxlog; + inherit (lib) mkOption types; in { port = 9117; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/node.nix b/nixos/modules/services/monitoring/prometheus/exporters/node.nix index 8615bd04951cc..9d6b51ad140d0 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/node.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/node.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.node; + inherit (lib) + mkOption + types + concatStringsSep + concatMapStringsSep + any + optionals + ; collectorIsEnabled = final: any (collector: (final == collector)) cfg.enabledCollectors; collectorIsDisabled = final: any (collector: (final == collector)) cfg.disabledCollectors; in diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nut.nix b/nixos/modules/services/monitoring/prometheus/exporters/nut.nix index e88059cea4396..157bdadddfc99 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nut.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nut.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nut; + inherit (lib) + mkOption + types + optionalString + concatStringsSep + ; in { port = 9199; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix b/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix index 9c1b39bb3a349..bb65bd2709330 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.services.prometheus.exporters.openldap; + inherit (lib) mkOption types concatStringsSep; in { port = 9330; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix b/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix index 725a5679e271f..71b602638632e 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.pgbouncer; + inherit (lib) + mkOption + types + optionals + escapeShellArg + concatStringsSep + ; in { port = 9127; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix b/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix index 926626b5e7979..30b260dc3792a 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.pihole; + inherit (lib) + mkOption + types + mkRemovedOptionModule + optionalString + ; in { imports = [ diff --git a/nixos/modules/services/monitoring/prometheus/exporters/ping.nix b/nixos/modules/services/monitoring/prometheus/exporters/ping.nix index a47db4c16f427..9122a6be66e66 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/ping.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/ping.nix @@ -1,9 +1,9 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.ping; + inherit (lib) mkOption types concatStringsSep; settingsFormat = pkgs.formats.yaml {}; configFile = settingsFormat.generate "config.yml" cfg.settings; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix b/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix index 188a5f9a1a14a..7aa3622f16d62 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.postfix; + inherit (lib) + mkOption + types + mkIf + escapeShellArg + concatStringsSep + optional + ; in { port = 9154; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix b/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix index 7ed71ff9e10e9..bf392382660ab 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.postgres; + inherit (lib) + mkOption + types + mkIf + mkForce + concatStringsSep + ; in { port = 9187; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/process.nix b/nixos/modules/services/monitoring/prometheus/exporters/process.nix index b041a957b6387..8e5eceee067ce 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/process.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/process.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.process; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + ; configFile = pkgs.writeText "process-exporter.yaml" (builtins.toJSON cfg.settings); in { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pve.nix b/nixos/modules/services/monitoring/prometheus/exporters/pve.nix index 96db49d9591f7..8928577b69532 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/pve.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/pve.nix @@ -1,8 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.pve; + inherit (lib) + mkOption + types + mkPackageOption + optionalString + optionalAttrs + ; # pve exporter requires a config file so create an empty one if configFile is not provided emptyConfigFile = pkgs.writeTextFile { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix b/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix index 66a8423f8ff5c..d788ce363d614 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.py-air-control; + inherit (lib) mkOption types; workingDir = "/var/lib/${cfg.stateDir}"; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/redis.nix b/nixos/modules/services/monitoring/prometheus/exporters/redis.nix index ee7d87e8e6150..672e3dfe7b059 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/redis.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/redis.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.redis; + inherit (lib) concatStringsSep; in { port = 9121; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/restic.nix b/nixos/modules/services/monitoring/prometheus/exporters/restic.nix index aaf3c189a4d20..ef44803ba053d 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/restic.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/restic.nix @@ -1,9 +1,18 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.restic; + inherit (lib) + mkOption + types + concatStringsSep + mkIf + mapAttrs' + splitString + toUpper + optionalAttrs + nameValuePair + ; in { port = 9753; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix b/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix index ee8047fb4599d..8993aee5d2482 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix @@ -1,9 +1,16 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.rspamd; + inherit (lib) + mkOption + types + replaceStrings + mkRemovedOptionModule + recursiveUpdate + concatStringsSep + literalExpression + ; mkFile = conf: pkgs.writeText "rspamd-exporter-config.yml" (builtins.toJSON conf); diff --git a/nixos/modules/services/monitoring/prometheus/exporters/script.nix b/nixos/modules/services/monitoring/prometheus/exporters/script.nix index 5fe8512f554e7..0967ce236a62e 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/script.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/script.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.script; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + ; configFile = pkgs.writeText "script-exporter.yaml" (builtins.toJSON cfg.settings); in { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix b/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix index 5b3cf10b650b0..be3e483c6ee19 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.shelly; + inherit (lib) mkOption types; in { port = 9784; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix b/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix index 84658c48c7239..8aadd87abbedb 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.smartctl; + inherit (lib) mkOption types literalExpression; args = lib.escapeShellArgs ([ "--web.listen-address=${cfg.listenAddress}:${toString cfg.port}" "--smartctl.path=${pkgs.smartmontools}/bin/smartctl" diff --git a/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix b/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix index 79ed5129dda4d..c3baed1503764 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.smokeping; + inherit (lib) mkOption types concatStringsSep; goDuration = types.mkOptionType { name = "goDuration"; description = "Go duration (https://golang.org/pkg/time/#ParseDuration)"; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix index 19ab31d735f86..dc10a9a2f92ea 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix @@ -1,10 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let logPrefix = "services.prometheus.exporters.snmp"; cfg = config.services.prometheus.exporters.snmp; + inherit (lib) + mkOption + types + literalExpression + escapeShellArg + concatStringsSep + ; # This ensures that we can deal with string paths, path types and # store-path strings with context. diff --git a/nixos/modules/services/monitoring/prometheus/exporters/sql.nix b/nixos/modules/services/monitoring/prometheus/exporters/sql.nix index 4c4d8f880364a..59715f5d33e24 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/sql.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/sql.nix @@ -1,7 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.sql; + inherit (lib) + mkOption + types + mapAttrs + mapAttrsToList + concatStringsSep + ; cfgOptions = { options = with types; { jobs = mkOption { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix b/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix index 94df86167e8ce..b1bc65c9a492f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.statsd; + inherit (lib) concatStringsSep; in { port = 9102; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix b/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix index 0e16d27b9d042..d848e263a3b64 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.surfboard; + inherit (lib) mkOption types concatStringsSep; in { port = 9239; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix b/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix index 2edd1de83e1bf..52bad81ed7d51 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix @@ -1,9 +1,8 @@ { config, pkgs, lib, ... }: -with lib; - -let cfg = config.services.prometheus.exporters.systemd; - +let + cfg = config.services.prometheus.exporters.systemd; + inherit (lib) concatStringsSep; in { port = 9558; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/tor.nix b/nixos/modules/services/monitoring/prometheus/exporters/tor.nix index 48406def98944..d39112d0c283c 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/tor.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/tor.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.tor; + inherit (lib) mkOption types concatStringsSep; in { port = 9130; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix b/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix index 0452f630c2e2f..df6011e2434b1 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix @@ -5,10 +5,17 @@ , ... }: -with lib; - let cfg = config.services.prometheus.exporters.unbound; + inherit (lib) + mkOption + types + mkRemovedOptionModule + optionalAttrs + optionalString + mkMerge + mkIf + ; in { imports = [ diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix b/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix index 82309febf63b8..07d177251f40d 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.unifi; + inherit (lib) + mkOption + types + escapeShellArg + optionalString + concatStringsSep + ; in { port = 9130; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix b/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix index 0ea824fbf1140..7b9ba4c5d1edb 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.unpoller; + inherit (lib) mkEnableOption generators; configFile = pkgs.writeText "prometheus-unpoller-exporter.json" (generators.toJSON {} { poller = { inherit (cfg.log) debug quiet; }; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix b/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix index 1582554c12531..4fda15c9ee4ea 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.v2ray; + inherit (lib) mkOption types concatStringsSep; in { port = 9299; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix b/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix index 811792674b96c..e94c513ae84f1 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.varnish; + inherit (lib) + mkOption + types + mkDefault + optional + escapeShellArg + concatStringsSep + ; in { port = 9131; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix index 27c0c191c6e34..7a48c836425ff 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.wireguard; + inherit (lib) + mkOption + types + mkRenamedOptionModule + mkEnableOption + optionalString + escapeShellArg + ; in { port = 9586; imports = [ diff --git a/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix b/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix index ce9cd624dc278..a685b94b827f4 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.zfs; + inherit (lib) + mkOption + types + concatStringsSep + concatMapStringsSep + ; in { port = 9134; diff --git a/nixos/modules/services/monitoring/rustdesk-server.nix b/nixos/modules/services/monitoring/rustdesk-server.nix index fcfd57167dd8f..21e6128c7226a 100644 --- a/nixos/modules/services/monitoring/rustdesk-server.nix +++ b/nixos/modules/services/monitoring/rustdesk-server.nix @@ -53,15 +53,14 @@ in { Slice = "system-rustdesk.slice"; User = "rustdesk"; Group = "rustdesk"; + DynamicUser = "yes"; Environment = []; WorkingDirectory = "/var/lib/rustdesk"; StateDirectory = "rustdesk"; StateDirectoryMode = "0750"; LockPersonality = true; - NoNewPrivileges = true; PrivateDevices = true; PrivateMounts = true; - PrivateTmp = true; PrivateUsers = true; ProtectClock = true; ProtectControlGroups = true; @@ -71,10 +70,7 @@ in { ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; - ProtectSystem = "strict"; - RemoveIPC = true; RestrictNamespaces = true; - RestrictSUIDSGID = true; }; }; in lib.mkIf cfg.enable { diff --git a/nixos/modules/services/monitoring/vmagent.nix b/nixos/modules/services/monitoring/vmagent.nix index cdcf1571154e9..4838e0709d09e 100644 --- a/nixos/modules/services/monitoring/vmagent.nix +++ b/nixos/modules/services/monitoring/vmagent.nix @@ -1,63 +1,62 @@ { config, pkgs, lib, ... }: -with lib; + let cfg = config.services.vmagent; settingsFormat = pkgs.formats.json { }; in { - options.services.vmagent = { - enable = mkEnableOption "vmagent"; - - user = mkOption { - default = "vmagent"; - type = types.str; - description = '' - User account under which vmagent runs. - ''; - }; + imports = [ + (lib.mkRemovedOptionModule [ "services" "vmagent" "dataDir" ] "dataDir has been deprecated in favor of systemd provided CacheDirectory") + (lib.mkRemovedOptionModule [ "services" "vmagent" "user" ] "user has been deprecated in favor of systemd DynamicUser") + (lib.mkRemovedOptionModule [ "services" "vmagent" "group" ] "group has been deprecated in favor of systemd DynamicUser") + (lib.mkRenamedOptionModule [ "services" "vmagent" "remoteWriteUrl" ] [ "services" "vmagent" "remoteWrite" "url" ]) + ]; - group = mkOption { - type = types.str; - default = "vmagent"; - description = '' - Group under which vmagent runs. - ''; - }; - - package = mkPackageOption pkgs "vmagent" { }; + options.services.vmagent = { + enable = lib.mkEnableOption "vmagent"; - dataDir = mkOption { - type = types.str; - default = "/var/lib/vmagent"; - description = '' - The directory where vmagent stores its data files. - ''; - }; + package = lib.mkPackageOption pkgs "vmagent" { }; - remoteWriteUrl = mkOption { - default = "http://localhost:8428/api/v1/write"; - type = types.str; - description = '' - The storage endpoint such as VictoriaMetrics - ''; + remoteWrite = { + url = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + Endpoint for prometheus compatible remote_write + ''; + }; + basicAuthUsername = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + Basic Auth username used to connect to remote_write endpoint + ''; + }; + basicAuthPasswordFile = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + File that contains the Basic Auth password used to connect to remote_write endpoint + ''; + }; }; - prometheusConfig = mkOption { + prometheusConfig = lib.mkOption { type = lib.types.submodule { freeformType = settingsFormat.type; }; description = '' Config for prometheus style metrics ''; }; - openFirewall = mkOption { - type = types.bool; + openFirewall = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to open the firewall for the default ports. ''; }; - extraArgs = mkOption { - type = types.listOf types.str; + extraArgs = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Extra args to pass to `vmagent`. See the docs: @@ -67,37 +66,36 @@ in { }; }; - config = mkIf cfg.enable { - users.groups = mkIf (cfg.group == "vmagent") { vmagent = { }; }; - - users.users = mkIf (cfg.user == "vmagent") { - vmagent = { - group = cfg.group; - description = "vmagent daemon user"; - home = cfg.dataDir; - isSystemUser = true; - }; - }; - - networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ 8429 ]; + config = lib.mkIf cfg.enable { + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 8429 ]; systemd.services.vmagent = let prometheusConfig = settingsFormat.generate "prometheusConfig.yaml" cfg.prometheusConfig; + startCommandLine = lib.concatStringsSep " " ([ + "${cfg.package}/bin/vmagent" + "-promscrape.config=${prometheusConfig}" + ] ++ cfg.extraArgs + ++ lib.optionals (cfg.remoteWrite.url != null) [ + "-remoteWrite.url=${cfg.remoteWrite.url}" + "-remoteWrite.tmpDataPath=%C/vmagent/remote_write_tmp" + ] ++ lib.optional (cfg.remoteWrite.basicAuthUsername != null) "-remoteWrite.basicAuth.username=${cfg.remoteWrite.basicAuthUsername}" + ++ lib.optional (cfg.remoteWrite.basicAuthPasswordFile != null) "-remoteWrite.basicAuth.passwordFile=\${CREDENTIALS_DIRECTORY}/remote_write_basic_auth_password"); in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; description = "vmagent system service"; serviceConfig = { - User = cfg.user; - Group = cfg.group; + DynamicUser = true; + User = "vmagent"; + Group = "vmagent"; Type = "simple"; Restart = "on-failure"; - WorkingDirectory = cfg.dataDir; - ExecStart = "${cfg.package}/bin/vmagent -remoteWrite.url=${cfg.remoteWriteUrl} -promscrape.config=${prometheusConfig} ${escapeShellArgs cfg.extraArgs}"; + CacheDirectory = "vmagent"; + ExecStart = startCommandLine; + LoadCredential = lib.optional (cfg.remoteWrite.basicAuthPasswordFile != null) [ + "remote_write_basic_auth_password:${cfg.remoteWrite.basicAuthPasswordFile}" + ]; }; }; - - systemd.tmpfiles.rules = - [ "d '${cfg.dataDir}' 0755 ${cfg.user} ${cfg.group} -" ]; }; } diff --git a/nixos/modules/services/networking/adguardhome.nix b/nixos/modules/services/networking/adguardhome.nix index 6958bcccf54cf..df9927351edc3 100644 --- a/nixos/modules/services/networking/adguardhome.nix +++ b/nixos/modules/services/networking/adguardhome.nix @@ -4,6 +4,7 @@ with lib; let cfg = config.services.adguardhome; + settingsFormat = pkgs.formats.yaml { }; args = concatStringsSep " " ([ "--no-check-update" @@ -12,27 +13,33 @@ let "--config /var/lib/AdGuardHome/AdGuardHome.yaml" ] ++ cfg.extraArgs); - configFile = pkgs.writeTextFile { - name = "AdGuardHome.yaml"; - text = builtins.toJSON cfg.settings; - checkPhase = "${pkgs.adguardhome}/bin/adguardhome -c $out --check-config"; - }; - defaultBindPort = 3000; - -in -{ - - imports = - let cfgPath = [ "services" "adguardhome" ]; - in - [ - (mkRenamedOptionModuleWith { sinceRelease = 2211; from = cfgPath ++ [ "host" ]; to = cfgPath ++ [ "settings" "bind_host" ]; }) - (mkRenamedOptionModuleWith { sinceRelease = 2211; from = cfgPath ++ [ "port" ]; to = cfgPath ++ [ "settings" "bind_port" ]; }) - ]; - + settings = if (cfg.settings != null) then + cfg.settings // (if cfg.settings.schema_version < 23 then { + bind_host = cfg.host; + bind_port = cfg.port; + } else { + http.address = "${cfg.host}:${toString cfg.port}"; + }) + else + null; + + configFile = + (settingsFormat.generate "AdGuardHome.yaml" settings).overrideAttrs (_: { + checkPhase = "${cfg.package}/bin/adguardhome -c $out --check-config"; + }); +in { options.services.adguardhome = with types; { enable = mkEnableOption "AdGuard Home network-wide ad blocker"; + package = mkOption { + type = package; + default = pkgs.adguardhome; + defaultText = literalExpression "pkgs.adguardhome"; + description = '' + The package that runs adguardhome. + ''; + }; + openFirewall = mkOption { default = false; type = bool; @@ -43,8 +50,8 @@ in }; allowDHCP = mkOption { - default = cfg.settings.dhcp.enabled or false; - defaultText = literalExpression ''config.services.adguardhome.settings.dhcp.enabled or false''; + default = settings.dhcp.enabled or false; + defaultText = literalExpression "config.services.adguardhome.settings.dhcp.enabled or false"; type = bool; description = '' Allows AdGuard Home to open raw sockets (`CAP_NET_RAW`), which is @@ -65,32 +72,34 @@ in ''; }; + host = mkOption { + default = "0.0.0.0"; + type = str; + description = '' + Host address to bind HTTP server to. + ''; + }; + + port = mkOption { + default = 3000; + type = port; + description = '' + Port to serve HTTP pages on. + ''; + }; + settings = mkOption { default = null; type = nullOr (submodule { - freeformType = (pkgs.formats.yaml { }).type; + freeformType = settingsFormat.type; options = { schema_version = mkOption { - default = pkgs.adguardhome.schema_version; - defaultText = literalExpression "pkgs.adguardhome.schema_version"; + default = cfg.package.schema_version; + defaultText = literalExpression "cfg.package.schema_version"; type = int; description = '' Schema version for the configuration. - Defaults to the `schema_version` supplied by `pkgs.adguardhome`. - ''; - }; - bind_host = mkOption { - default = "0.0.0.0"; - type = str; - description = '' - Host address to bind HTTP server to. - ''; - }; - bind_port = mkOption { - default = defaultBindPort; - type = port; - description = '' - Port to serve HTTP pages on. + Defaults to the `schema_version` supplied by `cfg.package`. ''; }; }; @@ -107,7 +116,7 @@ in Set this to `null` (default) for a non-declarative configuration without any Nix-supplied values. - Declarative configurations are supplied with a default `schema_version`, `bind_host`, and `bind_port`. + Declarative configurations are supplied with a default `schema_version`, and `http.address`. ::: ''; }; @@ -124,17 +133,25 @@ in config = mkIf cfg.enable { assertions = [ { - assertion = cfg.settings != null -> cfg.mutableSettings - || (hasAttrByPath [ "dns" "bind_host" ] cfg.settings) - || (hasAttrByPath [ "dns" "bind_hosts" ] cfg.settings); - message = - "AdGuard setting dns.bind_host or dns.bind_hosts needs to be configured for a minimal working configuration"; + assertion = cfg.settings != null + -> !(hasAttrByPath [ "bind_host" ] cfg.settings); + message = "AdGuard option `settings.bind_host' has been superseded by `services.adguardhome.host'"; + } + { + assertion = cfg.settings != null + -> !(hasAttrByPath [ "bind_port" ] cfg.settings); + message = "AdGuard option `settings.bind_host' has been superseded by `services.adguardhome.port'"; + } + { + assertion = settings != null -> cfg.mutableSettings + || hasAttrByPath [ "dns" "bootstrap_dns" ] settings; + message = "AdGuard setting dns.bootstrap_dns needs to be configured for a minimal working configuration"; } { - assertion = cfg.settings != null -> cfg.mutableSettings - || hasAttrByPath [ "dns" "bootstrap_dns" ] cfg.settings; - message = - "AdGuard setting dns.bootstrap_dns needs to be configured for a minimal working configuration"; + assertion = settings != null -> cfg.mutableSettings + || hasAttrByPath [ "dns" "bootstrap_dns" ] settings + && isList settings.dns.bootstrap_dns; + message = "AdGuard setting dns.bootstrap_dns needs to be a list"; } ]; @@ -147,7 +164,7 @@ in StartLimitBurst = 10; }; - preStart = optionalString (cfg.settings != null) '' + preStart = optionalString (settings != null) '' if [ -e "$STATE_DIRECTORY/AdGuardHome.yaml" ] \ && [ "${toString cfg.mutableSettings}" = "1" ]; then # Writing directly to AdGuardHome.yaml results in empty file @@ -161,8 +178,9 @@ in serviceConfig = { DynamicUser = true; - ExecStart = "${pkgs.adguardhome}/bin/adguardhome ${args}"; - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ] ++ optionals cfg.allowDHCP [ "CAP_NET_RAW" ]; + ExecStart = "${cfg.package}/bin/adguardhome ${args}"; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ] + ++ optionals cfg.allowDHCP [ "CAP_NET_RAW" ]; Restart = "always"; RestartSec = 10; RuntimeDirectory = "AdGuardHome"; @@ -170,6 +188,6 @@ in }; }; - networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.bind_port or defaultBindPort ]; + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ]; }; } diff --git a/nixos/modules/services/networking/clatd.nix b/nixos/modules/services/networking/clatd.nix new file mode 100644 index 0000000000000..76e0c130ca466 --- /dev/null +++ b/nixos/modules/services/networking/clatd.nix @@ -0,0 +1,82 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.clatd; + + settingsFormat = pkgs.formats.keyValue {}; + + configFile = settingsFormat.generate "clatd.conf" cfg.settings; +in +{ + options = { + services.clatd = { + enable = mkEnableOption "clatd"; + + package = mkPackageOption pkgs "clatd" { }; + + settings = mkOption { + type = types.submodule ({ name, ... }: { + freeformType = settingsFormat.type; + }); + default = { }; + example = literalExpression '' + { + plat-prefix = "64:ff9b::/96"; + } + ''; + description = '' + Configuration of clatd. See [clatd Documentation](https://github.com/toreanderson/clatd/blob/master/README.pod#configuration). + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.clatd = { + description = "464XLAT CLAT daemon"; + documentation = [ "man:clatd(8)" ]; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + startLimitIntervalSec = 0; + + serviceConfig = { + ExecStart = "${cfg.package}/bin/clatd -c ${configFile}"; + startLimitIntervalSec = 0; + + # Hardening + CapabilityBoundingSet = [ + "CAP_NET_ADMIN" + ]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectProc = "invisible"; + ProtectSystem = true; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_NETLINK" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@network-io" + "@system-service" + "~@privileged" + "~@resources" + ]; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/jotta-cli.md b/nixos/modules/services/networking/jotta-cli.md new file mode 100644 index 0000000000000..fee002a4e6046 --- /dev/null +++ b/nixos/modules/services/networking/jotta-cli.md @@ -0,0 +1,27 @@ +# Jottacloud Command-line Tool {#module-services-jotta-cli} + +The [Jottacloud Command-line Tool](https://docs.jottacloud.com/en/articles/1436834-jottacloud-command-line-tool) is a headless [Jottacloud](https://jottacloud.com) client. + +## Quick Start {#module-services-jotta-cli-quick-start} + +```nix +{ + user.services.jotta-cli.enable = true; +} +``` + +This adds `jotta-cli` to `environment.systemPackages` and starts a user service that runs `jottad` with the default options. + +## Example Configuration {#module-services-jotta-cli-example-configuration} + +```nix +user.services.jotta-cli = { + enable = true; + options = [ "slow" ]; + package = pkgs.jotta-cli; +}; +``` + +This uses `jotta-cli` and `jottad` from the `pkgs.jotta-cli` package and starts `jottad` in low memory mode. + +`jottad` is also added to `environment.systemPackages`, so `jottad --help` can be used to explore options. diff --git a/nixos/modules/services/networking/jotta-cli.nix b/nixos/modules/services/networking/jotta-cli.nix new file mode 100644 index 0000000000000..c7e6dad5453ca --- /dev/null +++ b/nixos/modules/services/networking/jotta-cli.nix @@ -0,0 +1,43 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.user.services.jotta-cli; +in { + options = { + user.services.jotta-cli = { + + enable = mkEnableOption "Jottacloud Command-line Tool"; + + options = mkOption { + default = [ "stdoutlog" "datadir" "%h/.jottad/" ]; + example = [ ]; + type = with types; listOf str; + description = "Command-line options passed to jottad."; + }; + + package = lib.mkPackageOption pkgs "jotta-cli" { }; + }; + }; + config = mkIf cfg.enable { + systemd.user.services.jottad = { + + description = "Jottacloud Command-line Tool daemon"; + + serviceConfig = { + Type = "notify"; + EnvironmentFile = "-%h/.config/jotta-cli/jotta-cli.env"; + ExecStart = "${lib.getExe' cfg.package "jottad"} ${concatStringsSep " " cfg.options}"; + Restart = "on-failure"; + }; + + wantedBy = [ "default.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + }; + environment.systemPackages = [ pkgs.jotta-cli ]; + }; + + meta.maintainers = with lib.maintainers; [ evenbrenden ]; + meta.doc = ./jotta-cli.md; +} diff --git a/nixos/modules/services/networking/knot.nix b/nixos/modules/services/networking/knot.nix index 89d3ea5e9626a..145b4ad1dd3f1 100644 --- a/nixos/modules/services/networking/knot.nix +++ b/nixos/modules/services/networking/knot.nix @@ -226,7 +226,7 @@ in { }; settings = mkOption { - type = types.submodule { freeformType = types.attrs; }; + type = (pkgs.formats.yaml {}).type; default = {}; description = '' Extra configuration as nix values. diff --git a/nixos/modules/services/networking/netbird/coturn.nix b/nixos/modules/services/networking/netbird/coturn.nix index dd032abb2d75e..746d70a07250d 100644 --- a/nixos/modules/services/networking/netbird/coturn.nix +++ b/nixos/modules/services/networking/netbird/coturn.nix @@ -148,10 +148,10 @@ in allowedUDPPorts = cfg.openPorts; allowedTCPPorts = cfg.openPorts; - allowedUDPPortRanges = [ + allowedUDPPortRanges = with config.services.coturn; [ { - from = cfg.minPort; - to = cfg.maxPort; + from = min-port; + to = max-port; } ]; }; diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index e33bbb2af178f..b7143cf520f96 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -470,7 +470,7 @@ in - [main] - no-auto-default=* - ''' - + extraConfig.main.no-auto-default = "*"; + + settings.main.no-auto-default = "*"; }; ``` '' diff --git a/nixos/modules/services/networking/pixiecore.nix b/nixos/modules/services/networking/pixiecore.nix index e61d32e136095..cfdb8014136ed 100644 --- a/nixos/modules/services/networking/pixiecore.nix +++ b/nixos/modules/services/networking/pixiecore.nix @@ -6,7 +6,7 @@ let cfg = config.services.pixiecore; in { - meta.maintainers = with maintainers; [ bbigras danderson ]; + meta.maintainers = with maintainers; [ bbigras ]; options = { services.pixiecore = { diff --git a/nixos/modules/services/networking/pppd.nix b/nixos/modules/services/networking/pppd.nix index d937456efddd4..8310b119b5f67 100644 --- a/nixos/modules/services/networking/pppd.nix +++ b/nixos/modules/services/networking/pppd.nix @@ -7,7 +7,7 @@ let in { meta = { - maintainers = with maintainers; [ danderson ]; + maintainers = with maintainers; [ ]; }; options = { diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 5f2f6cb07af79..c62bccd462d33 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -346,6 +346,7 @@ in violates the privacy of users and is not recommended. ''; }; + UsePAM = mkEnableOption "PAM authentication" // { default = true; }; UseDns = mkOption { type = types.bool; # apply if cfg.useDns then "yes" else "no" @@ -489,6 +490,8 @@ in {manpage}`sshd_config(5)` for details. ''; }; + # Disabled by default, since pam_motd handles this. + PrintMotd = mkEnableOption "printing /etc/motd when a user logs in interactively"; }; }); }; @@ -622,7 +625,7 @@ in networking.firewall.allowedTCPPorts = optionals cfg.openFirewall cfg.ports; - security.pam.services.sshd = + security.pam.services.sshd = lib.mkIf cfg.settings.UsePAM { startSession = true; showMotd = true; unixAuth = cfg.settings.PasswordAuthentication; @@ -638,8 +641,6 @@ in services.openssh.extraConfig = mkOrder 0 '' - UsePAM yes - Banner ${if cfg.banner == null then "none" else pkgs.writeText "ssh_banner" cfg.banner} AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} @@ -657,7 +658,6 @@ in ${optionalString cfg.allowSFTP '' Subsystem sftp ${cfg.sftpServerExecutable} ${concatStringsSep " " cfg.sftpFlags} ''} - PrintMotd no # handled by pam_motd AuthorizedKeysFile ${toString cfg.authorizedKeysFiles} ${optionalString (cfg.authorizedKeysCommand != "none") '' AuthorizedKeysCommand ${cfg.authorizedKeysCommand} diff --git a/nixos/modules/services/networking/sunshine.nix b/nixos/modules/services/networking/sunshine.nix index c115b9cd5cf99..0749eaee95d8a 100644 --- a/nixos/modules/services/networking/sunshine.nix +++ b/nixos/modules/services/networking/sunshine.nix @@ -32,6 +32,13 @@ in Whether to give the Sunshine binary CAP_SYS_ADMIN, required for DRM/KMS screen capture. ''; }; + autoStart = mkOption { + type = bool; + default = true; + description = '' + Whether sunshine should be started automatically. + ''; + }; settings = mkOption { default = { }; description = '' @@ -135,7 +142,7 @@ in systemd.user.services.sunshine = { description = "Self-hosted game stream host for Moonlight"; - wantedBy = [ "graphical-session.target" ]; + wantedBy = mkIf cfg.autoStart [ "graphical-session.target" ]; partOf = [ "graphical-session.target" ]; wants = [ "graphical-session.target" ]; after = [ "graphical-session.target" ]; diff --git a/nixos/modules/services/networking/tailscale.nix b/nixos/modules/services/networking/tailscale.nix index 2a77c0c7a23e7..a79e47d8491b8 100644 --- a/nixos/modules/services/networking/tailscale.nix +++ b/nixos/modules/services/networking/tailscale.nix @@ -6,7 +6,7 @@ let cfg = config.services.tailscale; isNetworkd = config.networking.useNetworkd; in { - meta.maintainers = with maintainers; [ danderson mbaillie twitchyliquid64 mfrw ]; + meta.maintainers = with maintainers; [ mbaillie mfrw ]; options.services.tailscale = { enable = mkEnableOption "Tailscale client daemon"; diff --git a/nixos/modules/services/networking/trust-dns.nix b/nixos/modules/services/networking/trust-dns.nix index e6f8cc15819f6..039b7de263504 100644 --- a/nixos/modules/services/networking/trust-dns.nix +++ b/nixos/modules/services/networking/trust-dns.nix @@ -51,7 +51,7 @@ in package = mkPackageOption pkgs "trust-dns" { extraDescription = '' ::: {.note} - The package must provide `meta.mainProgram` which names the server binayr; any other utilities (client, resolver) are not needed. + The package must provide `meta.mainProgram` which names the server binary; any other utilities (client, resolver) are not needed. ::: ''; }; @@ -86,7 +86,7 @@ in type = types.listOf types.str; default = [ "0.0.0.0" ]; description = '' - List of ipv4 addresses on which to listen for DNS queries. + List of ipv4 addresses on which to listen for DNS queries. ''; }; listen_addrs_ipv6 = mkOption { @@ -114,7 +114,7 @@ in }; zones = mkOption { description = "List of zones to serve."; - default = {}; + default = []; type = types.listOf (types.coercedTo types.str (zone: { inherit zone; }) zoneType); }; }; diff --git a/nixos/modules/services/security/oauth2-proxy-nginx.nix b/nixos/modules/services/security/oauth2-proxy-nginx.nix new file mode 100644 index 0000000000000..c05bd304752d1 --- /dev/null +++ b/nixos/modules/services/security/oauth2-proxy-nginx.nix @@ -0,0 +1,130 @@ +{ config, lib, ... }: +let + cfg = config.services.oauth2-proxy.nginx; +in +{ + options.services.oauth2-proxy.nginx = { + proxy = lib.mkOption { + type = lib.types.str; + default = config.services.oauth2-proxy.httpAddress; + defaultText = lib.literalExpression "config.services.oauth2-proxy.httpAddress"; + description = '' + The address of the reverse proxy endpoint for oauth2-proxy + ''; + }; + + domain = lib.mkOption { + type = lib.types.str; + description = '' + The domain under which the oauth2-proxy will be accesible and the path of cookies are set to. + This setting must be set to ensure back-redirects are working properly + if oauth2-proxy is configured with {option}`services.oauth2-proxy.cookie.domain` + or multiple {option}`services.oauth2-proxy.nginx.virtualHosts` that are not on the same domain. + ''; + }; + + virtualHosts = lib.mkOption { + type = let + vhostSubmodule = lib.types.submodule { + options = { + allowed_groups = lib.mkOption { + type = lib.types.nullOr (lib.types.listOf lib.types.str); + description = "List of groups to allow access to this vhost, or null to allow all."; + default = null; + }; + allowed_emails = lib.mkOption { + type = lib.types.nullOr (lib.types.listOf lib.types.str); + description = "List of emails to allow access to this vhost, or null to allow all."; + default = null; + }; + allowed_email_domains = lib.mkOption { + type = lib.types.nullOr (lib.types.listOf lib.types.str); + description = "List of email domains to allow access to this vhost, or null to allow all."; + default = null; + }; + }; + }; + oldType = lib.types.listOf lib.types.str; + convertFunc = x: + lib.warn "services.oauth2-proxy.nginx.virtualHosts should be an attrset, found ${lib.generators.toPretty {} x}" + lib.genAttrs x (_: {}); + newType = lib.types.attrsOf vhostSubmodule; + in lib.types.coercedTo oldType convertFunc newType; + default = {}; + example = { + "protected.foo.com" = { + allowed_groups = ["admins"]; + allowed_emails = ["boss@foo.com"]; + }; + }; + description = '' + Nginx virtual hosts to put behind the oauth2 proxy. + You can exclude specific locations by setting `auth_request off;` in the locations extraConfig setting. + ''; + }; + }; + + config.services.oauth2-proxy = lib.mkIf (cfg.virtualHosts != [] && (lib.hasPrefix "127.0.0.1:" cfg.proxy)) { + enable = true; + }; + + config.services.nginx = lib.mkIf (cfg.virtualHosts != [] && config.services.oauth2-proxy.enable) (lib.mkMerge ([ + { + virtualHosts.${cfg.domain}.locations."/oauth2/" = { + proxyPass = cfg.proxy; + extraConfig = '' + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; + ''; + }; + } + ] ++ lib.optional (cfg.virtualHosts != []) { + recommendedProxySettings = true; # needed because duplicate headers + } ++ (lib.mapAttrsToList (vhost: conf: { + virtualHosts.${vhost} = { + locations = { + "/oauth2/auth" = let + maybeQueryArg = name: value: + if value == null then null + else "${name}=${lib.concatStringsSep "," (builtins.map lib.escapeURL value)}"; + allArgs = lib.mapAttrsToList maybeQueryArg conf; + cleanArgs = builtins.filter (x: x != null) allArgs; + cleanArgsStr = lib.concatStringsSep "&" cleanArgs; + in { + # nginx doesn't support passing query string arguments to auth_request, + # so pass them here instead + proxyPass = "${cfg.proxy}/oauth2/auth?${cleanArgsStr}"; + extraConfig = '' + auth_request off; + proxy_set_header X-Scheme $scheme; + # nginx auth_request includes headers but not body + proxy_set_header Content-Length ""; + proxy_pass_request_body off; + ''; + }; + "@redirectToAuth2ProxyLogin" = { + return = "307 https://${cfg.domain}/oauth2/start?rd=$scheme://$host$request_uri"; + extraConfig = '' + auth_request off; + ''; + }; + }; + + extraConfig = '' + auth_request /oauth2/auth; + error_page 401 = @redirectToAuth2ProxyLogin; + + # pass information via X-User and X-Email headers to backend, + # requires running with --set-xauthrequest flag + auth_request_set $user $upstream_http_x_auth_request_user; + auth_request_set $email $upstream_http_x_auth_request_email; + proxy_set_header X-User $user; + proxy_set_header X-Email $email; + + # if you enabled --cookie-refresh, this is needed for it to work with auth_request + auth_request_set $auth_cookie $upstream_http_set_cookie; + add_header Set-Cookie $auth_cookie; + ''; + }; + }) cfg.virtualHosts))); +} diff --git a/nixos/modules/services/security/oauth2_proxy.nix b/nixos/modules/services/security/oauth2-proxy.nix index d2992a196bf87..075e64b743b1e 100644 --- a/nixos/modules/services/security/oauth2_proxy.nix +++ b/nixos/modules/services/security/oauth2-proxy.nix @@ -1,15 +1,12 @@ -# NixOS module for oauth2_proxy. - { config, lib, pkgs, ... }: -with lib; let - cfg = config.services.oauth2_proxy; + cfg = config.services.oauth2-proxy; - # oauth2_proxy provides many options that are only relevant if you are using + # oauth2-proxy provides many options that are only relevant if you are using # a certain provider. This set maps from provider name to a function that # takes the configuration and returns a string that can be inserted into the - # command-line to launch oauth2_proxy. + # command-line to launch oauth2-proxy. providerSpecificOptions = { azure = cfg: { azure-tenant = cfg.azure.tenant; @@ -73,28 +70,28 @@ let } // (getProviderOptions cfg cfg.provider) // cfg.extraConfig; mapConfig = key: attr: - optionalString (attr != null && attr != []) ( - if isDerivation attr then mapConfig key (toString attr) else - if (builtins.typeOf attr) == "set" then concatStringsSep " " - (mapAttrsToList (name: value: mapConfig (key + "-" + name) value) attr) else - if (builtins.typeOf attr) == "list" then concatMapStringsSep " " (mapConfig key) attr else - if (builtins.typeOf attr) == "bool" then "--${key}=${boolToString attr}" else + lib.optionalString (attr != null && attr != []) ( + if lib.isDerivation attr then mapConfig key (toString attr) else + if (builtins.typeOf attr) == "set" then lib.concatStringsSep " " + (lib.mapAttrsToList (name: value: mapConfig (key + "-" + name) value) attr) else + if (builtins.typeOf attr) == "list" then lib.concatMapStringsSep " " (mapConfig key) attr else + if (builtins.typeOf attr) == "bool" then "--${key}=${lib.boolToString attr}" else if (builtins.typeOf attr) == "string" then "--${key}='${attr}'" else "--${key}=${toString attr}"); - configString = concatStringsSep " " (mapAttrsToList mapConfig allConfig); + configString = lib.concatStringsSep " " (lib.mapAttrsToList mapConfig allConfig); in { - options.services.oauth2_proxy = { - enable = mkEnableOption "oauth2_proxy"; + options.services.oauth2-proxy = { + enable = lib.mkEnableOption "oauth2-proxy"; - package = mkPackageOption pkgs "oauth2-proxy" { }; + package = lib.mkPackageOption pkgs "oauth2-proxy" { }; ############################################## # PROVIDER configuration # Taken from: https://github.com/oauth2-proxy/oauth2-proxy/blob/master/providers/providers.go - provider = mkOption { - type = types.enum [ + provider = lib.mkOption { + type = lib.types.enum [ "adfs" "azure" "bitbucket" @@ -116,24 +113,24 @@ in ''; }; - approvalPrompt = mkOption { - type = types.enum ["force" "auto"]; + approvalPrompt = lib.mkOption { + type = lib.types.enum ["force" "auto"]; default = "force"; description = '' OAuth approval_prompt. ''; }; - clientID = mkOption { - type = types.nullOr types.str; + clientID = lib.mkOption { + type = lib.types.nullOr lib.types.str; description = '' The OAuth Client ID. ''; example = "123456.apps.googleusercontent.com"; }; - oidcIssuerUrl = mkOption { - type = types.nullOr types.str; + oidcIssuerUrl = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' The OAuth issuer URL. @@ -141,15 +138,15 @@ in example = "https://login.microsoftonline.com/{TENANT_ID}/v2.0"; }; - clientSecret = mkOption { - type = types.nullOr types.str; + clientSecret = lib.mkOption { + type = lib.types.nullOr lib.types.str; description = '' The OAuth Client Secret. ''; }; - skipAuthRegexes = mkOption { - type = types.listOf types.str; + skipAuthRegexes = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Skip authentication for requests matching any of these regular @@ -159,8 +156,8 @@ in # XXX: Not clear whether these two options are mutually exclusive or not. email = { - domains = mkOption { - type = types.listOf types.str; + domains = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Authenticate emails with the specified domains. Use @@ -168,8 +165,8 @@ in ''; }; - addresses = mkOption { - type = types.nullOr types.lines; + addresses = lib.mkOption { + type = lib.types.nullOr lib.types.lines; default = null; description = '' Line-separated email addresses that are allowed to authenticate. @@ -177,8 +174,8 @@ in }; }; - loginURL = mkOption { - type = types.nullOr types.str; + loginURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Authentication endpoint. @@ -190,8 +187,8 @@ in example = "https://provider.example.com/oauth/authorize"; }; - redeemURL = mkOption { - type = types.nullOr types.str; + redeemURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Token redemption endpoint. @@ -203,8 +200,8 @@ in example = "https://provider.example.com/oauth/token"; }; - validateURL = mkOption { - type = types.nullOr types.str; + validateURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Access token validation endpoint. @@ -216,10 +213,10 @@ in example = "https://provider.example.com/user/emails"; }; - redirectURL = mkOption { + redirectURL = lib.mkOption { # XXX: jml suspects this is always necessary, but the command-line # doesn't require it so making it optional. - type = types.nullOr types.str; + type = lib.types.nullOr lib.types.str; default = null; description = '' The OAuth2 redirect URL. @@ -228,16 +225,16 @@ in }; azure = { - tenant = mkOption { - type = types.str; + tenant = lib.mkOption { + type = lib.types.str; default = "common"; description = '' Go to a tenant-specific or common (tenant-independent) endpoint. ''; }; - resource = mkOption { - type = types.str; + resource = lib.mkOption { + type = lib.types.str; description = '' The resource that is protected. ''; @@ -245,8 +242,8 @@ in }; google = { - adminEmail = mkOption { - type = types.str; + adminEmail = lib.mkOption { + type = lib.types.str; description = '' The Google Admin to impersonate for API calls. @@ -258,16 +255,16 @@ in ''; }; - groups = mkOption { - type = types.listOf types.str; + groups = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Restrict logins to members of these Google groups. ''; }; - serviceAccountJSON = mkOption { - type = types.path; + serviceAccountJSON = lib.mkOption { + type = lib.types.path; description = '' The path to the service account JSON credentials. ''; @@ -275,16 +272,16 @@ in }; github = { - org = mkOption { - type = types.nullOr types.str; + org = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Restrict logins to members of this organisation. ''; }; - team = mkOption { - type = types.nullOr types.str; + team = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Restrict logins to members of this team. @@ -295,8 +292,8 @@ in #################################################### # UPSTREAM Configuration - upstream = mkOption { - type = with types; coercedTo str (x: [x]) (listOf str); + upstream = lib.mkOption { + type = with lib.types; coercedTo str (x: [x]) (listOf str); default = []; description = '' The http url(s) of the upstream endpoint or `file://` @@ -304,40 +301,40 @@ in ''; }; - passAccessToken = mkOption { - type = types.bool; + passAccessToken = lib.mkOption { + type = lib.types.bool; default = false; description = '' Pass OAuth access_token to upstream via X-Forwarded-Access-Token header. ''; }; - passBasicAuth = mkOption { - type = types.bool; + passBasicAuth = lib.mkOption { + type = lib.types.bool; default = true; description = '' Pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream. ''; }; - basicAuthPassword = mkOption { - type = types.nullOr types.str; + basicAuthPassword = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' The password to set when passing the HTTP Basic Auth header. ''; }; - passHostHeader = mkOption { - type = types.bool; + passHostHeader = lib.mkOption { + type = lib.types.bool; default = true; description = '' Pass the request Host Header to upstream. ''; }; - signatureKey = mkOption { - type = types.nullOr types.str; + signatureKey = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' GAP-Signature request signature key. @@ -346,8 +343,8 @@ in }; cookie = { - domain = mkOption { - type = types.nullOr types.str; + domain = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Optional cookie domains to force cookies to (ie: `.yourcompany.com`). @@ -357,33 +354,33 @@ in example = ".yourcompany.com"; }; - expire = mkOption { - type = types.str; + expire = lib.mkOption { + type = lib.types.str; default = "168h0m0s"; description = '' Expire timeframe for cookie. ''; }; - httpOnly = mkOption { - type = types.bool; + httpOnly = lib.mkOption { + type = lib.types.bool; default = true; description = '' Set HttpOnly cookie flag. ''; }; - name = mkOption { - type = types.str; + name = lib.mkOption { + type = lib.types.str; default = "_oauth2_proxy"; description = '' The name of the cookie that the oauth_proxy creates. ''; }; - refresh = mkOption { + refresh = lib.mkOption { # XXX: Unclear what the behavior is when this is not specified. - type = types.nullOr types.str; + type = lib.types.nullOr lib.types.str; default = null; description = '' Refresh the cookie after this duration; 0 to disable. @@ -391,15 +388,15 @@ in example = "168h0m0s"; }; - secret = mkOption { - type = types.nullOr types.str; + secret = lib.mkOption { + type = lib.types.nullOr lib.types.str; description = '' The seed string for secure cookies. ''; }; - secure = mkOption { - type = types.bool; + secure = lib.mkOption { + type = lib.types.bool; default = true; description = '' Set secure (HTTPS) cookie flag. @@ -410,8 +407,8 @@ in #################################################### # OAUTH2 PROXY configuration - httpAddress = mkOption { - type = types.str; + httpAddress = lib.mkOption { + type = lib.types.str; default = "http://127.0.0.1:4180"; description = '' HTTPS listening address. This module does not expose the port by @@ -421,8 +418,8 @@ in }; htpasswd = { - file = mkOption { - type = types.nullOr types.path; + file = lib.mkOption { + type = lib.types.nullOr lib.types.path; default = null; description = '' Additionally authenticate against a htpasswd file. Entries must be @@ -430,8 +427,8 @@ in ''; }; - displayForm = mkOption { - type = types.bool; + displayForm = lib.mkOption { + type = lib.types.bool; default = true; description = '' Display username / password login form if an htpasswd file is provided. @@ -439,16 +436,16 @@ in }; }; - customTemplatesDir = mkOption { - type = types.nullOr types.path; + customTemplatesDir = lib.mkOption { + type = lib.types.nullOr lib.types.path; default = null; description = '' Path to custom HTML templates. ''; }; - reverseProxy = mkOption { - type = types.bool; + reverseProxy = lib.mkOption { + type = lib.types.bool; default = false; description = '' In case when running behind a reverse proxy, controls whether headers @@ -458,8 +455,8 @@ in ''; }; - proxyPrefix = mkOption { - type = types.str; + proxyPrefix = lib.mkOption { + type = lib.types.str; default = "/oauth2"; description = '' The url root path that this proxy should be nested under. @@ -467,30 +464,30 @@ in }; tls = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to serve over TLS. ''; }; - certificate = mkOption { - type = types.path; + certificate = lib.mkOption { + type = lib.types.path; description = '' Path to certificate file. ''; }; - key = mkOption { - type = types.path; + key = lib.mkOption { + type = lib.types.path; description = '' Path to private key file. ''; }; - httpsAddress = mkOption { - type = types.str; + httpsAddress = lib.mkOption { + type = lib.types.str; default = ":443"; description = '' `addr:port` to listen on for HTTPS clients. @@ -502,8 +499,8 @@ in }; }; - requestLogging = mkOption { - type = types.bool; + requestLogging = lib.mkOption { + type = lib.types.bool; default = true; description = '' Log requests to stdout. @@ -514,42 +511,42 @@ in # UNKNOWN # XXX: Is this mandatory? Is it part of another group? Is it part of the provider specification? - scope = mkOption { + scope = lib.mkOption { # XXX: jml suspects this is always necessary, but the command-line # doesn't require it so making it optional. - type = types.nullOr types.str; + type = lib.types.nullOr lib.types.str; default = null; description = '' OAuth scope specification. ''; }; - profileURL = mkOption { - type = types.nullOr types.str; + profileURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Profile access endpoint. ''; }; - setXauthrequest = mkOption { - type = types.nullOr types.bool; + setXauthrequest = lib.mkOption { + type = lib.types.nullOr lib.types.bool; default = false; description = '' Set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode). Setting this to 'null' means using the upstream default (false). ''; }; - extraConfig = mkOption { + extraConfig = lib.mkOption { default = {}; - type = types.attrsOf types.anything; + type = lib.types.attrsOf lib.types.anything; description = '' Extra config to pass to oauth2-proxy. ''; }; - keyFile = mkOption { - type = types.nullOr types.path; + keyFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; default = null; description = '' oauth2-proxy allows passing sensitive configuration via environment variables. @@ -557,28 +554,30 @@ in OAUTH2_PROXY_CLIENT_SECRET=asdfasdfasdf.apps.googleuserscontent.com and specify the path here. ''; - example = "/run/keys/oauth2_proxy"; + example = "/run/keys/oauth2-proxy"; }; - }; - config = mkIf cfg.enable { + imports = [ + (lib.mkRenamedOptionModule [ "services" "oauth2_proxy" ] [ "services" "oauth2-proxy" ]) + ]; - services.oauth2_proxy = mkIf (cfg.keyFile != null) { - clientID = mkDefault null; - clientSecret = mkDefault null; - cookie.secret = mkDefault null; + config = lib.mkIf cfg.enable { + services.oauth2-proxy = lib.mkIf (cfg.keyFile != null) { + clientID = lib.mkDefault null; + clientSecret = lib.mkDefault null; + cookie.secret = lib.mkDefault null; }; - users.users.oauth2_proxy = { + users.users.oauth2-proxy = { description = "OAuth2 Proxy"; isSystemUser = true; - group = "oauth2_proxy"; + group = "oauth2-proxy"; }; - users.groups.oauth2_proxy = {}; + users.groups.oauth2-proxy = {}; - systemd.services.oauth2_proxy = { + systemd.services.oauth2-proxy = { description = "OAuth2 Proxy"; path = [ cfg.package ]; wantedBy = [ "multi-user.target" ]; @@ -586,10 +585,10 @@ in after = [ "network-online.target" ]; serviceConfig = { - User = "oauth2_proxy"; + User = "oauth2-proxy"; Restart = "always"; ExecStart = "${cfg.package}/bin/oauth2-proxy ${configString}"; - EnvironmentFile = mkIf (cfg.keyFile != null) cfg.keyFile; + EnvironmentFile = lib.mkIf (cfg.keyFile != null) cfg.keyFile; }; }; diff --git a/nixos/modules/services/security/oauth2_proxy_nginx.nix b/nixos/modules/services/security/oauth2_proxy_nginx.nix deleted file mode 100644 index 87ea61276837c..0000000000000 --- a/nixos/modules/services/security/oauth2_proxy_nginx.nix +++ /dev/null @@ -1,91 +0,0 @@ -{ config, lib, ... }: -with lib; -let - cfg = config.services.oauth2_proxy.nginx; -in -{ - options.services.oauth2_proxy.nginx = { - proxy = mkOption { - type = types.str; - default = config.services.oauth2_proxy.httpAddress; - defaultText = literalExpression "config.services.oauth2_proxy.httpAddress"; - description = '' - The address of the reverse proxy endpoint for oauth2_proxy - ''; - }; - - domain = mkOption { - type = types.str; - description = '' - The domain under which the oauth2_proxy will be accesible and the path of cookies are set to. - This setting must be set to ensure back-redirects are working properly - if oauth2-proxy is configured with {option}`services.oauth2_proxy.cookie.domain` - or multiple {option}`services.oauth2_proxy.nginx.virtualHosts` that are not on the same domain. - ''; - }; - - virtualHosts = mkOption { - type = types.listOf types.str; - default = []; - description = '' - A list of nginx virtual hosts to put behind the oauth2 proxy. - You can exclude specific locations by setting `auth_request off;` in the locations extraConfig setting. - ''; - }; - }; - - config.services.oauth2_proxy = mkIf (cfg.virtualHosts != [] && (hasPrefix "127.0.0.1:" cfg.proxy)) { - enable = true; - }; - - config.services.nginx = mkIf (cfg.virtualHosts != [] && config.services.oauth2_proxy.enable) (mkMerge ([ - { - virtualHosts.${cfg.domain}.locations."/oauth2/" = { - proxyPass = cfg.proxy; - extraConfig = '' - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; - ''; - }; - } - ] ++ optional (cfg.virtualHosts != []) { - recommendedProxySettings = true; # needed because duplicate headers - } ++ (map (vhost: { - virtualHosts.${vhost} = { - locations = { - "/oauth2/auth" = { - proxyPass = cfg.proxy; - extraConfig = '' - auth_request off; - proxy_set_header X-Scheme $scheme; - # nginx auth_request includes headers but not body - proxy_set_header Content-Length ""; - proxy_pass_request_body off; - ''; - }; - "@redirectToAuth2ProxyLogin" = { - return = "307 https://${cfg.domain}/oauth2/start?rd=$scheme://$host$request_uri"; - extraConfig = '' - auth_request off; - ''; - }; - }; - - extraConfig = '' - auth_request /oauth2/auth; - error_page 401 = @redirectToAuth2ProxyLogin; - - # pass information via X-User and X-Email headers to backend, - # requires running with --set-xauthrequest flag - auth_request_set $user $upstream_http_x_auth_request_user; - auth_request_set $email $upstream_http_x_auth_request_email; - proxy_set_header X-User $user; - proxy_set_header X-Email $email; - - # if you enabled --cookie-refresh, this is needed for it to work with auth_request - auth_request_set $auth_cookie $upstream_http_set_cookie; - add_header Set-Cookie $auth_cookie; - ''; - }; - }) cfg.virtualHosts))); -} diff --git a/nixos/modules/services/security/vault.nix b/nixos/modules/services/security/vault.nix index ab86da47b2e1c..650f9bda99c33 100644 --- a/nixos/modules/services/security/vault.nix +++ b/nixos/modules/services/security/vault.nix @@ -56,8 +56,8 @@ in }; devRootTokenID = mkOption { - type = types.str; - default = false; + type = types.nullOr types.str; + default = null; description = '' Initial root token. This only applies when {option}`services.vault.dev` is true ''; diff --git a/nixos/modules/services/security/vaultwarden/default.nix b/nixos/modules/services/security/vaultwarden/default.nix index b2920931f9a9e..33957be437b30 100644 --- a/nixos/modules/services/security/vaultwarden/default.nix +++ b/nixos/modules/services/security/vaultwarden/default.nix @@ -131,21 +131,13 @@ in { Additional environment file as defined in {manpage}`systemd.exec(5)`. Secrets like {env}`ADMIN_TOKEN` and {env}`SMTP_PASSWORD` - may be passed to the service without adding them to the world-readable Nix store. + should be passed to the service without adding them to the world-readable Nix store. - Note that this file needs to be available on the host on which - `vaultwarden` is running. + Note that this file needs to be available on the host on which `vaultwarden` is running. - As a concrete example, to make the Admin UI available - (from which new users can be invited initially), + As a concrete example, to make the Admin UI available (from which new users can be invited initially), the secret {env}`ADMIN_TOKEN` needs to be defined as described - [here](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page). - Setting `environmentFile` to `/var/lib/vaultwarden.env` - and ensuring permissions with e.g. - `chown vaultwarden:vaultwarden /var/lib/vaultwarden.env` - (the `vaultwarden` user will only exist after activating with - `enable = true;` before this), we can set the contents of the file to have - contents such as: + [here](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page): ``` # Admin secret token, see diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index a9fc88e320c6b..8dba0aca64337 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -39,7 +39,7 @@ in implementation = mkOption { type = types.enum [ "dbus" "broker" ]; - default = "broker"; + default = "dbus"; description = '' The implementation to use for the message bus defined by the D-Bus specification. Can be either the classic dbus daemon or dbus-broker, which aims to provide high diff --git a/nixos/modules/services/web-apps/akkoma.nix b/nixos/modules/services/web-apps/akkoma.nix index eca498549df36..7c9bf6c465164 100644 --- a/nixos/modules/services/web-apps/akkoma.nix +++ b/nixos/modules/services/web-apps/akkoma.nix @@ -817,11 +817,11 @@ in { base_url = mkOption { type = types.nullOr types.nonEmptyStr; default = if lib.versionOlder config.system.stateVersion "24.05" - then "${httpConf.scheme}://${httpConf.host}:${builtins.toString httpConf.port}/media/" + then "${httpConf.scheme}://${httpConf.host}:${builtins.toString httpConf.port}" else null; defaultText = literalExpression '' if lib.versionOlder config.system.stateVersion "24.05" - then "$\{httpConf.scheme}://$\{httpConf.host}:$\{builtins.toString httpConf.port}/media/" + then "$\{httpConf.scheme}://$\{httpConf.host}:$\{builtins.toString httpConf.port}" else null; ''; description = '' @@ -957,7 +957,7 @@ in { assertions = optionals (cfg.config.":pleroma".":media_proxy".enabled && cfg.config.":pleroma".":media_proxy".base_url == null) ['' `services.akkoma.config.":pleroma".":media_proxy".base_url` must be set when the media proxy is enabled. '']; - warnings = optionals (with config.security; (!sudo.enable) && (!sudo-rs.enable)) ['' + warnings = optionals (with config.security; cfg.installWrapper && (!sudo.enable) && (!sudo-rs.enable)) ['' The pleroma_ctl wrapper enabled by the installWrapper option relies on sudo, which appears to have been disabled through security.sudo.enable. '']; diff --git a/nixos/modules/services/web-apps/castopod.nix b/nixos/modules/services/web-apps/castopod.nix index 69ee670276a76..d3750c3dd3938 100644 --- a/nixos/modules/services/web-apps/castopod.nix +++ b/nixos/modules/services/web-apps/castopod.nix @@ -17,7 +17,7 @@ let in { meta.doc = ./castopod.md; - meta.maintainers = with lib.maintainers; [ alexoundos misuzu ]; + meta.maintainers = with lib.maintainers; [ alexoundos ]; options.services = { castopod = { diff --git a/nixos/modules/services/web-apps/coder.nix b/nixos/modules/services/web-apps/coder.nix index 318a7c8fc1357..5450adbe118da 100644 --- a/nixos/modules/services/web-apps/coder.nix +++ b/nixos/modules/services/web-apps/coder.nix @@ -169,7 +169,7 @@ in { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - environment = config.environment.extra // { + environment = cfg.environment.extra // { CODER_ACCESS_URL = cfg.accessUrl; CODER_WILDCARD_ACCESS_URL = cfg.wildcardAccessUrl; CODER_PG_CONNECTION_URL = "user=${cfg.database.username} ${optionalString (cfg.database.password != null) "password=${cfg.database.password}"} database=${cfg.database.database} host=${cfg.database.host} ${optionalString (cfg.database.sslmode != null) "sslmode=${cfg.database.sslmode}"}"; @@ -223,4 +223,5 @@ in { }; }; }; + meta.maintainers = pkgs.coder.meta.maintainers; } diff --git a/nixos/modules/services/web-apps/gotosocial.nix b/nixos/modules/services/web-apps/gotosocial.nix index 8e0e1ad765212..aee1edf66a6a7 100644 --- a/nixos/modules/services/web-apps/gotosocial.nix +++ b/nixos/modules/services/web-apps/gotosocial.nix @@ -27,7 +27,7 @@ let in { meta.doc = ./gotosocial.md; - meta.maintainers = with lib.maintainers; [ misuzu blakesmith ]; + meta.maintainers = with lib.maintainers; [ blakesmith ]; options.services.gotosocial = { enable = lib.mkEnableOption "ActivityPub social network server"; diff --git a/nixos/modules/services/web-apps/mediawiki.nix b/nixos/modules/services/web-apps/mediawiki.nix index 7246fd93a2314..b11626ec2dc3b 100644 --- a/nixos/modules/services/web-apps/mediawiki.nix +++ b/nixos/modules/services/web-apps/mediawiki.nix @@ -246,7 +246,9 @@ in passwordFile = mkOption { type = types.path; - description = "A file containing the initial password for the admin user."; + description = '' + A file containing the initial password for the administrator account "admin". + ''; example = "/run/keys/mediawiki-password"; }; diff --git a/nixos/modules/services/web-apps/movim.nix b/nixos/modules/services/web-apps/movim.nix index bb88a185b4618..29bed0e067fa4 100644 --- a/nixos/modules/services/web-apps/movim.nix +++ b/nixos/modules/services/web-apps/movim.nix @@ -103,22 +103,20 @@ let lib.concatStringsSep "\n" [ (lib.optionalString brotli.enable '' echo -n "Precompressing static files with Brotli …" - find ${appDir}/public -type f ${findTextFileNames} \ - | ${lib.getExe pkgs.parallel} ${lib.escapeShellArgs [ - "--will-cite" - "-j $NIX_BUILD_CORES" - "${lib.getExe brotli.package} --keep --quality=${builtins.toString brotli.compressionLevel} --output={}.br {}" - ]} + find ${appDir}/public -type f ${findTextFileNames} -print0 \ + | xargs -0 -n 1 -P $NIX_BUILD_CORES ${pkgs.writeShellScript "movim_precompress_broti" '' + file="$1" + ${lib.getExe brotli.package} --keep --quality=${builtins.toString brotli.compressionLevel} --output=$file.br $file + ''} echo " done." '') (lib.optionalString gzip.enable '' echo -n "Precompressing static files with Gzip …" - find ${appDir}/public -type f ${findTextFileNames} \ - | ${lib.getExe pkgs.parallel} ${lib.escapeShellArgs [ - "--will-cite" - "-j $NIX_BUILD_CORES" - "${lib.getExe gzip.package} -c -${builtins.toString gzip.compressionLevel} {} > {}.gz" - ]} + find ${appDir}/public -type f ${findTextFileNames} -print0 \ + | xargs -0 -n 1 -P $NIX_BUILD_CORES ${pkgs.writeShellScript "movim_precompress_broti" '' + file="$1" + ${lib.getExe gzip.package} -c -${builtins.toString gzip.compressionLevel} $file > $file.gz + ''} echo " done." '') ]; diff --git a/nixos/modules/services/web-apps/nextcloud.md b/nixos/modules/services/web-apps/nextcloud.md index 06a8712b0b8ae..ec860d307b381 100644 --- a/nixos/modules/services/web-apps/nextcloud.md +++ b/nixos/modules/services/web-apps/nextcloud.md @@ -5,7 +5,7 @@ self-hostable cloud platform. The server setup can be automated using [services.nextcloud](#opt-services.nextcloud.enable). A desktop client is packaged at `pkgs.nextcloud-client`. -The current default by NixOS is `nextcloud28` which is also the latest +The current default by NixOS is `nextcloud29` which is also the latest major version available. ## Basic usage {#module-services-nextcloud-basic-usage} @@ -184,6 +184,32 @@ Alternatively, extra apps can also be declared with the [](#opt-services.nextclo When using this setting, apps can no longer be managed statefully because this can lead to Nextcloud updating apps that are managed by Nix. If you want automatic updates it is recommended that you use web interface to install apps. +## Known warnings {#module-services-nextcloud-known-warnings} + +### Failed to get an iterator for log entries: Logreader application only supports "file" log_type {#module-services-nextcloud-warning-logreader} + +This is because + +* our module writes logs into the journal (`journalctl -t Nextcloud`) +* the Logreader application that allows reading logs in the admin panel is enabled + by default and requires logs written to a file. + +The logreader application doesn't work, as it was the case before. The only change is that +it complains loudly now. So nothing actionable here by default. Alternatively you can + +* disable the logreader application to shut up the "error". + + We can't really do that by default since whether apps are enabled/disabled is part + of the application's state and tracked inside the database. + +* set [](#opt-services.nextcloud.settings.log_type) to "file" to be able to view logs + from the admin panel. + +### Your web server is not properly set up to resolve `.well-known` URLs, failed on: `/.well-known/caldav` {#module-services-nextcloud-warning-wellknown-caldav} + +This warning appearing seems to be an upstream issue and is being sorted out +in [nextcloud/server#45033](https://github.com/nextcloud/server/issues/45033). + ## Maintainer information {#module-services-nextcloud-maintainer-info} As stated in the previous paragraph, we must provide a clean upgrade-path for Nextcloud diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index f179a9854eb91..21f76938f20c5 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -819,7 +819,8 @@ in { ++ (optional (versionOlder cfg.package.version "25") (upgradeWarning 24 "22.11")) ++ (optional (versionOlder cfg.package.version "26") (upgradeWarning 25 "23.05")) ++ (optional (versionOlder cfg.package.version "27") (upgradeWarning 26 "23.11")) - ++ (optional (versionOlder cfg.package.version "28") (upgradeWarning 27 "24.05")); + ++ (optional (versionOlder cfg.package.version "28") (upgradeWarning 27 "24.05")) + ++ (optional (versionOlder cfg.package.version "29") (upgradeWarning 28 "24.11")); services.nextcloud.package = with pkgs; mkDefault ( @@ -832,10 +833,12 @@ in { else if versionOlder stateVersion "23.05" then nextcloud25 else if versionOlder stateVersion "23.11" then nextcloud26 else if versionOlder stateVersion "24.05" then nextcloud27 - else nextcloud28 + else nextcloud29 ); - services.nextcloud.phpPackage = pkgs.php82; + services.nextcloud.phpPackage = + if versionOlder cfg.package.version "29" then pkgs.php82 + else pkgs.php83; services.nextcloud.phpOptions = mkMerge [ (mapAttrs (const mkOptionDefault) defaultPHPSettings) diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 40470f535bf61..08fab09e1e559 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -352,7 +352,8 @@ let # The acme-challenge location doesn't need to be added if we are not using any automated # certificate provisioning and can also be omitted when we use a certificate obtained via a DNS-01 challenge - acmeLocation = optionalString (vhost.enableACME || (vhost.useACMEHost != null && config.security.acme.certs.${vhost.useACMEHost}.dnsProvider == null)) + acmeName = if vhost.useACMEHost != null then vhost.useACMEHost else vhostName; + acmeLocation = optionalString ((vhost.enableACME || vhost.useACMEHost != null) && config.security.acme.certs.${acmeName}.dnsProvider == null) # Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx) # We use ^~ here, so that we don't check any regexes (which could # otherwise easily override this intended match accidentally). @@ -829,7 +830,7 @@ in sslCiphers = mkOption { type = types.nullOr types.str; # Keep in sync with https://ssl-config.mozilla.org/#server=nginx&config=intermediate - default = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; + default = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305"; description = "Ciphers to choose from when negotiating TLS handshakes."; }; diff --git a/nixos/modules/services/x11/desktop-managers/budgie.nix b/nixos/modules/services/x11/desktop-managers/budgie.nix index 75ee82f1f948a..b4e7390293351 100644 --- a/nixos/modules/services/x11/desktop-managers/budgie.nix +++ b/nixos/modules/services/x11/desktop-managers/budgie.nix @@ -214,7 +214,7 @@ in { services.geoclue2.enable = mkDefault true; # for BCC's Privacy > Location Services panel. services.upower.enable = config.powerManagement.enable; # for Budgie's Status Indicator and BCC's Power panel. - services.xserver.libinput.enable = mkDefault true; # for BCC's Mouse panel. + services.libinput.enable = mkDefault true; # for BCC's Mouse panel. services.colord.enable = mkDefault true; # for BCC's Color panel. services.gnome.at-spi2-core.enable = mkDefault true; # for BCC's A11y panel. services.accounts-daemon.enable = mkDefault true; # for BCC's Users panel. diff --git a/nixos/modules/services/x11/desktop-managers/cinnamon.nix b/nixos/modules/services/x11/desktop-managers/cinnamon.nix index 8c29b41c8cf80..2e0eef67c0b3e 100644 --- a/nixos/modules/services/x11/desktop-managers/cinnamon.nix +++ b/nixos/modules/services/x11/desktop-managers/cinnamon.nix @@ -116,7 +116,7 @@ in services.touchegg.enable = mkDefault true; services.udisks2.enable = true; services.upower.enable = mkDefault config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; services.xserver.updateDbusEnvironment = true; networking.networkmanager.enable = mkDefault true; @@ -157,6 +157,7 @@ in # packages nemo-with-extensions + gnome-online-accounts-gtk cinnamon-control-center cinnamon-settings-daemon libgnomekbd diff --git a/nixos/modules/services/x11/desktop-managers/deepin.nix b/nixos/modules/services/x11/desktop-managers/deepin.nix index 680ce7b9a93e6..30bd14adb4192 100644 --- a/nixos/modules/services/x11/desktop-managers/deepin.nix +++ b/nixos/modules/services/x11/desktop-managers/deepin.nix @@ -61,7 +61,7 @@ in services.gnome.gnome-keyring.enable = mkDefault true; services.bamf.enable = mkDefault true; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; services.udisks2.enable = true; services.upower.enable = mkDefault config.powerManagement.enable; networking.networkmanager.enable = mkDefault true; diff --git a/nixos/modules/services/x11/desktop-managers/default.nix b/nixos/modules/services/x11/desktop-managers/default.nix index 6fe606f92267b..42e66e86e1a35 100644 --- a/nixos/modules/services/x11/desktop-managers/default.nix +++ b/nixos/modules/services/x11/desktop-managers/default.nix @@ -1,8 +1,7 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) mkOption types; xcfg = config.services.xserver; cfg = xcfg.desktopManager; @@ -59,7 +58,7 @@ in session = mkOption { internal = true; default = []; - example = singleton + example = lib.singleton { name = "kde"; bgSupport = true; start = "..."; @@ -73,26 +72,15 @@ in manage = "desktop"; start = d.start # literal newline to ensure d.start's last line is not appended to - + optionalString (needBGCond d) '' + + lib.optionalString (needBGCond d) '' if [ -e $HOME/.background-image ]; then - ${pkgs.feh}/bin/feh --bg-${cfg.wallpaper.mode} ${optionalString cfg.wallpaper.combineScreens "--no-xinerama"} $HOME/.background-image + ${pkgs.feh}/bin/feh --bg-${cfg.wallpaper.mode} ${lib.optionalString cfg.wallpaper.combineScreens "--no-xinerama"} $HOME/.background-image fi ''; }); }; - default = mkOption { - type = types.nullOr types.str; - default = null; - example = "none"; - description = '' - **Deprecated**, please use [](#opt-services.displayManager.defaultSession) instead. - - Default desktop manager loaded if none have been chosen. - ''; - }; - }; }; diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix index 09f90e1cd4df8..0a341ba133d39 100644 --- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix +++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -96,7 +96,7 @@ in services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; services.dbus.packages = [ e.efl ]; diff --git a/nixos/modules/services/x11/desktop-managers/gnome.nix b/nixos/modules/services/x11/desktop-managers/gnome.nix index 95c79cf96108c..fe50d930b5af0 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome.nix @@ -1,8 +1,7 @@ { config, lib, pkgs, utils, ... }: -with lib; - let + inherit (lib) mkOption types mkDefault mkEnableOption literalExpression; cfg = config.services.xserver.desktopManager.gnome; serviceCfg = config.services.gnome; @@ -51,8 +50,8 @@ let destination = "/share/gnome-background-properties/nixos.xml"; }; - flashbackEnabled = cfg.flashback.enableMetacity || length cfg.flashback.customSessions > 0; - flashbackWms = optional cfg.flashback.enableMetacity { + flashbackEnabled = cfg.flashback.enableMetacity || lib.length cfg.flashback.customSessions > 0; + flashbackWms = lib.optional cfg.flashback.enableMetacity { wmName = "metacity"; wmLabel = "Metacity"; wmCommand = "${pkgs.gnome.metacity}/bin/metacity"; @@ -67,73 +66,9 @@ in meta = { doc = ./gnome.md; - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "core-os-services" "enable" ] - [ "services" "gnome" "core-os-services" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "gnome3" "core-shell" "enable" ] - [ "services" "gnome" "core-shell" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "gnome3" "core-utilities" "enable" ] - [ "services" "gnome" "core-utilities" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "gnome3" "core-developer-tools" "enable" ] - [ "services" "gnome" "core-developer-tools" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "gnome3" "games" "enable" ] - [ "services" "gnome" "games" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "gnome3" "experimental-features" "realtime-scheduling" ] - [ "services" "gnome" "experimental-features" "realtime-scheduling" ] - ) - (mkRenamedOptionModule - [ "services" "xserver" "desktopManager" "gnome3" "enable" ] - [ "services" "xserver" "desktopManager" "gnome" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "xserver" "desktopManager" "gnome3" "sessionPath" ] - [ "services" "xserver" "desktopManager" "gnome" "sessionPath" ] - ) - (mkRenamedOptionModule - [ "services" "xserver" "desktopManager" "gnome3" "favoriteAppsOverride" ] - [ "services" "xserver" "desktopManager" "gnome" "favoriteAppsOverride" ] - ) - (mkRenamedOptionModule - [ "services" "xserver" "desktopManager" "gnome3" "extraGSettingsOverrides" ] - [ "services" "xserver" "desktopManager" "gnome" "extraGSettingsOverrides" ] - ) - (mkRenamedOptionModule - [ "services" "xserver" "desktopManager" "gnome3" "extraGSettingsOverridePackages" ] - [ "services" "xserver" "desktopManager" "gnome" "extraGSettingsOverridePackages" ] - ) - (mkRenamedOptionModule - [ "services" "xserver" "desktopManager" "gnome3" "debug" ] - [ "services" "xserver" "desktopManager" "gnome" "debug" ] - ) - (mkRenamedOptionModule - [ "services" "xserver" "desktopManager" "gnome3" "flashback" ] - [ "services" "xserver" "desktopManager" "gnome" "flashback" ] - ) - (mkRenamedOptionModule - [ "environment" "gnome3" "excludePackages" ] - [ "environment" "gnome" "excludePackages" ] - ) - (mkRemovedOptionModule - [ "services" "gnome" "experimental-features" "realtime-scheduling" ] - "Set `security.rtkit.enable = true;` to make realtime scheduling possible. (Still needs to be enabled using GSettings.)" - ) - ]; - options = { services.gnome = { @@ -248,8 +183,8 @@ in }; - config = mkMerge [ - (mkIf (cfg.enable || flashbackEnabled) { + config = lib.mkMerge [ + (lib.mkIf (cfg.enable || flashbackEnabled) { # Seed our configuration into nixos-generate-config system.nixos-generate-config.desktopConfiguration = ['' # Enable the GNOME Desktop Environment. @@ -264,7 +199,7 @@ in services.displayManager.sessionPackages = [ pkgs.gnome.gnome-session.sessions ]; environment.extraInit = '' - ${concatMapStrings (p: '' + ${lib.concatMapStrings (p: '' if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name} fi @@ -278,19 +213,19 @@ in environment.systemPackages = cfg.sessionPath; - environment.sessionVariables.GNOME_SESSION_DEBUG = mkIf cfg.debug "1"; + environment.sessionVariables.GNOME_SESSION_DEBUG = lib.mkIf cfg.debug "1"; # Override GSettings schemas environment.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas"; }) - (mkIf flashbackEnabled { + (lib.mkIf flashbackEnabled { services.displayManager.sessionPackages = let wmNames = map (wm: wm.wmName) flashbackWms; namesAreUnique = lib.unique wmNames == wmNames; in - assert (assertMsg namesAreUnique "Flashback WM names must be unique."); + assert (lib.assertMsg namesAreUnique "Flashback WM names must be unique."); map (wm: pkgs.gnome.gnome-flashback.mkSessionForWm { @@ -318,7 +253,7 @@ in ++ (map (wm: gnome-flashback.mkGnomeSession { inherit (wm) wmName wmLabel enableGnomePanel; }) flashbackWms); }) - (mkIf serviceCfg.core-os-services.enable { + (lib.mkIf serviceCfg.core-os-services.enable { hardware.bluetooth.enable = mkDefault true; hardware.pulseaudio.enable = mkDefault true; programs.dconf.enable = true; @@ -339,7 +274,7 @@ in # services.packagekit.enable = mkDefault true; services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center + services.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center # Explicitly enabled since GNOME will be severely broken without these. xdg.mime.enable = true; @@ -371,7 +306,7 @@ in ]; }) - (mkIf serviceCfg.core-shell.enable { + (lib.mkIf serviceCfg.core-shell.enable { services.xserver.desktopManager.gnome.sessionPath = let mandatoryPackages = [ @@ -393,7 +328,7 @@ in services.gnome.gnome-user-share.enable = mkDefault true; services.gnome.rygel.enable = mkDefault true; services.gvfs.enable = true; - services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true)); + services.system-config-printer.enable = (lib.mkIf config.services.printing.enable (mkDefault true)); systemd.packages = with pkgs.gnome; [ gnome-session @@ -408,10 +343,6 @@ in services.avahi.enable = mkDefault true; - xdg.portal.extraPortals = [ - pkgs.gnome.gnome-shell - ]; - services.geoclue2.enable = mkDefault true; services.geoclue2.enableDemoAgent = false; # GNOME has its own geoclue agent @@ -463,7 +394,7 @@ in }) # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/-/blob/gnome-45/elements/core/meta-gnome-core-utilities.bst - (mkIf serviceCfg.core-utilities.enable { + (lib.mkIf serviceCfg.core-utilities.enable { environment.systemPackages = with pkgs.gnome; utils.removePackagesByName @@ -524,7 +455,7 @@ in ]; }) - (mkIf serviceCfg.games.enable { + (lib.mkIf serviceCfg.games.enable { environment.systemPackages = with pkgs.gnome; utils.removePackagesByName [ aisleriot atomix @@ -550,7 +481,7 @@ in }) # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/-/blob/3.38.0/elements/core/meta-gnome-core-developer-tools.bst - (mkIf serviceCfg.core-developer-tools.enable { + (lib.mkIf serviceCfg.core-developer-tools.enable { environment.systemPackages = with pkgs.gnome; utils.removePackagesByName [ dconf-editor devhelp diff --git a/nixos/modules/services/x11/desktop-managers/lxqt.nix b/nixos/modules/services/x11/desktop-managers/lxqt.nix index 1937bdcbd3e73..ac86c385bcc8d 100644 --- a/nixos/modules/services/x11/desktop-managers/lxqt.nix +++ b/nixos/modules/services/x11/desktop-managers/lxqt.nix @@ -69,7 +69,7 @@ in services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; xdg.portal.lxqt.enable = mkDefault true; diff --git a/nixos/modules/services/x11/desktop-managers/mate.nix b/nixos/modules/services/x11/desktop-managers/mate.nix index 520d40d67908c..beae07b70dbfe 100644 --- a/nixos/modules/services/x11/desktop-managers/mate.nix +++ b/nixos/modules/services/x11/desktop-managers/mate.nix @@ -88,7 +88,7 @@ in services.udev.packages = [ pkgs.mate.mate-settings-daemon ]; services.gvfs.enable = true; services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; security.pam.services.mate-screensaver.unixAuth = true; diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixos/modules/services/x11/desktop-managers/pantheon.nix index 57ccbaccb0c68..008bc65eb6a4f 100644 --- a/nixos/modules/services/x11/desktop-managers/pantheon.nix +++ b/nixos/modules/services/x11/desktop-managers/pantheon.nix @@ -159,7 +159,7 @@ in services.gsignond.plugins = with pkgs.gsignondPlugins; [ lastfm mail oauth ]; services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; services.xserver.updateDbusEnvironment = true; services.zeitgeist.enable = mkDefault true; services.geoclue2.enable = mkDefault true; diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix index 56fcd70dc9516..7d80b9b2641c3 100644 --- a/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -348,7 +348,7 @@ in services.system-config-printer.enable = mkIf config.services.printing.enable (mkDefault true); services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; # Extra UDEV rules used by Solid services.udev.packages = [ diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix index c55d0021b6a7c..85d0d199de3f2 100644 --- a/nixos/modules/services/x11/desktop-managers/xfce.nix +++ b/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -164,7 +164,7 @@ in services.gvfs.enable = true; services.tumbler.enable = true; services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true)); - services.xserver.libinput.enable = mkDefault true; # used in xfce4-settings-manager + services.libinput.enable = mkDefault true; # used in xfce4-settings-manager # Enable default programs programs.dconf.enable = true; diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix index 0f9b712c6df53..87331a6658d34 100644 --- a/nixos/modules/services/x11/display-managers/default.nix +++ b/nixos/modules/services/x11/display-managers/default.nix @@ -9,9 +9,8 @@ { config, lib, options, pkgs, ... }: -with lib; - let + inherit (lib) mkOption types literalExpression optionalString; cfg = config.services.xserver; xorg = pkgs.xorg; @@ -91,7 +90,7 @@ let # Import environment variables into the systemd user environment. ${optionalString (cfg.displayManager.importedVariables != []) ( "/run/current-system/systemd/bin/systemctl --user import-environment " - + toString (unique cfg.displayManager.importedVariables) + + toString (lib.unique cfg.displayManager.importedVariables) )} # Speed up application start by 50-150ms according to @@ -222,13 +221,6 @@ in }; config = { - assertions = [ - { - assertion = cfg.desktopManager.default != null || cfg.windowManager.default != null -> cfg.displayManager.defaultSession == defaultSessionFromLegacyOptions; - message = "You cannot use both services.displayManager.defaultSession option and legacy options (services.xserver.desktopManager.default and services.xserver.windowManager.default)."; - } - ]; - services.displayManager.sessionData.wrapper = xsessionWrapper; services.xserver.displayManager.xserverBin = "${xorg.xorgserver.out}/bin/X"; @@ -254,8 +246,8 @@ in # that do not have upstream session files (those defined using services.{display,desktop,window}Manager.session options). services.displayManager.sessionPackages = let - dms = filter (s: s.manage == "desktop") cfg.displayManager.session; - wms = filter (s: s.manage == "window") cfg.displayManager.session; + dms = lib.filter (s: s.manage == "desktop") cfg.displayManager.session; + wms = lib.filter (s: s.manage == "window") cfg.displayManager.session; # Script responsible for starting the window manager and the desktop manager. xsession = dm: wm: pkgs.writeScript "xsession" '' @@ -283,16 +275,16 @@ in ''; in # We will generate every possible pair of WM and DM. - concatLists ( + lib.concatLists ( lib.mapCartesianProduct ({dm, wm}: let sessionName = "${dm.name}${optionalString (wm.name != "none") ("+" + wm.name)}"; script = xsession dm wm; desktopNames = if dm ? desktopNames - then concatStringsSep ";" dm.desktopNames + then lib.concatStringsSep ";" dm.desktopNames else sessionName; in - optional (dm.name != "none" || wm.name != "none") + lib.optional (dm.name != "none" || wm.name != "none") (pkgs.writeTextFile { name = "${sessionName}-xsession"; destination = "/share/xsessions/${sessionName}.desktop"; @@ -317,11 +309,11 @@ in }; imports = [ - (mkRemovedOptionModule [ "services" "xserver" "displayManager" "desktopManagerHandlesLidAndPower" ] + (lib.mkRemovedOptionModule [ "services" "xserver" "displayManager" "desktopManagerHandlesLidAndPower" ] "The option is no longer necessary because all display managers have already delegated lid management to systemd.") - (mkRenamedOptionModule [ "services" "xserver" "displayManager" "job" "logsXsession" ] [ "services" "displayManager" "logToFile" ]) - (mkRenamedOptionModule [ "services" "xserver" "displayManager" "logToJournal" ] [ "services" "displayManager" "logToJournal" ]) - (mkRenamedOptionModule [ "services" "xserver" "displayManager" "extraSessionFilesPackages" ] [ "services" "displayManager" "sessionPackages" ]) + (lib.mkRenamedOptionModule [ "services" "xserver" "displayManager" "job" "logsXsession" ] [ "services" "displayManager" "logToFile" ]) + (lib.mkRenamedOptionModule [ "services" "xserver" "displayManager" "logToJournal" ] [ "services" "displayManager" "logToJournal" ]) + (lib.mkRenamedOptionModule [ "services" "xserver" "displayManager" "extraSessionFilesPackages" ] [ "services" "displayManager" "sessionPackages" ]) ]; } diff --git a/nixos/modules/services/x11/hardware/cmt.nix b/nixos/modules/services/x11/hardware/cmt.nix index 55d3d840ee092..53906c5c716f4 100644 --- a/nixos/modules/services/x11/hardware/cmt.nix +++ b/nixos/modules/services/x11/hardware/cmt.nix @@ -46,10 +46,10 @@ in { assertions = [ { - assertion = !config.services.xserver.libinput.enable; + assertion = !config.services.libinput.enable; message = '' cmt and libinput are incompatible, meaning you cannot enable them both. - To use cmt you need to disable libinput with `services.xserver.libinput.enable = false` + To use cmt you need to disable libinput with `services.libinput.enable = false` If you haven't enabled it in configuration.nix, it's enabled by default on a different xserver module. ''; diff --git a/nixos/modules/services/x11/hardware/synaptics.nix b/nixos/modules/services/x11/hardware/synaptics.nix index 4dfa917d8fb4a..c43fdac6b1ec6 100644 --- a/nixos/modules/services/x11/hardware/synaptics.nix +++ b/nixos/modules/services/x11/hardware/synaptics.nix @@ -30,7 +30,7 @@ in { enable = mkOption { type = types.bool; default = false; - description = "Whether to enable touchpad support. Deprecated: Consider services.xserver.libinput.enable."; + description = "Whether to enable touchpad support. Deprecated: Consider services.libinput.enable."; }; dev = mkOption { @@ -207,8 +207,8 @@ in { assertions = [ { - assertion = !config.services.xserver.libinput.enable; - message = "Synaptics and libinput are incompatible, you cannot enable both (in services.xserver)."; + assertion = !config.services.libinput.enable; + message = "Synaptics and libinput are incompatible, you cannot enable both."; } ]; diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix index ec54e4cc12a9e..85eb4c6614d94 100644 --- a/nixos/modules/services/x11/window-managers/default.nix +++ b/nixos/modules/services/x11/window-managers/default.nix @@ -1,8 +1,7 @@ { config, lib, ... }: -with lib; - let + inherit (lib) mkOption types; cfg = config.services.xserver.windowManager; in @@ -72,17 +71,6 @@ in }); }; - default = mkOption { - type = types.nullOr types.str; - default = null; - example = "wmii"; - description = '' - **Deprecated**, please use [](#opt-services.displayManager.defaultSession) instead. - - Default window manager loaded if none have been chosen. - ''; - }; - }; }; diff --git a/nixos/modules/system/boot/loader/grub/grub.nix b/nixos/modules/system/boot/loader/grub/grub.nix index fe340cfaedb67..9c36651d68747 100644 --- a/nixos/modules/system/boot/loader/grub/grub.nix +++ b/nixos/modules/system/boot/loader/grub/grub.nix @@ -6,7 +6,6 @@ let concatMap concatMapStrings concatStrings - concatStringsSep escapeShellArg flip foldr @@ -491,10 +490,10 @@ in theme = mkOption { type = types.nullOr types.path; - example = literalExpression "pkgs.nixos-grub2-theme"; + example = literalExpression ''"''${pkgs.libsForQt5.breeze-grub}/grub/themes/breeze"''; default = null; description = '' - Grub theme to be used. + Path to the grub theme to be used. ''; }; diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix index 8b218cf1a6b2f..cee8663f0040e 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot.nix @@ -7,8 +7,22 @@ let efi = config.boot.loader.efi; + # We check the source code in a derivation that does not depend on the + # system configuration so that most users don't have to redo the check and require + # the necessary dependencies. + checkedSource = pkgs.runCommand "systemd-boot" { + preferLocalBuild = true; + } '' + install -m755 -D ${./systemd-boot-builder.py} $out + ${lib.getExe pkgs.buildPackages.mypy} \ + --no-implicit-optional \ + --disallow-untyped-calls \ + --disallow-untyped-defs \ + $out + ''; + systemdBootBuilder = pkgs.substituteAll rec { - src = ./systemd-boot-builder.py; + src = checkedSource; isExecutable = true; @@ -66,19 +80,9 @@ let ''; }; - checkedSystemdBootBuilder = pkgs.runCommand "systemd-boot" { } '' - mkdir -p $out/bin - install -m755 ${systemdBootBuilder} $out/bin/systemd-boot-builder - ${lib.getExe pkgs.buildPackages.mypy} \ - --no-implicit-optional \ - --disallow-untyped-calls \ - --disallow-untyped-defs \ - $out/bin/systemd-boot-builder - ''; - finalSystemdBootBuilder = pkgs.writeScript "install-systemd-boot.sh" '' #!${pkgs.runtimeShell} - ${checkedSystemdBootBuilder}/bin/systemd-boot-builder "$@" + ${systemdBootBuilder} "$@" ${cfg.extraInstallCommands} ''; in { diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix index aea6855f91c50..c82924763d5e8 100644 --- a/nixos/modules/system/boot/systemd.nix +++ b/nixos/modules/system/boot/systemd.nix @@ -595,18 +595,17 @@ in }; systemd.units = - mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths - // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services - // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices - // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets - // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets - // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers - // listToAttrs (map - (v: let n = escapeSystemdPath v.where; - in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts) - // listToAttrs (map - (v: let n = escapeSystemdPath v.where; - in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); + let + withName = cfgToUnit: cfg: lib.nameValuePair cfg.name (cfgToUnit cfg); + in + mapAttrs' (_: withName pathToUnit) cfg.paths + // mapAttrs' (_: withName serviceToUnit) cfg.services + // mapAttrs' (_: withName sliceToUnit) cfg.slices + // mapAttrs' (_: withName socketToUnit) cfg.sockets + // mapAttrs' (_: withName targetToUnit) cfg.targets + // mapAttrs' (_: withName timerToUnit) cfg.timers + // listToAttrs (map (withName mountToUnit) cfg.mounts) + // listToAttrs (map (withName automountToUnit) cfg.automounts); # Environment of PID 1 systemd.managerEnvironment = { diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index 00441b693d670..cc32b2a15e7ce 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -490,18 +490,18 @@ in { targets.initrd.aliases = ["default.target"]; units = - mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths - // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services - // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices - // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets - // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets - // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers + mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit v)) cfg.paths + // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit v)) cfg.services + // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit v)) cfg.slices + // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit v)) cfg.sockets + // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets + // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers // listToAttrs (map (v: let n = escapeSystemdPath v.where; - in nameValuePair "${n}.mount" (mountToUnit n v)) cfg.mounts) + in nameValuePair "${n}.mount" (mountToUnit v)) cfg.mounts) // listToAttrs (map (v: let n = escapeSystemdPath v.where; - in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts); + in nameValuePair "${n}.automount" (automountToUnit v)) cfg.automounts); # make sure all the /dev nodes are set up services.systemd-tmpfiles-setup-dev.wantedBy = ["sysinit.target"]; diff --git a/nixos/modules/system/boot/systemd/user.nix b/nixos/modules/system/boot/systemd/user.nix index 4c7b51ee22b74..2685cf7e283a2 100644 --- a/nixos/modules/system/boot/systemd/user.nix +++ b/nixos/modules/system/boot/systemd/user.nix @@ -175,12 +175,12 @@ in { }; systemd.user.units = - mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths - // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services - // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices - // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets - // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets - // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers; + mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit v)) cfg.paths + // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit v)) cfg.services + // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit v)) cfg.slices + // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit v)) cfg.sockets + // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit v)) cfg.targets + // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit v)) cfg.timers; # Generate timer units for all services that have a ‘startAt’ value. systemd.user.timers = diff --git a/nixos/modules/virtualisation/containers.nix b/nixos/modules/virtualisation/containers.nix index d726955307861..f5f8a16282d4e 100644 --- a/nixos/modules/virtualisation/containers.nix +++ b/nixos/modules/virtualisation/containers.nix @@ -28,43 +28,6 @@ in description = "Enable the OCI seccomp BPF hook"; }; - cdi = { - dynamic.nvidia.enable = mkOption { - type = types.bool; - default = false; - description = '' - Enable dynamic CDI configuration for NVidia devices by running nvidia-container-toolkit on boot. - ''; - }; - - static = mkOption { - type = types.attrs; - default = { }; - description = '' - Declarative CDI specification. Each key of the attribute set - will be mapped to a file in /etc/cdi. It is required for every - key to be provided in JSON format. - ''; - example = { - some-vendor = builtins.fromJSON '' - { - "cdiVersion": "0.5.0", - "kind": "some-vendor.com/foo", - "devices": [], - "containerEdits": [] - } - ''; - - some-other-vendor = { - cdiVersion = "0.5.0"; - kind = "some-other-vendor.com/bar"; - devices = []; - containerEdits = []; - }; - }; - }; - }; - containersConf.settings = mkOption { type = toml.type; default = { }; @@ -90,13 +53,6 @@ in storage.settings = mkOption { type = toml.type; - default = { - storage = { - driver = "overlay"; - graphroot = "/var/lib/containers/storage"; - runroot = "/run/containers/storage"; - }; - }; description = "storage.conf configuration"; }; @@ -150,8 +106,6 @@ in config = lib.mkIf cfg.enable { - hardware.nvidia-container-toolkit-cdi-generator.enable = lib.mkIf cfg.cdi.dynamic.nvidia.enable true; - virtualisation.containers.containersConf.cniPlugins = [ pkgs.cni-plugins ]; virtualisation.containers.containersConf.settings = { @@ -163,13 +117,13 @@ in }; }; - environment.etc = let - cdiStaticConfigurationFiles = (lib.attrsets.mapAttrs' - (name: value: - lib.attrsets.nameValuePair "cdi/${name}.json" - { text = builtins.toJSON value; }) - cfg.cdi.static); - in { + virtualisation.containers.storage.settings.storage = { + driver = "overlay"; + graphroot = "/var/lib/containers/storage"; + runroot = "/run/containers/storage"; + }; + + environment.etc = { "containers/containers.conf".source = toml.generate "containers.conf" cfg.containersConf.settings; @@ -183,7 +137,7 @@ in "containers/policy.json".source = if cfg.policy != { } then pkgs.writeText "policy.json" (builtins.toJSON cfg.policy) else "${pkgs.skopeo.policy}/default-policy.json"; - } // cdiStaticConfigurationFiles; + }; }; diff --git a/nixos/modules/virtualisation/incus.nix b/nixos/modules/virtualisation/incus.nix index 08e8288fb2038..4d04853d20a56 100644 --- a/nixos/modules/virtualisation/incus.nix +++ b/nixos/modules/virtualisation/incus.nix @@ -9,7 +9,7 @@ let cfg = config.virtualisation.incus; preseedFormat = pkgs.formats.yaml { }; - serverBinPath = ''${pkgs.qemu_kvm}/libexec:${ + serverBinPath = ''/run/wrappers/bin:${pkgs.qemu_kvm}/libexec:${ lib.makeBinPath ( with pkgs; [ @@ -33,29 +33,41 @@ let gzip iproute2 iptables + iw kmod + libnvidia-container + libxfs lvm2 minio + minio-client nftables - qemu_kvm qemu-utils + qemu_kvm rsync + squashfs-tools-ng squashfsTools + sshfs + swtpm systemd thin-provisioning-tools util-linux virtiofsd + xdelta xz + ] + ++ lib.optionals config.security.apparmor.enable [ + apparmor-bin-utils (writeShellScriptBin "apparmor_parser" '' exec '${apparmor-parser}/bin/apparmor_parser' -I '${apparmor-profiles}/etc/apparmor.d' "$@" '') ] + ++ lib.optionals config.services.ceph.client.enable [ ceph-client ] + ++ lib.optionals config.virtualisation.vswitch.enable [ config.virtualisation.vswitch.package ] ++ lib.optionals config.boot.zfs.enabled [ config.boot.zfs.package "${config.boot.zfs.package}/lib/udev" ] - ++ lib.optionals config.virtualisation.vswitch.enable [ config.virtualisation.vswitch.package ] ) }''; @@ -111,7 +123,12 @@ in package = lib.mkPackageOption pkgs "incus-lts" { }; - lxcPackage = lib.mkPackageOption pkgs "lxc" { }; + lxcPackage = lib.mkOption { + type = lib.types.package; + default = config.virtualisation.lxc.package; + defaultText = lib.literalExpression "config.virtualisation.lxc.package"; + description = "The lxc package to use."; + }; clientPackage = lib.mkOption { type = lib.types.package; diff --git a/nixos/modules/virtualisation/lxc.nix b/nixos/modules/virtualisation/lxc.nix index 7d7d48db924f8..1ef322588a68c 100644 --- a/nixos/modules/virtualisation/lxc.nix +++ b/nixos/modules/virtualisation/lxc.nix @@ -32,6 +32,7 @@ in {manpage}`lxc.system.conf(5)`. ''; }; + package = lib.mkPackageOption pkgs "lxc" { }; defaultConfig = lib.mkOption { @@ -57,19 +58,19 @@ in ###### implementation config = lib.mkIf cfg.enable { - environment.systemPackages = [ pkgs.lxc ]; + environment.systemPackages = [ cfg.package ]; environment.etc."lxc/lxc.conf".text = cfg.systemConfig; environment.etc."lxc/lxc-usernet".text = cfg.usernetConfig; environment.etc."lxc/default.conf".text = cfg.defaultConfig; systemd.tmpfiles.rules = [ "d /var/lib/lxc/rootfs 0755 root root -" ]; - security.apparmor.packages = [ pkgs.lxc ]; + security.apparmor.packages = [ cfg.package ]; security.apparmor.policies = { "bin.lxc-start".profile = '' - include ${pkgs.lxc}/etc/apparmor.d/usr.bin.lxc-start + include ${cfg.package}/etc/apparmor.d/usr.bin.lxc-start ''; "lxc-containers".profile = '' - include ${pkgs.lxc}/etc/apparmor.d/lxc-containers + include ${cfg.package}/etc/apparmor.d/lxc-containers ''; }; }; diff --git a/nixos/modules/virtualisation/lxd.nix b/nixos/modules/virtualisation/lxd.nix index 51d9a9482091d..4c94b3dfe946d 100644 --- a/nixos/modules/virtualisation/lxd.nix +++ b/nixos/modules/virtualisation/lxd.nix @@ -35,10 +35,11 @@ in { package = lib.mkPackageOption pkgs "lxd-lts" { }; - lxcPackage = lib.mkPackageOption pkgs "lxc" { - extraDescription = '' - Required for AppArmor profiles. - ''; + lxcPackage = lib.mkOption { + type = lib.types.package; + default = config.virtualisation.lxc.package; + defaultText = lib.literalExpression "config.virtualisation.lxc.package"; + description = "The lxc package to use."; }; zfsSupport = lib.mkOption { diff --git a/nixos/modules/virtualisation/podman/default.nix b/nixos/modules/virtualisation/podman/default.nix index 4b1b67ac9444e..deb0b4d2c5bd7 100644 --- a/nixos/modules/virtualisation/podman/default.nix +++ b/nixos/modules/virtualisation/podman/default.nix @@ -219,6 +219,11 @@ in systemd.services.podman.environment = config.networking.proxy.envVars; systemd.sockets.podman.wantedBy = [ "sockets.target" ]; systemd.sockets.podman.socketConfig.SocketGroup = "podman"; + # Podman does not support multiple sockets, as of podman 5.0.2, so we use + # a symlink. Unfortunately this does not let us use an alternate group, + # such as `docker`. + systemd.sockets.podman.socketConfig.Symlinks = + lib.mkIf cfg.dockerSocket.enable [ "/run/docker.sock" ]; systemd.user.services.podman.environment = config.networking.proxy.envVars; systemd.user.sockets.podman.wantedBy = [ "sockets.target" ]; @@ -239,11 +244,6 @@ in '') ]; - systemd.tmpfiles.rules = - lib.optionals cfg.dockerSocket.enable [ - "L! /run/docker.sock - - - - /run/podman/podman.sock" - ]; - users.groups.podman = { }; assertions = [ diff --git a/nixos/modules/virtualisation/qemu-vm.nix b/nixos/modules/virtualisation/qemu-vm.nix index 06c1253d1fb64..c30f4577fdd86 100644 --- a/nixos/modules/virtualisation/qemu-vm.nix +++ b/nixos/modules/virtualisation/qemu-vm.nix @@ -249,7 +249,7 @@ let ${concatStringsSep " " config.virtualisation.qemu.networkingOptions} \ ${concatStringsSep " \\\n " (mapAttrsToList - (tag: share: "-virtfs local,path=${share.source},security_model=none,mount_tag=${tag}") + (tag: share: "-virtfs local,path=${share.source},security_model=${share.securityModel},mount_tag=${tag}") config.virtualisation.sharedDirectories)} \ ${drivesCmdLine config.virtualisation.qemu.drives} \ ${concatStringsSep " \\\n " config.virtualisation.qemu.options} \ @@ -462,6 +462,18 @@ in type = types.path; description = "The mount point of the directory inside the virtual machine"; }; + options.securityModel = mkOption { + type = types.enum [ "passthrough" "mapped-xattr" "mapped-file" "none" ]; + default = "mapped-xattr"; + description = '' + The security model to use for this share: + + - `passthrough`: files are stored using the same credentials as they are created on the guest (this requires QEMU to run as root) + - `mapped-xattr`: some of the file attributes like uid, gid, mode bits and link target are stored as file attributes + - `mapped-file`: the attributes are stored in the hidden .virtfs_metadata directory. Directories exported by this security model cannot interact with other unix tools + - `none`: same as "passthrough" except the sever won't report failures if it fails to set file attributes like ownership + ''; + }; }); default = { }; example = { @@ -1091,18 +1103,22 @@ in nix-store = mkIf cfg.mountHostNixStore { source = builtins.storeDir; target = "/nix/store"; + securityModel = "none"; }; xchg = { source = ''"$TMPDIR"/xchg''; + securityModel = "none"; target = "/tmp/xchg"; }; shared = { source = ''"''${SHARED_DIR:-$TMPDIR/xchg}"''; target = "/tmp/shared"; + securityModel = "none"; }; certs = mkIf cfg.useHostCerts { source = ''"$TMPDIR"/certs''; target = "/etc/ssl/certs"; + securityModel = "none"; }; }; diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index 39cbe85579ae9..d1773da9afa6f 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -82,7 +82,9 @@ in rec { (onFullSupported "nixos.tests.gitlab") (onFullSupported "nixos.tests.gnome") (onFullSupported "nixos.tests.gnome-xorg") - (onSystems ["x86_64-linux"] "nixos.tests.hibernate") + # FIXME: broken by QEMU 8.2.3 upgrade, reenable when fixed + # Upstream issue: https://gitlab.com/qemu-project/qemu/-/issues/2321 + # (onSystems ["x86_64-linux"] "nixos.tests.hibernate") (onFullSupported "nixos.tests.i3wm") (onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSimple") (onSystems ["x86_64-linux"] "nixos.tests.installer.btrfsSubvolDefault") diff --git a/nixos/tests/adguardhome.nix b/nixos/tests/adguardhome.nix index 80613ce825340..005d54e17dfdc 100644 --- a/nixos/tests/adguardhome.nix +++ b/nixos/tests/adguardhome.nix @@ -2,41 +2,39 @@ name = "adguardhome"; nodes = { - nullConf = { ... }: { services.adguardhome = { enable = true; }; }; + nullConf = { services.adguardhome.enable = true; }; - emptyConf = { lib, ... }: { + emptyConf = { services.adguardhome = { enable = true; + + settings = { }; + }; + }; + + schemaVersionBefore23 = { + services.adguardhome = { + enable = true; + + settings.schema_version = 20; }; }; - declarativeConf = { ... }: { + declarativeConf = { services.adguardhome = { enable = true; mutableSettings = false; - settings = { - schema_version = 0; - dns = { - bind_host = "0.0.0.0"; - bootstrap_dns = "127.0.0.1"; - }; - }; + settings.dns.bootstrap_dns = [ "127.0.0.1" ]; }; }; - mixedConf = { ... }: { + mixedConf = { services.adguardhome = { enable = true; mutableSettings = true; - settings = { - schema_version = 0; - dns = { - bind_host = "0.0.0.0"; - bootstrap_dns = "127.0.0.1"; - }; - }; + settings.dns.bootstrap_dns = [ "127.0.0.1" ]; }; }; @@ -70,11 +68,7 @@ allowDHCP = true; mutableSettings = false; settings = { - schema_version = 0; - dns = { - bind_host = "0.0.0.0"; - bootstrap_dns = "127.0.0.1"; - }; + dns.bootstrap_dns = [ "127.0.0.1" ]; dhcp = { # This implicitly enables CAP_NET_RAW enabled = true; @@ -104,33 +98,38 @@ testScript = '' with subtest("Minimal (settings = null) config test"): - nullConf.wait_for_unit("adguardhome.service") + nullConf.wait_for_unit("adguardhome.service") + nullConf.wait_for_open_port(3000) with subtest("Default config test"): - emptyConf.wait_for_unit("adguardhome.service") - emptyConf.wait_for_open_port(3000) + emptyConf.wait_for_unit("adguardhome.service") + emptyConf.wait_for_open_port(3000) + + with subtest("Default schema_version 23 config test"): + schemaVersionBefore23.wait_for_unit("adguardhome.service") + schemaVersionBefore23.wait_for_open_port(3000) with subtest("Declarative config test, DNS will be reachable"): - declarativeConf.wait_for_unit("adguardhome.service") - declarativeConf.wait_for_open_port(53) - declarativeConf.wait_for_open_port(3000) + declarativeConf.wait_for_unit("adguardhome.service") + declarativeConf.wait_for_open_port(53) + declarativeConf.wait_for_open_port(3000) with subtest("Mixed config test, check whether merging works"): - mixedConf.wait_for_unit("adguardhome.service") - mixedConf.wait_for_open_port(53) - mixedConf.wait_for_open_port(3000) - # Test whether merging works properly, even if nothing is changed - mixedConf.systemctl("restart adguardhome.service") - mixedConf.wait_for_unit("adguardhome.service") - mixedConf.wait_for_open_port(3000) + mixedConf.wait_for_unit("adguardhome.service") + mixedConf.wait_for_open_port(53) + mixedConf.wait_for_open_port(3000) + # Test whether merging works properly, even if nothing is changed + mixedConf.systemctl("restart adguardhome.service") + mixedConf.wait_for_unit("adguardhome.service") + mixedConf.wait_for_open_port(3000) with subtest("Testing successful DHCP start"): - dhcpConf.wait_for_unit("adguardhome.service") - client.systemctl("start network-online.target") - client.wait_for_unit("network-online.target") - # Test IP assignment via DHCP - dhcpConf.wait_until_succeeds("ping -c 5 10.0.10.100") - # Test hostname resolution over DHCP-provided DNS - dhcpConf.wait_until_succeeds("ping -c 5 client.lan") + dhcpConf.wait_for_unit("adguardhome.service") + client.systemctl("start network-online.target") + client.wait_for_unit("network-online.target") + # Test IP assignment via DHCP + dhcpConf.wait_until_succeeds("ping -c 5 10.0.10.100") + # Test hostname resolution over DHCP-provided DNS + dhcpConf.wait_until_succeeds("ping -c 5 client.lan") ''; } diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 232f10d7c24dd..ba876fe31fc04 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -193,6 +193,7 @@ in { cinnamon = handleTest ./cinnamon.nix {}; cinnamon-wayland = handleTest ./cinnamon-wayland.nix {}; cjdns = handleTest ./cjdns.nix {}; + clatd = handleTest ./clatd.nix {}; clickhouse = handleTest ./clickhouse.nix {}; cloud-init = handleTest ./cloud-init.nix {}; cloud-init-hostname = handleTest ./cloud-init-hostname.nix {}; @@ -399,6 +400,7 @@ in { honk = runTest ./honk.nix; installed-tests = pkgs.recurseIntoAttrs (handleTest ./installed-tests {}); invidious = handleTest ./invidious.nix {}; + isolate = handleTest ./isolate.nix {}; livebook-service = handleTest ./livebook-service.nix {}; pyload = handleTest ./pyload.nix {}; oci-containers = handleTestOn ["aarch64-linux" "x86_64-linux"] ./oci-containers.nix {}; @@ -450,6 +452,7 @@ in { jirafeau = handleTest ./jirafeau.nix {}; jitsi-meet = handleTest ./jitsi-meet.nix {}; jool = import ./jool.nix { inherit pkgs runTest; }; + jotta-cli = handleTest ./jotta-cli.nix {}; k3s = handleTest ./k3s {}; kafka = handleTest ./kafka.nix {}; kanidm = handleTest ./kanidm.nix {}; @@ -772,6 +775,7 @@ in { qgis = handleTest ./qgis.nix { qgisPackage = pkgs.qgis; }; qgis-ltr = handleTest ./qgis.nix { qgisPackage = pkgs.qgis-ltr; }; qownnotes = handleTest ./qownnotes.nix {}; + qtile = handleTest ./qtile.nix {}; quake3 = handleTest ./quake3.nix {}; quicktun = handleTest ./quicktun.nix {}; quorum = handleTest ./quorum.nix {}; @@ -782,6 +786,7 @@ in { rasdaemon = handleTest ./rasdaemon.nix {}; readarr = handleTest ./readarr.nix {}; redis = handleTest ./redis.nix {}; + redlib = handleTest ./redlib.nix {}; redmine = handleTest ./redmine.nix {}; restartByActivationScript = handleTest ./restart-by-activation-script.nix {}; restic-rest-server = handleTest ./restic-rest-server.nix {}; @@ -864,6 +869,7 @@ in { swap-partition = handleTest ./swap-partition.nix {}; swap-random-encryption = handleTest ./swap-random-encryption.nix {}; sway = handleTest ./sway.nix {}; + swayfx = handleTest ./swayfx.nix {}; switchTest = handleTest ./switch-test.nix {}; sympa = handleTest ./sympa.nix {}; syncthing = handleTest ./syncthing.nix {}; @@ -941,7 +947,6 @@ in { tiddlywiki = handleTest ./tiddlywiki.nix {}; tigervnc = handleTest ./tigervnc.nix {}; timescaledb = handleTest ./timescaledb.nix {}; - promscale = handleTest ./promscale.nix {}; timezone = handleTest ./timezone.nix {}; tinc = handleTest ./tinc {}; tinydns = handleTest ./tinydns.nix {}; @@ -989,6 +994,7 @@ in { v2ray = handleTest ./v2ray.nix {}; varnish60 = handleTest ./varnish.nix { package = pkgs.varnish60; }; varnish74 = handleTest ./varnish.nix { package = pkgs.varnish74; }; + varnish75 = handleTest ./varnish.nix { package = pkgs.varnish75; }; vault = handleTest ./vault.nix {}; vault-agent = handleTest ./vault-agent.nix {}; vault-dev = handleTest ./vault-dev.nix {}; diff --git a/nixos/tests/castopod.nix b/nixos/tests/castopod.nix index 29bf8e8cacd89..3257cd3d363c7 100644 --- a/nixos/tests/castopod.nix +++ b/nixos/tests/castopod.nix @@ -2,7 +2,7 @@ import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "castopod"; meta = with lib.maintainers; { - maintainers = [ alexoundos misuzu ]; + maintainers = [ alexoundos ]; }; nodes.castopod = { nodes, ... }: { diff --git a/nixos/tests/clatd.nix b/nixos/tests/clatd.nix new file mode 100644 index 0000000000000..00021d87ba5f4 --- /dev/null +++ b/nixos/tests/clatd.nix @@ -0,0 +1,189 @@ +# This test verifies that we can ping an IPv4-only server from an IPv6-only +# client via a NAT64 router using CLAT on the client. The hosts and networks +# are configured as follows: +# +# +------ +# Client | clat Address: 192.0.0.1/32 (configured via clatd) +# | Route: default +# | +# | eth1 Address: 2001:db8::2/64 +# | | Route: default via 2001:db8::1 +# +--|--- +# | VLAN 3 +# +--|--- +# | eth2 Address: 2001:db8::1/64 +# Router | +# | nat64 Address: 64:ff9b::1/128 +# | Route: 64:ff9b::/96 +# | Address: 192.0.2.0/32 +# | Route: 192.0.2.0/24 +# | +# | eth1 Address: 100.64.0.1/24 +# +--|--- +# | VLAN 2 +# +--|--- +# Server | eth1 Address: 100.64.0.2/24 +# | Route: 192.0.2.0/24 via 100.64.0.1 +# +------ + +import ./make-test-python.nix ({ pkgs, lib, ... }: + +{ + name = "clatd"; + meta = with pkgs.lib.maintainers; { + maintainers = [ hax404 ]; + }; + + nodes = { + # The server is configured with static IPv4 addresses. RFC 6052 Section 3.1 + # disallows the mapping of non-global IPv4 addresses like RFC 1918 into the + # Well-Known Prefix 64:ff9b::/96. TAYGA also does not allow the mapping of + # documentation space (RFC 5737). To circumvent this, 100.64.0.2/24 from + # RFC 6589 (Carrier Grade NAT) is used here. + # To reach the IPv4 address pool of the NAT64 gateway, there is a static + # route configured. In normal cases, where the router would also source NAT + # the pool addresses to one IPv4 addresses, this would not be needed. + server = { + virtualisation.vlans = [ + 2 # towards router + ]; + networking = { + useDHCP = false; + interfaces.eth1 = lib.mkForce {}; + }; + systemd.network = { + enable = true; + networks."vlan1" = { + matchConfig.Name = "eth1"; + address = [ + "100.64.0.2/24" + ]; + routes = [ + { routeConfig = { Destination = "192.0.2.0/24"; Gateway = "100.64.0.1"; }; } + ]; + }; + }; + }; + + # The router is configured with static IPv4 addresses towards the server + # and IPv6 addresses towards the client. For NAT64, the Well-Known prefix + # 64:ff9b::/96 is used. NAT64 is done with TAYGA which provides the + # tun-interface nat64 and does the translation over it. The IPv6 packets + # are sent to this interfaces and received as IPv4 packets and vice versa. + # As TAYGA only translates IPv6 addresses to dedicated IPv4 addresses, it + # needs a pool of IPv4 addresses which must be at least as big as the + # expected amount of clients. In this test, the packets from the pool are + # directly routed towards the client. In normal cases, there would be a + # second source NAT44 to map all clients behind one IPv4 address. + router = { + boot.kernel.sysctl = { + "net.ipv4.ip_forward" = 1; + "net.ipv6.conf.all.forwarding" = 1; + }; + + virtualisation.vlans = [ + 2 # towards server + 3 # towards client + ]; + + networking = { + useDHCP = false; + useNetworkd = true; + firewall.enable = false; + interfaces.eth1 = lib.mkForce { + ipv4 = { + addresses = [ { address = "100.64.0.1"; prefixLength = 24; } ]; + }; + }; + interfaces.eth2 = lib.mkForce { + ipv6 = { + addresses = [ { address = "2001:db8::1"; prefixLength = 64; } ]; + }; + }; + }; + + services.tayga = { + enable = true; + ipv4 = { + address = "192.0.2.0"; + router = { + address = "192.0.2.1"; + }; + pool = { + address = "192.0.2.0"; + prefixLength = 24; + }; + }; + ipv6 = { + address = "2001:db8::1"; + router = { + address = "64:ff9b::1"; + }; + pool = { + address = "64:ff9b::"; + prefixLength = 96; + }; + }; + }; + }; + + # The client is configured with static IPv6 addresses. It has also a static + # default route towards the router. To reach the IPv4-only server, the + # client starts the clat daemon which starts and configures the local + # IPv4 -> IPv6 translation via Tayga. + client = { + virtualisation.vlans = [ + 3 # towards router + ]; + + networking = { + useDHCP = false; + interfaces.eth1 = lib.mkForce {}; + }; + + systemd.network = { + enable = true; + networks."vlan1" = { + matchConfig.Name = "eth1"; + address = [ + "2001:db8::2/64" + ]; + routes = [ + { routeConfig = { Destination = "::/0"; Gateway = "2001:db8::1"; }; } + ]; + }; + }; + + services.clatd = { + enable = true; + settings.plat-prefix = "64:ff9b::/96"; + }; + + environment.systemPackages = [ pkgs.mtr ]; + }; + }; + + testScript = '' + start_all() + + # wait for all machines to start up + for machine in client, router, server: + machine.wait_for_unit("network-online.target") + + with subtest("Wait for tayga and clatd"): + router.wait_for_unit("tayga.service") + client.wait_for_unit("clatd.service") + # clatd checks if this system has IPv4 connectivity for 10 seconds + client.wait_until_succeeds( + 'journalctl -u clatd -e | grep -q "Starting up TAYGA, using config file"' + ) + + with subtest("Test ICMP"): + client.wait_until_succeeds("ping -c 3 100.64.0.2 >&2") + + with subtest("Test ICMP and show a traceroute"): + client.wait_until_succeeds("mtr --show-ips --report-wide 100.64.0.2 >&2") + + client.log(client.execute("systemd-analyze security clatd.service")[1]) + ''; +}) diff --git a/nixos/tests/coder.nix b/nixos/tests/coder.nix index 12813827284b9..fd1fa0cc3031f 100644 --- a/nixos/tests/coder.nix +++ b/nixos/tests/coder.nix @@ -1,8 +1,6 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "coder"; - meta = with pkgs.lib.maintainers; { - maintainers = [ shyim ghuntley ]; - }; + meta.maintainers = pkgs.coder.meta.maintainers; nodes.machine = { pkgs, ... }: diff --git a/nixos/tests/forgejo.nix b/nixos/tests/forgejo.nix index 8b9ee46ff5d32..827fae2790c6e 100644 --- a/nixos/tests/forgejo.nix +++ b/nixos/tests/forgejo.nix @@ -141,9 +141,9 @@ let assert "BEGIN PGP PUBLIC KEY BLOCK" in server.succeed("curl http://localhost:3000/api/v1/signing-key.gpg") api_version = json.loads(server.succeed("curl http://localhost:3000/api/forgejo/v1/version")).get("version") - assert "development" != api_version and "-gitea-" in api_version, ( + assert "development" != api_version and "${pkgs.forgejo.version}+gitea-" in api_version, ( "/api/forgejo/v1/version should not return 'development' " - + f"but should contain a gitea compatibility version string. Got '{api_version}' instead." + + f"but should contain a forgejo+gitea compatibility version string. Got '{api_version}' instead." ) server.succeed( @@ -152,7 +152,7 @@ let ) server.succeed( "su -l forgejo -c 'GITEA_WORK_DIR=/var/lib/forgejo gitea admin user create " - + "--username test --password totallysafe --email test@localhost'" + + "--username test --password totallysafe --email test@localhost --must-change-password=false'" ) api_token = server.succeed( diff --git a/nixos/tests/gvisor.nix b/nixos/tests/gvisor.nix index 7f130b709fc9d..5c9447b07118d 100644 --- a/nixos/tests/gvisor.nix +++ b/nixos/tests/gvisor.nix @@ -3,7 +3,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "gvisor"; meta = with pkgs.lib.maintainers; { - maintainers = [ andrew-d ]; + maintainers = [ ]; }; nodes = { diff --git a/nixos/tests/incus/virtual-machine.nix b/nixos/tests/incus/virtual-machine.nix index 48178aaed32c4..eebbbd113ed16 100644 --- a/nixos/tests/incus/virtual-machine.nix +++ b/nixos/tests/incus/virtual-machine.nix @@ -30,6 +30,9 @@ in memorySize = 1024; diskSize = 4096; + # Provide a TPM to test vTPM support for guests + tpm.enable = true; + incus.enable = true; }; networking.nftables.enable = true; @@ -47,8 +50,14 @@ in with subtest("virtual-machine image can be imported"): machine.succeed("incus image import ${vm-image-metadata}/*/*.tar.xz ${vm-image-disk}/nixos.qcow2 --alias nixos") + with subtest("virtual-machine can be created"): + machine.succeed("incus create nixos ${instance-name} --vm --config limits.memory=512MB --config security.secureboot=false") + + with subtest("virtual tpm can be configured"): + machine.succeed("incus config device add ${instance-name} vtpm tpm path=/dev/tpm0") + with subtest("virtual-machine can be launched and become available"): - machine.succeed("incus launch nixos ${instance-name} --vm --config limits.memory=512MB --config security.secureboot=false") + machine.succeed("incus start ${instance-name}") with machine.nested("Waiting for instance to start and be usable"): retry(instance_is_up) diff --git a/nixos/tests/installed-tests/default.nix b/nixos/tests/installed-tests/default.nix index e87edb2007e93..b1ddfe3dcbd80 100644 --- a/nixos/tests/installed-tests/default.nix +++ b/nixos/tests/installed-tests/default.nix @@ -1,5 +1,5 @@ # NixOS tests for gnome-desktop-testing-runner using software -# See https://wiki.gnome.org/Initiatives/GnomeGoals/InstalledTests +# See https://github.com/NixOS/nixpkgs/issues/34987 { system ? builtins.currentSystem, config ? {}, diff --git a/nixos/tests/installed-tests/gnome-photos.nix b/nixos/tests/installed-tests/gnome-photos.nix index bcb6479ee89c6..010ad97024026 100644 --- a/nixos/tests/installed-tests/gnome-photos.nix +++ b/nixos/tests/installed-tests/gnome-photos.nix @@ -13,7 +13,7 @@ makeInstalledTest { (stdenv.mkDerivation { name = "desktop-gsettings"; dontUnpack = true; - nativeBuildInputs = [ glib wrapGAppsHook ]; + nativeBuildInputs = [ glib wrapGAppsHook3 ]; buildInputs = [ gsettings-desktop-schemas ]; installPhase = '' runHook preInstall diff --git a/nixos/tests/isolate.nix b/nixos/tests/isolate.nix new file mode 100644 index 0000000000000..327231be1cd4a --- /dev/null +++ b/nixos/tests/isolate.nix @@ -0,0 +1,38 @@ +import ./make-test-python.nix ({ lib, ... }: +{ + name = "isolate"; + meta.maintainers = with lib.maintainers; [ virchau13 ]; + + nodes.machine = + { ... }: + { + security.isolate = { + enable = true; + }; + }; + + testScript = '' + bash_path = machine.succeed('realpath $(which bash)').strip() + sleep_path = machine.succeed('realpath $(which sleep)').strip() + def sleep_test(walltime, sleeptime): + return f'isolate --no-default-dirs --wall-time {walltime} ' + \ + f'--dir=/box={box_path} --dir=/nix=/nix --run -- ' + \ + f"{bash_path} -c 'exec -a sleep {sleep_path} {sleeptime}'" + + def sleep_test_cg(walltime, sleeptime): + return f'isolate --cg --no-default-dirs --wall-time {walltime} ' + \ + f'--dir=/box={box_path} --dir=/nix=/nix --processes=2 --run -- ' + \ + f"{bash_path} -c '( exec -a sleep {sleep_path} {sleeptime} )'" + + with subtest("without cgroups"): + box_path = machine.succeed('isolate --init').strip() + machine.succeed(sleep_test(1, 0.5)) + machine.fail(sleep_test(0.5, 1)) + machine.succeed('isolate --cleanup') + with subtest("with cgroups"): + box_path = machine.succeed('isolate --cg --init').strip() + machine.succeed(sleep_test_cg(1, 0.5)) + machine.fail(sleep_test_cg(0.5, 1)) + machine.succeed('isolate --cg --cleanup') + ''; +}) diff --git a/nixos/tests/jotta-cli.nix b/nixos/tests/jotta-cli.nix new file mode 100644 index 0000000000000..5eefe65c1d385 --- /dev/null +++ b/nixos/tests/jotta-cli.nix @@ -0,0 +1,25 @@ +import ./make-test-python.nix ({ pkgs, ... }: { + + name = "jotta-cli"; + meta.maintainers = with pkgs.lib.maintainers; [ evenbrenden ]; + + nodes.machine = { pkgs, ... }: { + user.services.jotta-cli.enable = true; + imports = [ ./common/user-account.nix ]; + }; + + testScript = { nodes, ... }: + let uid = toString nodes.machine.users.users.alice.uid; + in '' + machine.start() + + machine.succeed("loginctl enable-linger alice") + machine.wait_for_unit("user@${uid}.service") + + machine.wait_for_unit("jottad.service", "alice") + machine.wait_for_open_unix_socket("/run/user/${uid}/jottad/jottad.socket") + + # "jotta-cli version" should fail if jotta-cli cannot connect to jottad + machine.succeed('XDG_RUNTIME_DIR=/run/user/${uid} su alice -c "jotta-cli version"') + ''; +}) diff --git a/nixos/tests/kanidm.nix b/nixos/tests/kanidm.nix index fa24d4a8a5e13..8ed9af63f1d41 100644 --- a/nixos/tests/kanidm.nix +++ b/nixos/tests/kanidm.nix @@ -76,14 +76,17 @@ import ./make-test-python.nix ({ pkgs, ... }: with subtest("Test LDAP interface"): server.succeed("ldapsearch -H ldaps://${serverDomain}:636 -b '${ldapBaseDN}' -x '(name=test)'") - with subtest("Test CLI login"): - client.succeed("kanidm login -D anonymous") - client.succeed("kanidm self whoami | grep anonymous@${serverDomain}") - client.succeed("kanidm logout") - with subtest("Recover idm_admin account"): idm_admin_password = server.succeed("su - kanidm -c 'kanidmd recover-account -c ${serverConfigFile} idm_admin 2>&1 | rg -o \'[A-Za-z0-9]{48}\' '").strip().removeprefix("'").removesuffix("'") + with subtest("Test CLI login"): + client.wait_until_tty_matches("1", "login: ") + client.send_chars("root\n") + client.send_chars("kanidm login -D idm_admin\n") + client.wait_until_tty_matches("1", "Enter password: ") + client.send_chars(f"{idm_admin_password}\n") + client.wait_until_tty_matches("1", "Login Success for idm_admin") + with subtest("Test unixd connection"): client.wait_for_unit("kanidm-unixd.service") client.wait_for_file("/run/kanidm-unixd/sock") @@ -92,12 +95,6 @@ import ./make-test-python.nix ({ pkgs, ... }: with subtest("Test user creation"): client.wait_for_unit("getty@tty1.service") client.wait_until_succeeds("pgrep -f 'agetty.*tty1'") - client.wait_until_tty_matches("1", "login: ") - client.send_chars("root\n") - client.send_chars("kanidm login -D idm_admin\n") - client.wait_until_tty_matches("1", "Enter password: ") - client.send_chars(f"{idm_admin_password}\n") - client.wait_until_tty_matches("1", "Login Success for idm_admin") client.succeed("kanidm person create testuser TestUser") client.succeed("kanidm person posix set --shell \"$SHELL\" testuser") client.send_chars("kanidm person posix set-password testuser\n") diff --git a/nixos/tests/libinput.nix b/nixos/tests/libinput.nix index 9b6fa159b999c..b002492b16657 100644 --- a/nixos/tests/libinput.nix +++ b/nixos/tests/libinput.nix @@ -12,7 +12,7 @@ import ./make-test-python.nix ({ ... }: test-support.displayManager.auto.user = "alice"; - services.xserver.libinput = { + services.libinput = { enable = true; mouse = { naturalScrolling = true; diff --git a/nixos/tests/libreswan.nix b/nixos/tests/libreswan.nix index aadba941fab17..c798a04645bc0 100644 --- a/nixos/tests/libreswan.nix +++ b/nixos/tests/libreswan.nix @@ -119,11 +119,11 @@ in with subtest("Libreswan is ready"): alice.wait_for_unit("ipsec") bob.wait_for_unit("ipsec") - alice.succeed("ipsec verify 1>&2") + alice.succeed("ipsec checkconfig") with subtest("Alice and Bob can start the tunnel"): - alice.execute("ipsec auto --start tunnel >&2 &") - bob.succeed("ipsec auto --start tunnel") + alice.execute("ipsec start tunnel >&2 &") + bob.succeed("ipsec start tunnel") # apparently this is needed to "wake" the tunnel bob.execute("ping -c1 alice") diff --git a/nixos/tests/nextcloud/default.nix b/nixos/tests/nextcloud/default.nix index 84ac371537271..d024adffd9f06 100644 --- a/nixos/tests/nextcloud/default.nix +++ b/nixos/tests/nextcloud/default.nix @@ -22,4 +22,4 @@ foldl }; }) { } - [ 26 27 28 ] + [ 27 28 29 ] diff --git a/nixos/tests/nginx-sso.nix b/nixos/tests/nginx-sso.nix index 221c5f4ed9058..2bb9c7a1c3bb7 100644 --- a/nixos/tests/nginx-sso.nix +++ b/nixos/tests/nginx-sso.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "nginx-sso"; meta = { - maintainers = with pkgs.lib.maintainers; [ delroth ]; + maintainers = with pkgs.lib.maintainers; [ ambroisie ]; }; nodes.machine = { diff --git a/nixos/tests/openssh.nix b/nixos/tests/openssh.nix index 8074fd2ed4838..2684b6f45e84e 100644 --- a/nixos/tests/openssh.nix +++ b/nixos/tests/openssh.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: let inherit (import ./ssh-keys.nix pkgs) - snakeOilPrivateKey snakeOilPublicKey; + snakeOilPrivateKey snakeOilPublicKey snakeOilEd25519PrivateKey snakeOilEd25519PublicKey; in { name = "openssh"; meta = with pkgs.lib.maintainers; { @@ -22,6 +22,19 @@ in { ]; }; + server-allowed-users = + { ... }: + + { + services.openssh = { enable = true; settings.AllowUsers = [ "alice" "bob" ]; }; + users.groups = { alice = { }; bob = { }; carol = { }; }; + users.users = { + alice = { isNormalUser = true; group = "alice"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; + bob = { isNormalUser = true; group = "bob"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; + carol = { isNormalUser = true; group = "carol"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; + }; + }; + server-lazy = { ... }: @@ -95,17 +108,46 @@ in { }; }; - server_allowedusers = + server-no-openssl = { ... }: + { + programs.ssh.package = pkgs.opensshPackages.openssh.override { + linkOpenssl = false; + }; + services.openssh = { + enable = true; + hostKeys = [ + { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; } + ]; + settings = { + # Must not specify the OpenSSL provided algorithms. + Ciphers = [ "chacha20-poly1305@openssh.com" ]; + KexAlgorithms = [ + "curve25519-sha256" + "curve25519-sha256@libssh.org" + ]; + }; + }; + users.users.root.openssh.authorizedKeys.keys = [ + snakeOilEd25519PublicKey + ]; + }; + server-no-pam = + { pkgs, ... }: { - services.openssh = { enable = true; settings.AllowUsers = [ "alice" "bob" ]; }; - users.groups = { alice = { }; bob = { }; carol = { }; }; - users.users = { - alice = { isNormalUser = true; group = "alice"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; - bob = { isNormalUser = true; group = "bob"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; - carol = { isNormalUser = true; group = "carol"; openssh.authorizedKeys.keys = [ snakeOilPublicKey ]; }; + programs.ssh.package = pkgs.opensshPackages.openssh.override { + withPAM = false; + }; + services.openssh = { + enable = true; + settings = { + UsePAM = false; + }; }; + users.users.root.openssh.authorizedKeys.keys = [ + snakeOilPublicKey + ]; }; client = @@ -119,8 +161,11 @@ in { start_all() server.wait_for_unit("sshd", timeout=30) + server_allowed_users.wait_for_unit("sshd", timeout=30) server_localhost_only.wait_for_unit("sshd", timeout=30) server_match_rule.wait_for_unit("sshd", timeout=30) + server_no_openssl.wait_for_unit("sshd", timeout=30) + server_no_pam.wait_for_unit("sshd", timeout=30) server_lazy.wait_for_unit("sshd.socket", timeout=30) server_localhost_only_lazy.wait_for_unit("sshd.socket", timeout=30) @@ -166,8 +211,9 @@ in { "cat ${snakeOilPrivateKey} > privkey.snakeoil" ) client.succeed("chmod 600 privkey.snakeoil") + # The final segment in this IP is allocated according to the alphabetical order of machines in this test. client.succeed( - "ssh -p 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil root@192.168.2.4 true", + "ssh -p 2222 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil root@192.168.2.5 true", timeout=30 ) @@ -198,15 +244,35 @@ in { ) client.succeed("chmod 600 privkey.snakeoil") client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil alice@server_allowedusers true", + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil alice@server-allowed-users true", timeout=30 ) client.succeed( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil bob@server_allowedusers true", + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil bob@server-allowed-users true", timeout=30 ) client.fail( - "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil carol@server_allowedusers true", + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil carol@server-allowed-users true", + timeout=30 + ) + + with subtest("no-openssl"): + client.succeed( + "cat ${snakeOilEd25519PrivateKey} > privkey.snakeoil" + ) + client.succeed("chmod 600 privkey.snakeoil") + client.succeed( + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server-no-openssl true", + timeout=30 + ) + + with subtest("no-pam"): + client.succeed( + "cat ${snakeOilPrivateKey} > privkey.snakeoil" + ) + client.succeed("chmod 600 privkey.snakeoil") + client.succeed( + "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server-no-pam true", timeout=30 ) ''; diff --git a/nixos/tests/postgresql-jit.nix b/nixos/tests/postgresql-jit.nix index baf26b8da2b39..f4b1d07a7faf8 100644 --- a/nixos/tests/postgresql-jit.nix +++ b/nixos/tests/postgresql-jit.nix @@ -1,6 +1,7 @@ { system ? builtins.currentSystem , config ? {} , pkgs ? import ../.. { inherit system config; } +, package ? null }: with import ../lib/testing-python.nix { inherit system pkgs; }; @@ -9,14 +10,17 @@ let inherit (pkgs) lib; packages = builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs); - mkJitTest = packageName: makeTest { - name = "${packageName}"; + mkJitTestFromName = name: + mkJitTest pkgs.${name}; + + mkJitTest = package: makeTest { + name = package.name; meta.maintainers = with lib.maintainers; [ ma27 ]; nodes.machine = { pkgs, lib, ... }: { services.postgresql = { + inherit package; enable = true; enableJIT = true; - package = pkgs.${packageName}; initialScript = pkgs.writeText "init.sql" '' create table demo (id int); insert into demo (id) select generate_series(1, 5); @@ -45,4 +49,7 @@ let ''; }; in -lib.genAttrs packages mkJitTest +if package == null then + lib.genAttrs packages mkJitTestFromName +else + mkJitTest package diff --git a/nixos/tests/postgresql-wal-receiver.nix b/nixos/tests/postgresql-wal-receiver.nix index b0bd7711dbcd9..ab2ab4ad0d4fa 100644 --- a/nixos/tests/postgresql-wal-receiver.nix +++ b/nixos/tests/postgresql-wal-receiver.nix @@ -1,6 +1,7 @@ { system ? builtins.currentSystem, config ? {}, - pkgs ? import ../.. { inherit system config; } + pkgs ? import ../.. { inherit system config; }, + package ? null }: with import ../lib/testing-python.nix { inherit system pkgs; }; @@ -9,111 +10,110 @@ let lib = pkgs.lib; # Makes a test for a PostgreSQL package, given by name and looked up from `pkgs`. - makePostgresqlWalReceiverTest = postgresqlPackage: + makeTestAttribute = name: { - name = postgresqlPackage; - value = - let - pkg = pkgs."${postgresqlPackage}"; - postgresqlDataDir = "/var/lib/postgresql/${pkg.psqlSchema}"; - replicationUser = "wal_receiver_user"; - replicationSlot = "wal_receiver_slot"; - replicationConn = "postgresql://${replicationUser}@localhost"; - baseBackupDir = "/tmp/pg_basebackup"; - walBackupDir = "/tmp/pg_wal"; - atLeast12 = lib.versionAtLeast pkg.version "12.0"; - - recoveryFile = if atLeast12 - then pkgs.writeTextDir "recovery.signal" "" - else pkgs.writeTextDir "recovery.conf" "restore_command = 'cp ${walBackupDir}/%f %p'"; - - in makeTest { - name = "postgresql-wal-receiver-${postgresqlPackage}"; - meta.maintainers = with lib.maintainers; [ pacien ]; - - nodes.machine = { ... }: { - services.postgresql = { - package = pkg; - enable = true; - settings = lib.mkMerge [ - { - wal_level = "archive"; # alias for replica on pg >= 9.6 - max_wal_senders = 10; - max_replication_slots = 10; - } - (lib.mkIf atLeast12 { - restore_command = "cp ${walBackupDir}/%f %p"; - recovery_end_command = "touch recovery.done"; - }) - ]; - authentication = '' - host replication ${replicationUser} all trust - ''; - initialScript = pkgs.writeText "init.sql" '' - create user ${replicationUser} replication; - select * from pg_create_physical_replication_slot('${replicationSlot}'); - ''; - }; + inherit name; + value = makePostgresqlWalReceiverTest pkgs."${name}"; + }; + + makePostgresqlWalReceiverTest = pkg: + let + postgresqlDataDir = "/var/lib/postgresql/${pkg.psqlSchema}"; + replicationUser = "wal_receiver_user"; + replicationSlot = "wal_receiver_slot"; + replicationConn = "postgresql://${replicationUser}@localhost"; + baseBackupDir = "/tmp/pg_basebackup"; + walBackupDir = "/tmp/pg_wal"; + + recoveryFile = pkgs.writeTextDir "recovery.signal" ""; - services.postgresqlWalReceiver.receivers.main = { - postgresqlPackage = pkg; - connection = replicationConn; - slot = replicationSlot; - directory = walBackupDir; + in makeTest { + name = "postgresql-wal-receiver-${pkg.name}"; + meta.maintainers = with lib.maintainers; [ pacien ]; + + nodes.machine = { ... }: { + services.postgresql = { + package = pkg; + enable = true; + settings = { + max_replication_slots = 10; + max_wal_senders = 10; + recovery_end_command = "touch recovery.done"; + restore_command = "cp ${walBackupDir}/%f %p"; + wal_level = "archive"; # alias for replica on pg >= 9.6 }; - # This is only to speedup test, it isn't time racing. Service is set to autorestart always, - # default 60sec is fine for real system, but is too much for a test - systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5; + authentication = '' + host replication ${replicationUser} all trust + ''; + initialScript = pkgs.writeText "init.sql" '' + create user ${replicationUser} replication; + select * from pg_create_physical_replication_slot('${replicationSlot}'); + ''; }; - testScript = '' - # make an initial base backup - machine.wait_for_unit("postgresql") - machine.wait_for_unit("postgresql-wal-receiver-main") - # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other - # required only for 9.4 - machine.sleep(5) - machine.succeed( - "${pkg}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}" - ) - - # create a dummy table with 100 records - machine.succeed( - "sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'" - ) - - # stop postgres and destroy data - machine.systemctl("stop postgresql") - machine.systemctl("stop postgresql-wal-receiver-main") - machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}") - - # restore the base backup - machine.succeed( - "cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}" - ) - - # prepare WAL and recovery - machine.succeed("chmod a+rX -R ${walBackupDir}") - machine.execute( - "for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done" - ) # make use of partial segments too - machine.succeed( - "cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*" - ) - - # replay WAL - machine.systemctl("start postgresql") - machine.wait_for_file("${postgresqlDataDir}/recovery.done") - machine.systemctl("restart postgresql") - machine.wait_for_unit("postgresql") - - # check that our records have been restored - machine.succeed( - "test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100" - ) - ''; + services.postgresqlWalReceiver.receivers.main = { + postgresqlPackage = pkg; + connection = replicationConn; + slot = replicationSlot; + directory = walBackupDir; + }; + # This is only to speedup test, it isn't time racing. Service is set to autorestart always, + # default 60sec is fine for real system, but is too much for a test + systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5; }; + + testScript = '' + # make an initial base backup + machine.wait_for_unit("postgresql") + machine.wait_for_unit("postgresql-wal-receiver-main") + # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other + # required only for 9.4 + machine.sleep(5) + machine.succeed( + "${pkg}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}" + ) + + # create a dummy table with 100 records + machine.succeed( + "sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'" + ) + + # stop postgres and destroy data + machine.systemctl("stop postgresql") + machine.systemctl("stop postgresql-wal-receiver-main") + machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}") + + # restore the base backup + machine.succeed( + "cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}" + ) + + # prepare WAL and recovery + machine.succeed("chmod a+rX -R ${walBackupDir}") + machine.execute( + "for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done" + ) # make use of partial segments too + machine.succeed( + "cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*" + ) + + # replay WAL + machine.systemctl("start postgresql") + machine.wait_for_file("${postgresqlDataDir}/recovery.done") + machine.systemctl("restart postgresql") + machine.wait_for_unit("postgresql") + + # check that our records have been restored + machine.succeed( + "test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100" + ) + ''; }; -# Maps the generic function over all attributes of PostgreSQL packages -in builtins.listToAttrs (map makePostgresqlWalReceiverTest (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs))) +in +if package == null then + # all-tests.nix: Maps the generic function over all attributes of PostgreSQL packages + builtins.listToAttrs (map makeTestAttribute (builtins.attrNames (import ../../pkgs/servers/sql/postgresql pkgs))) +else + # Called directly from <package>.tests + makePostgresqlWalReceiverTest package diff --git a/nixos/tests/prometheus-exporters.nix b/nixos/tests/prometheus-exporters.nix index 576253450814f..56569c4de2c85 100644 --- a/nixos/tests/prometheus-exporters.nix +++ b/nixos/tests/prometheus-exporters.nix @@ -907,7 +907,7 @@ let attrs = { objectClass = [ "olcDatabaseConfig" "olcMdbConfig" ]; olcDatabase = "{1}mdb"; - olcDbDirectory = "/var/db/openldap"; + olcDbDirectory = "/var/lib/openldap/db"; olcSuffix = "dc=example"; olcRootDN = { # cn=root,dc=example diff --git a/nixos/tests/promscale.nix b/nixos/tests/promscale.nix deleted file mode 100644 index da18628f2482c..0000000000000 --- a/nixos/tests/promscale.nix +++ /dev/null @@ -1,60 +0,0 @@ -# mostly copied from ./timescaledb.nix which was copied from ./postgresql.nix -# as it seemed unapproriate to test additional extensions for postgresql there. - -{ system ? builtins.currentSystem -, config ? { } -, pkgs ? import ../.. { inherit system config; } -}: - -with import ../lib/testing-python.nix { inherit system pkgs; }; -with pkgs.lib; - -let - postgresql-versions = import ../../pkgs/servers/sql/postgresql pkgs; - test-sql = pkgs.writeText "postgresql-test" '' - CREATE USER promscale SUPERUSER PASSWORD 'promscale'; - CREATE DATABASE promscale OWNER promscale; - ''; - - make-postgresql-test = postgresql-name: postgresql-package: makeTest { - name = postgresql-name; - meta = with pkgs.lib.maintainers; { - maintainers = [ anpin ]; - }; - - nodes.machine = { config, pkgs, ... }: - { - services.postgresql = { - enable = true; - package = postgresql-package; - extraPlugins = ps: with ps; [ - timescaledb - promscale_extension - ]; - settings = { shared_preload_libraries = "timescaledb, promscale"; }; - }; - environment.systemPackages = with pkgs; [ promscale ]; - }; - - testScript = '' - machine.start() - machine.wait_for_unit("postgresql") - with subtest("Postgresql with extensions timescaledb and promscale is available just after unit start"): - print(machine.succeed("sudo -u postgres psql -f ${test-sql}")) - machine.succeed("sudo -u postgres psql promscale -c 'SHOW shared_preload_libraries;' | grep promscale") - machine.succeed( - "promscale --db.name promscale --db.password promscale --db.user promscale --db.ssl-mode allow --startup.install-extensions --startup.only" - ) - machine.succeed("sudo -u postgres psql promscale -c 'SELECT ps_trace.get_trace_retention_period();' | grep '(1 row)'") - machine.shutdown() - ''; - }; - #version 15 is not supported yet - applicablePostgresqlVersions = filterAttrs (_: value: versionAtLeast value.version "12" && !(versionAtLeast value.version "15")) postgresql-versions; -in -mapAttrs' - (name: package: { - inherit name; - value = make-postgresql-test name package; - }) - applicablePostgresqlVersions diff --git a/nixos/tests/qtile.nix b/nixos/tests/qtile.nix new file mode 100644 index 0000000000000..b4d8f9d421144 --- /dev/null +++ b/nixos/tests/qtile.nix @@ -0,0 +1,34 @@ +import ./make-test-python.nix ({ lib, ...} : { + name = "qtile"; + + meta = { + maintainers = with lib.maintainers; [ sigmanificient ]; + }; + + nodes.machine = { pkgs, lib, ... }: { + imports = [ ./common/x11.nix ./common/user-account.nix ]; + test-support.displayManager.auto.user = "alice"; + + services.xserver.windowManager.qtile.enable = true; + services.displayManager.defaultSession = lib.mkForce "none+qtile"; + + environment.systemPackages = [ pkgs.kitty ]; + }; + + testScript = '' + with subtest("ensure x starts"): + machine.wait_for_x() + machine.wait_for_file("/home/alice/.Xauthority") + machine.succeed("xauth merge ~alice/.Xauthority") + + with subtest("ensure client is available"): + machine.succeed("qtile --version") + + with subtest("ensure we can open a new terminal"): + machine.sleep(2) + machine.send_key("meta_l-ret") + machine.wait_for_window(r"alice.*?machine") + machine.sleep(2) + machine.screenshot("terminal") + ''; +}) diff --git a/nixos/tests/ssh-keys.nix b/nixos/tests/ssh-keys.nix index df9ff38a3b22a..675f3a0b43947 100644 --- a/nixos/tests/ssh-keys.nix +++ b/nixos/tests/ssh-keys.nix @@ -12,4 +12,16 @@ pkgs: "yNTYAAABBBChdA2BmwcG49OrQN33f/sj+OHL5sJhwVl2Qim0vkUJQCry1zFpKTa" "9ZcDMiWaEhoAR6FGoaGI04ff7CS+1yybQ= snakeoil" ]; + + snakeOilEd25519PrivateKey = pkgs.writeText "privkey.snakeoil" '' + -----BEGIN OPENSSH PRIVATE KEY----- + b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW + QyNTUxOQAAACAYBTIWo1J4PkY4/7AhVyPT8xvAUI67tp+yYFFRdSm7+QAAAJC89yCivPcg + ogAAAAtzc2gtZWQyNTUxOQAAACAYBTIWo1J4PkY4/7AhVyPT8xvAUI67tp+yYFFRdSm7+Q + AAAEDJmKp3lX6Pz0unTc0QZwrHb8Eyr9fJUopE9d2/+q+eCxgFMhajUng+Rjj/sCFXI9Pz + G8BQjru2n7JgUVF1Kbv5AAAACnRvbUBvemRlc2sBAgM= + -----END OPENSSH PRIVATE KEY----- + ''; + + snakeOilEd25519PublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBgFMhajUng+Rjj/sCFXI9PzG8BQjru2n7JgUVF1Kbv5 snakeoil"; } diff --git a/nixos/tests/swayfx.nix b/nixos/tests/swayfx.nix new file mode 100644 index 0000000000000..77844ec80ae1d --- /dev/null +++ b/nixos/tests/swayfx.nix @@ -0,0 +1,207 @@ +import ./make-test-python.nix ( + { pkgs, lib, ... }: + { + name = "swayfx"; + meta = { + maintainers = with lib.maintainers; [ eclairevoyant ]; + }; + + # testScriptWithTypes:49: error: Cannot call function of unknown type + # (machine.succeed if succeed else machine.execute)( + # ^ + # Found 1 error in 1 file (checked 1 source file) + skipTypeCheck = true; + + nodes.machine = + { config, ... }: + { + # Automatically login on tty1 as a normal user: + imports = [ ./common/user-account.nix ]; + services.getty.autologinUser = "alice"; + + environment = { + # For glinfo and wayland-info: + systemPackages = with pkgs; [ + mesa-demos + wayland-utils + alacritty + ]; + # Use a fixed SWAYSOCK path (for swaymsg): + variables = { + "SWAYSOCK" = "/tmp/sway-ipc.sock"; + # TODO: Investigate if we can get hardware acceleration to work (via + # virtio-gpu and Virgil). We currently have to use the Pixman software + # renderer since the GLES2 renderer doesn't work inside the VM (even + # with WLR_RENDERER_ALLOW_SOFTWARE): + # "WLR_RENDERER_ALLOW_SOFTWARE" = "1"; + "WLR_RENDERER" = "pixman"; + }; + # For convenience: + shellAliases = { + test-x11 = "glinfo | tee /tmp/test-x11.out && touch /tmp/test-x11-exit-ok"; + test-wayland = "wayland-info | tee /tmp/test-wayland.out && touch /tmp/test-wayland-exit-ok"; + }; + + # To help with OCR: + etc."xdg/foot/foot.ini".text = lib.generators.toINI { } { + main = { + font = "inconsolata:size=14"; + }; + colors = rec { + foreground = "000000"; + background = "ffffff"; + regular2 = foreground; + }; + }; + + etc."gpg-agent.conf".text = '' + pinentry-timeout 86400 + ''; + }; + + fonts.packages = [ pkgs.inconsolata ]; + + # Automatically configure and start Sway when logging in on tty1: + programs.bash.loginShellInit = '' + if [ "$(tty)" = "/dev/tty1" ]; then + set -e + + mkdir -p ~/.config/sway + sed s/Mod4/Mod1/ /etc/sway/config > ~/.config/sway/config + + sway --validate + sway && touch /tmp/sway-exit-ok + fi + ''; + + programs.sway = { + enable = true; + package = pkgs.swayfx.override { isNixOS = true; }; + }; + + # To test pinentry via gpg-agent: + programs.gnupg.agent.enable = true; + + # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch: + virtualisation.qemu.options = [ "-vga none -device virtio-gpu-pci" ]; + }; + + testScript = + { nodes, ... }: + '' + import shlex + import json + + q = shlex.quote + NODE_GROUPS = ["nodes", "floating_nodes"] + + + def swaymsg(command: str = "", succeed=True, type="command"): + assert command != "" or type != "command", "Must specify command or type" + shell = q(f"swaymsg -t {q(type)} -- {q(command)}") + with machine.nested( + f"sending swaymsg {shell!r}" + " (allowed to fail)" * (not succeed) + ): + ret = (machine.succeed if succeed else machine.execute)( + f"su - alice -c {shell}" + ) + + # execute also returns a status code, but disregard. + if not succeed: + _, ret = ret + + if not succeed and not ret: + return None + + parsed = json.loads(ret) + return parsed + + + def walk(tree): + yield tree + for group in NODE_GROUPS: + for node in tree.get(group, []): + yield from walk(node) + + + def wait_for_window(pattern): + def func(last_chance): + nodes = (node["name"] for node in walk(swaymsg(type="get_tree"))) + + if last_chance: + nodes = list(nodes) + machine.log(f"Last call! Current list of windows: {nodes}") + + return any(pattern in name for name in nodes) + + retry(func) + + start_all() + machine.wait_for_unit("multi-user.target") + + # To check the version: + print(machine.succeed("sway --version")) + + # Wait for Sway to complete startup: + machine.wait_for_file("/run/user/1000/wayland-1") + machine.wait_for_file("/tmp/sway-ipc.sock") + + # Test XWayland (foot does not support X): + swaymsg("exec WINIT_UNIX_BACKEND=x11 WAYLAND_DISPLAY= alacritty") + wait_for_window("alice@machine") + machine.send_chars("test-x11\n") + machine.wait_for_file("/tmp/test-x11-exit-ok") + print(machine.succeed("cat /tmp/test-x11.out")) + machine.copy_from_vm("/tmp/test-x11.out") + machine.screenshot("alacritty_glinfo") + machine.succeed("pkill alacritty") + + # Start a terminal (foot) on workspace 3: + machine.send_key("alt-3") + machine.sleep(3) + machine.send_key("alt-ret") + wait_for_window("alice@machine") + machine.send_chars("test-wayland\n") + machine.wait_for_file("/tmp/test-wayland-exit-ok") + print(machine.succeed("cat /tmp/test-wayland.out")) + machine.copy_from_vm("/tmp/test-wayland.out") + machine.screenshot("foot_wayland_info") + machine.send_key("alt-shift-q") + machine.wait_until_fails("pgrep foot") + + # Test gpg-agent starting pinentry-gnome3 via D-Bus (tests if + # $WAYLAND_DISPLAY is correctly imported into the D-Bus user env): + swaymsg("exec mkdir -p ~/.gnupg") + swaymsg("exec cp /etc/gpg-agent.conf ~/.gnupg") + + swaymsg("exec DISPLAY=INVALID gpg --no-tty --yes --quick-generate-key test", succeed=False) + machine.wait_until_succeeds("pgrep --exact gpg") + wait_for_window("gpg") + machine.succeed("pgrep --exact gpg") + machine.screenshot("gpg_pinentry") + machine.send_key("alt-shift-q") + machine.wait_until_fails("pgrep --exact gpg") + + # Test swaynag: + def get_height(): + return [node['rect']['height'] for node in walk(swaymsg(type="get_tree")) if node['focused']][0] + + before = get_height() + machine.send_key("alt-shift-e") + retry(lambda _: get_height() < before) + machine.screenshot("sway_exit") + + swaymsg("exec swaylock") + machine.wait_until_succeeds("pgrep -x swaylock") + machine.sleep(3) + machine.send_chars("${nodes.machine.config.users.users.alice.password}") + machine.send_key("ret") + machine.wait_until_fails("pgrep -x swaylock") + + # Exit Sway and verify process exit status 0: + swaymsg("exit", succeed=False) + machine.wait_until_fails("pgrep -x sway") + machine.wait_for_file("/tmp/sway-exit-ok") + ''; + } +) diff --git a/nixos/tests/switch-test.nix b/nixos/tests/switch-test.nix index a57d66f82eac9..4a7bcd5a82264 100644 --- a/nixos/tests/switch-test.nix +++ b/nixos/tests/switch-test.nix @@ -610,6 +610,11 @@ in { # Returns a comma separated representation of the given list in sorted # order, that matches the output format of switch-to-configuration.pl sortedUnits = xs: lib.concatStringsSep ", " (builtins.sort builtins.lessThan xs); + + dbusService = { + "dbus" = "dbus.service"; + "broker" = "dbus-broker.service"; + }.${nodes.machine.services.dbus.implementation}; in /* python */ '' def switch_to_specialisation(system, name, action="test", fail=False): if name == "": @@ -691,9 +696,9 @@ in { with subtest("continuing from an aborted switch"): # An aborted switch will write into a file what it tried to start # and a second switch should continue from this - machine.succeed("echo dbus-broker.service > /run/nixos/start-list") + machine.succeed("echo ${dbusService} > /run/nixos/start-list") out = switch_to_specialisation("${machine}", "modifiedSystemConf") - assert_contains(out, "starting the following units: dbus-broker.service\n") + assert_contains(out, "starting the following units: ${dbusService}\n") with subtest("fstab mounts"): switch_to_specialisation("${machine}", "") @@ -732,7 +737,7 @@ in { out = switch_to_specialisation("${machine}", "") assert_contains(out, "stopping the following units: test.mount\n") assert_lacks(out, "NOT restarting the following changed units:") - assert_contains(out, "reloading the following units: dbus-broker.service\n") + assert_contains(out, "reloading the following units: ${dbusService}\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") @@ -740,7 +745,7 @@ in { out = switch_to_specialisation("${machine}", "storeMountModified") assert_lacks(out, "stopping the following units:") assert_contains(out, "NOT restarting the following changed units: -.mount") - assert_contains(out, "reloading the following units: dbus-broker.service\n") + assert_contains(out, "reloading the following units: ${dbusService}\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") @@ -751,7 +756,7 @@ in { out = switch_to_specialisation("${machine}", "swap") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") - assert_contains(out, "reloading the following units: dbus-broker.service\n") + assert_contains(out, "reloading the following units: ${dbusService}\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: swapfile.swap") @@ -760,7 +765,7 @@ in { assert_contains(out, "stopping swap device: /swapfile") assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") - assert_contains(out, "reloading the following units: dbus-broker.service\n") + assert_contains(out, "reloading the following units: ${dbusService}\n") assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_lacks(out, "the following new units were started:") @@ -781,7 +786,7 @@ in { assert_lacks(out, "installing dummy bootloader") # test does not install a bootloader assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") - assert_contains(out, "reloading the following units: dbus-broker.service\n") # huh + assert_contains(out, "reloading the following units: ${dbusService}\n") # huh assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test.service\n") @@ -858,7 +863,7 @@ in { assert_lacks(out, "installing dummy bootloader") # test does not install a bootloader assert_lacks(out, "stopping the following units:") assert_lacks(out, "NOT restarting the following changed units:") - assert_contains(out, "reloading the following units: dbus-broker.service\n") # huh + assert_contains(out, "reloading the following units: ${dbusService}\n") # huh assert_lacks(out, "\nrestarting the following units:") assert_lacks(out, "\nstarting the following units:") assert_contains(out, "the following new units were started: test.service\n") diff --git a/nixos/tests/syncthing-relay.nix b/nixos/tests/syncthing-relay.nix index 3d70b1eda7b2a..cab9bcafe9d5c 100644 --- a/nixos/tests/syncthing-relay.nix +++ b/nixos/tests/syncthing-relay.nix @@ -1,6 +1,6 @@ import ./make-test-python.nix ({ lib, pkgs, ... }: { name = "syncthing-relay"; - meta.maintainers = with pkgs.lib.maintainers; [ delroth ]; + meta.maintainers = with pkgs.lib.maintainers; [ ]; nodes.machine = { environment.systemPackages = [ pkgs.jq ]; diff --git a/nixos/tests/systemd.nix b/nixos/tests/systemd.nix index 1a39cc73c8868..4b087d403f37d 100644 --- a/nixos/tests/systemd.nix +++ b/nixos/tests/systemd.nix @@ -1,7 +1,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "systemd"; - nodes.machine = { lib, ... }: { + nodes.machine = { config, lib, ... }: { imports = [ common/user-account.nix common/x11.nix ]; virtualisation.emptyDiskImages = [ 512 512 ]; @@ -38,9 +38,18 @@ import ./make-test-python.nix ({ pkgs, ... }: { script = "true"; }; + systemd.services.testDependency1 = { + description = "Test Dependency 1"; + wantedBy = [ config.systemd.services."testservice1".name ]; + serviceConfig.Type = "oneshot"; + script = '' + true + ''; + }; + systemd.services.testservice1 = { description = "Test Service 1"; - wantedBy = [ "multi-user.target" ]; + wantedBy = [ config.systemd.targets.multi-user.name ]; serviceConfig.Type = "oneshot"; script = '' if [ "$XXX_SYSTEM" = foo ]; then diff --git a/nixos/tests/web-apps/gotosocial.nix b/nixos/tests/web-apps/gotosocial.nix index 8c4e76b14e3bf..f9d28c2b8b998 100644 --- a/nixos/tests/web-apps/gotosocial.nix +++ b/nixos/tests/web-apps/gotosocial.nix @@ -1,7 +1,7 @@ { lib, ... }: { name = "gotosocial"; - meta.maintainers = with lib.maintainers; [ misuzu blakesmith ]; + meta.maintainers = with lib.maintainers; [ blakesmith ]; nodes.machine = { pkgs, ... }: { environment.systemPackages = [ pkgs.jq ]; |