diff options
Diffstat (limited to 'nixos')
71 files changed, 1434 insertions, 375 deletions
diff --git a/nixos/doc/manual/configuration/kubernetes.chapter.md b/nixos/doc/manual/configuration/kubernetes.chapter.md index 93787577be9b4..5d7b083289d9c 100644 --- a/nixos/doc/manual/configuration/kubernetes.chapter.md +++ b/nixos/doc/manual/configuration/kubernetes.chapter.md @@ -43,14 +43,6 @@ Note: Assigning either role will also default both and [](#opt-services.kubernetes.easyCerts) to true. This sets up flannel as CNI and activates automatic PKI bootstrapping. -As of kubernetes 1.10.X it has been deprecated to open non-tls-enabled -ports on kubernetes components. Thus, from NixOS 19.03 all plain HTTP -ports have been disabled by default. While opening insecure ports is -still possible, it is recommended not to bind these to other interfaces -than loopback. To re-enable the insecure port on the apiserver, see options: -[](#opt-services.kubernetes.apiserver.insecurePort) and -[](#opt-services.kubernetes.apiserver.insecureBindAddress) - ::: {.note} As of NixOS 19.03, it is mandatory to configure: [](#opt-services.kubernetes.masterAddress). diff --git a/nixos/doc/manual/from_md/configuration/kubernetes.chapter.xml b/nixos/doc/manual/from_md/configuration/kubernetes.chapter.xml index 83a50d7c49d1b..1de19f64bdad1 100644 --- a/nixos/doc/manual/from_md/configuration/kubernetes.chapter.xml +++ b/nixos/doc/manual/from_md/configuration/kubernetes.chapter.xml @@ -47,17 +47,6 @@ services.kubernetes.roles = [ "master" "node" ]; <xref linkend="opt-services.kubernetes.easyCerts" /> to true. This sets up flannel as CNI and activates automatic PKI bootstrapping. </para> - <para> - As of kubernetes 1.10.X it has been deprecated to open - non-tls-enabled ports on kubernetes components. Thus, from NixOS - 19.03 all plain HTTP ports have been disabled by default. While - opening insecure ports is still possible, it is recommended not to - bind these to other interfaces than loopback. To re-enable the - insecure port on the apiserver, see options: - <xref linkend="opt-services.kubernetes.apiserver.insecurePort" /> - and - <xref linkend="opt-services.kubernetes.apiserver.insecureBindAddress" /> - </para> <note> <para> As of NixOS 19.03, it is mandatory to configure: diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index bdd55a59370bb..daae918071574 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -13,6 +13,13 @@ <itemizedlist> <listitem> <para> + GNOME has been upgraded to 43. Please take a look at their + <link xlink:href="https://release.gnome.org/43/">Release + Notes</link> for details. + </para> + </listitem> + <listitem> + <para> During cross-compilation, tests are now executed if the test suite can be executed by the build platform. This is the case when doing “native” cross-compilation where the build and host @@ -211,6 +218,13 @@ </listitem> <listitem> <para> + <link xlink:href="https://github.com/edneville/please">Please</link>, + a Sudo clone written in Rust. Available as + <link linkend="opt-security.please.enable">security.please</link> + </para> + </listitem> + <listitem> + <para> <link xlink:href="https://github.com/messagebird/sachet/">Sachet</link>, an SMS alerting tool for the Prometheus Alertmanager. Available as @@ -242,6 +256,13 @@ </listitem> <listitem> <para> + <link xlink:href="https://github.com/prymitive/karma">karma</link>, + an alert dashboard for Prometheus Alertmanager. Available as + <link xlink:href="options.html#opt-services.karma.enable">services.karma</link> + </para> + </listitem> + <listitem> + <para> <link xlink:href="https://languagetool.org/">languagetool</link>, a multilingual grammar, style, and spell checker. Available as <link xlink:href="options.html#opt-services.languagetool.enable">services.languagetool</link>. @@ -581,6 +602,27 @@ </listitem> <listitem> <para> + <literal>generateOptparseApplicativeCompletions</literal> and + <literal>generateOptparseApplicativeCompletion</literal> from + <literal>haskell.lib.compose</literal> (and + <literal>haskell.lib</literal>) have been deprecated in favor + of <literal>generateOptparseApplicativeCompletions</literal> + (plural!) as provided by the haskell package sets (so + <literal>haskellPackages.generateOptparseApplicativeCompletions</literal> + etc.). The latter allows for cross-compilation (by + automatically disabling generation of completion in the cross + case). For it to work properly you need to make sure that the + function comes from the same context as the package you are + trying to override, i.e. always use the same package set as + your package is coming from or – even better – use + <literal>self.generateOptparseApplicativeCompletions</literal> + if you are overriding a haskell package set. The old functions + are retained for backwards compatibility, but yield are + warning. + </para> + </listitem> + <listitem> + <para> The <literal>services.graphite.api</literal> and <literal>services.graphite.beacon</literal> NixOS options, and the <literal>python3.pkgs.graphite_api</literal>, @@ -599,6 +641,47 @@ </listitem> <listitem> <para> + <literal>systemd-networkd</literal> v250 deprecated, renamed, + and moved some sections and settings which leads to the + following breaking module changes: + </para> + <itemizedlist spacing="compact"> + <listitem> + <para> + <literal>systemd.network.networks.<name>.dhcpV6PrefixDelegationConfig</literal> + is renamed to + <literal>systemd.network.networks.<name>.dhcpPrefixDelegationConfig</literal>. + </para> + </listitem> + <listitem> + <para> + <literal>systemd.network.networks.<name>.dhcpV6Config</literal> + no longer accepts the + <literal>ForceDHCPv6PDOtherInformation=</literal> setting. + Please use the <literal>WithoutRA=</literal> and + <literal>UseDelegatedPrefix=</literal> settings in your + <literal>systemd.network.networks.<name>.dhcpV6Config</literal> + and the <literal>DHCPv6Client=</literal> setting in your + <literal>systemd.network.networks.<name>.ipv6AcceptRAConfig</literal> + to control when the DHCPv6 client is started and how the + delegated prefixes are handled by the DHCPv6 client. + </para> + </listitem> + <listitem> + <para> + <literal>systemd.network.networks.<name>.networkConfig</literal> + no longer accepts the <literal>IPv6Token=</literal> + setting. Use the <literal>Token=</literal> setting in your + <literal>systemd.network.networks.<name>.ipv6AcceptRAConfig</literal> + instead. The + <literal>systemd.network.networks.<name>.ipv6Prefixes.*.ipv6PrefixConfig</literal> + now also accepts the <literal>Token=</literal> setting. + </para> + </listitem> + </itemizedlist> + </listitem> + <listitem> + <para> The <literal>meta.mainProgram</literal> attribute of packages in <literal>wineWowPackages</literal> now defaults to <literal>"wine64"</literal>. @@ -613,6 +696,12 @@ </listitem> <listitem> <para> + The top-level <literal>termonad-with-packages</literal> alias + for <literal>termonad</literal> has been removed. + </para> + </listitem> + <listitem> + <para> (Neo)Vim can not be configured with <literal>configure.pathogen</literal> anymore to reduce maintainance burden. Use <literal>configure.packages</literal> @@ -627,6 +716,12 @@ </listitem> <listitem> <para> + The default <literal>kops</literal> version is now 1.25.1 and + support for 1.22 and older has been dropped. + </para> + </listitem> + <listitem> + <para> <literal>k3s</literal> no longer supports docker as runtime due to upstream dropping support. </para> @@ -646,6 +741,16 @@ <literal>[ "lua54" "luau" ]</literal>. </para> </listitem> + <listitem> + <para> + <literal>pkgs.fetchNextcloudApp</literal> has been rewritten + to circumvent impurities in e.g. tarballs from GitHub and to + make it easier to apply patches. This means that your hashes + are out-of-date and the (previously required) attributes + <literal>name</literal> and <literal>version</literal> are no + longer accepted. + </para> + </listitem> </itemizedlist> </section> <section xml:id="sec-release-22.11-notable-changes"> @@ -724,6 +829,14 @@ </listitem> <listitem> <para> + The <literal>guake</literal> package has been updated from + 3.6.3 to 3.9.0, see the + <link xlink:href="https://github.com/Guake/guake/releases">changelog</link> + for more details. + </para> + </listitem> + <listitem> + <para> <literal>dockerTools.buildImage</literal> deprecates the misunderstood <literal>contents</literal> parameter, in favor of <literal>copyToRoot</literal>. Use diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 69e0cbd2ad513..821345e892543 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -6,6 +6,9 @@ Support is planned until the end of June 2023, handing over to 23.05. In addition to numerous new and upgraded packages, this release has the following highlights: +- GNOME has been upgraded to 43. Please take a look at their [Release + Notes](https://release.gnome.org/43/) for details. + - During cross-compilation, tests are now executed if the test suite can be executed by the build platform. This is the case when doing “native” cross-compilation where the build and host platforms are largely the same, but the nixpkgs' cross @@ -76,6 +79,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [HBase cluster](https://hbase.apache.org/), a distributed, scalable, big data store. Available as [services.hadoop.hbase](options.html#opt-services.hadoop.hbase.enable). +- [Please](https://github.com/edneville/please), a Sudo clone written in Rust. Available as [security.please](#opt-security.please.enable) + - [Sachet](https://github.com/messagebird/sachet/), an SMS alerting tool for the Prometheus Alertmanager. Available as [services.prometheus.sachet](#opt-services.prometheus.sachet.enable). - [infnoise](https://github.com/leetronics/infnoise), a hardware True Random Number Generator dongle. @@ -86,6 +91,8 @@ In addition to numerous new and upgraded packages, this release has the followin - [kanata](https://github.com/jtroo/kanata), a tool to improve keyboard comfort and usability with advanced customization. Available as [services.kanata](options.html#opt-services.kanata.enable). +- [karma](https://github.com/prymitive/karma), an alert dashboard for Prometheus Alertmanager. Available as [services.karma](options.html#opt-services.karma.enable) + - [languagetool](https://languagetool.org/), a multilingual grammar, style, and spell checker. Available as [services.languagetool](options.html#opt-services.languagetool.enable). @@ -191,6 +198,15 @@ Available as [services.patroni](options.html#opt-services.patroni.enable). - virtlyst package and `services.virtlyst` module removed, due to lack of maintainers. +- `generateOptparseApplicativeCompletions` and `generateOptparseApplicativeCompletion` from `haskell.lib.compose` + (and `haskell.lib`) have been deprecated in favor of `generateOptparseApplicativeCompletions` (plural!) as + provided by the haskell package sets (so `haskellPackages.generateOptparseApplicativeCompletions` etc.). + The latter allows for cross-compilation (by automatically disabling generation of completion in the cross case). + For it to work properly you need to make sure that the function comes from the same context as the package + you are trying to override, i.e. always use the same package set as your package is coming from or – even + better – use `self.generateOptparseApplicativeCompletions` if you are overriding a haskell package set. + The old functions are retained for backwards compatibility, but yield are warning. + - The `services.graphite.api` and `services.graphite.beacon` NixOS options, and the `python3.pkgs.graphite_api`, `python3.pkgs.graphite_beacon` and `python3.pkgs.influxgraph` packages, have been removed due to lack of upstream @@ -198,20 +214,34 @@ Available as [services.patroni](options.html#opt-services.patroni.enable). - The `aws` package has been removed due to being abandoned by the upstream. It is recommended to use `awscli` or `awscli2` instead. +- `systemd-networkd` v250 deprecated, renamed, and moved some sections and settings which leads to the following breaking module changes: + + * `systemd.network.networks.<name>.dhcpV6PrefixDelegationConfig` is renamed to `systemd.network.networks.<name>.dhcpPrefixDelegationConfig`. + * `systemd.network.networks.<name>.dhcpV6Config` no longer accepts the `ForceDHCPv6PDOtherInformation=` setting. Please use the `WithoutRA=` and `UseDelegatedPrefix=` settings in your `systemd.network.networks.<name>.dhcpV6Config` and the `DHCPv6Client=` setting in your `systemd.network.networks.<name>.ipv6AcceptRAConfig` to control when the DHCPv6 client is started and how the delegated prefixes are handled by the DHCPv6 client. + * `systemd.network.networks.<name>.networkConfig` no longer accepts the `IPv6Token=` setting. Use the `Token=` setting in your `systemd.network.networks.<name>.ipv6AcceptRAConfig` instead. The `systemd.network.networks.<name>.ipv6Prefixes.*.ipv6PrefixConfig` now also accepts the `Token=` setting. + - The `meta.mainProgram` attribute of packages in `wineWowPackages` now defaults to `"wine64"`. - The `paperless` module now defaults `PAPERLESS_TIME_ZONE` to your configured system timezone. +- The top-level `termonad-with-packages` alias for `termonad` has been removed. + - (Neo)Vim can not be configured with `configure.pathogen` anymore to reduce maintainance burden. Use `configure.packages` instead. - Neovim can not be configured with plug anymore (still works for vim). +- The default `kops` version is now 1.25.1 and support for 1.22 and older has been dropped. + - `k3s` no longer supports docker as runtime due to upstream dropping support. - `k3s` supports `clusterInit` option, and it is enabled by default, for servers. - `stylua` no longer accepts `lua52Support` and `luauSupport` overrides, use `features` instead, which defaults to `[ "lua54" "luau" ]`. +- `pkgs.fetchNextcloudApp` has been rewritten to circumvent impurities in e.g. tarballs from GitHub and to make it easier to + apply patches. This means that your hashes are out-of-date and the (previously required) attributes `name` and `version` + are no longer accepted. + <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> ## Other Notable Changes {#sec-release-22.11-notable-changes} @@ -234,6 +264,8 @@ Available as [services.patroni](options.html#opt-services.patroni.enable). - The `diamond` package has been update from 0.8.36 to 2.0.15. See the [upstream release notes](https://github.com/bbuchfink/diamond/releases) for more details. +- The `guake` package has been updated from 3.6.3 to 3.9.0, see the [changelog](https://github.com/Guake/guake/releases) for more details. + - `dockerTools.buildImage` deprecates the misunderstood `contents` parameter, in favor of `copyToRoot`. Use `copyToRoot = buildEnv { ... };` or similar if you intend to add packages to `/bin`. diff --git a/nixos/lib/make-options-doc/options-to-docbook.xsl b/nixos/lib/make-options-doc/options-to-docbook.xsl index d5b921b1dedb3..0fe14a6d2d169 100644 --- a/nixos/lib/make-options-doc/options-to-docbook.xsl +++ b/nixos/lib/make-options-doc/options-to-docbook.xsl @@ -40,8 +40,8 @@ concat($optionIdPrefix, translate( attr[@name = 'name']/string/@value, - '*< >[]:', - '_______' + '*< >[]:"', + '________' ))" /> <varlistentry> <term xlink:href="#{$id}"> diff --git a/nixos/lib/testing-python.nix b/nixos/lib/testing-python.nix index f63b6c78f6da3..d7204a2bc1434 100644 --- a/nixos/lib/testing-python.nix +++ b/nixos/lib/testing-python.nix @@ -29,7 +29,9 @@ rec { }; }; - # Make a full-blown test + # Make a full-blown test (legacy) + # For an official public interface to the tests, see + # https://nixos.org/manual/nixos/unstable/index.html#sec-calling-nixos-tests makeTest = { machine ? null , nodes ? {} @@ -48,7 +50,8 @@ rec { else builtins.unsafeGetAttrPos "testScript" t) , extraPythonPackages ? (_ : []) , interactive ? {} - } @ t: + } @ t: let + testConfig = (evalTest { imports = [ { _file = "makeTest parameters"; config = t; } @@ -60,6 +63,9 @@ rec { } ]; }).config; + in + testConfig.test # For nix-build + // testConfig; # For all-tests.nix simpleTest = as: (makeTest as).test; diff --git a/nixos/lib/testing/nodes.nix b/nixos/lib/testing/nodes.nix index 0395238cbaae7..8e620c96b3bb1 100644 --- a/nixos/lib/testing/nodes.nix +++ b/nixos/lib/testing/nodes.nix @@ -101,7 +101,7 @@ in nodesCompat = mapAttrs (name: config: config // { - config = lib.warn + config = lib.warnIf (lib.isInOldestRelease 2211) "Module argument `nodes.${name}.config` is deprecated. Use `nodes.${name}` instead." config; }) diff --git a/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix b/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix index c5976166fb310..4a00c52916f69 100644 --- a/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix +++ b/nixos/modules/installer/cd-dvd/installation-cd-graphical-base.nix @@ -38,9 +38,9 @@ with lib; # VM guest additions to improve host-guest interaction services.spice-vdagentd.enable = true; services.qemuGuest.enable = true; - virtualisation.vmware.guest.enable = true; + virtualisation.vmware.guest.enable = pkgs.stdenv.hostPlatform.isx86; virtualisation.hypervGuest.enable = true; - services.xe-guest-utilities.enable = true; + services.xe-guest-utilities.enable = pkgs.stdenv.hostPlatform.isx86; # The VirtualBox guest additions rely on an out-of-tree kernel module # which lags behind kernel releases, potentially causing broken builds. virtualisation.virtualbox.guest.enable = false; diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 8584a4eb1d23c..98ac1948e6862 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -263,6 +263,7 @@ ./security/pam.nix ./security/pam_usb.nix ./security/pam_mount.nix + ./security/please.nix ./security/polkit.nix ./security/rngd.nix ./security/rtkit.nix @@ -392,9 +393,9 @@ ./services/desktops/pipewire/pipewire-media-session.nix ./services/desktops/pipewire/wireplumber.nix ./services/desktops/gnome/at-spi2-core.nix - ./services/desktops/gnome/chrome-gnome-shell.nix ./services/desktops/gnome/evolution-data-server.nix ./services/desktops/gnome/glib-networking.nix + ./services/desktops/gnome/gnome-browser-connector.nix ./services/desktops/gnome/gnome-initial-setup.nix ./services/desktops/gnome/gnome-keyring.nix ./services/desktops/gnome/gnome-online-accounts.nix @@ -684,6 +685,7 @@ ./services/monitoring/heapster.nix ./services/monitoring/incron.nix ./services/monitoring/kapacitor.nix + ./services/monitoring/karma.nix ./services/monitoring/kthxbye.nix ./services/monitoring/loki.nix ./services/monitoring/longview.nix @@ -714,6 +716,7 @@ ./services/monitoring/unifi-poller.nix ./services/monitoring/ups.nix ./services/monitoring/uptime.nix + ./services/monitoring/vmagent.nix ./services/monitoring/vnstat.nix ./services/monitoring/zabbix-agent.nix ./services/monitoring/zabbix-proxy.nix diff --git a/nixos/modules/programs/neovim.nix b/nixos/modules/programs/neovim.nix index 31848c246f646..8de527fceb26a 100644 --- a/nixos/modules/programs/neovim.nix +++ b/nixos/modules/programs/neovim.nix @@ -11,7 +11,19 @@ let in { options.programs.neovim = { - enable = mkEnableOption (lib.mdDoc "Neovim"); + enable = mkOption { + type = types.bool; + default = false; + example = true; + description = lib.mdDoc '' + Whether to enable Neovim. + + When enabled through this option, Neovim is wrapped to use a + configuration managed by this module. The configuration file in the + user's home directory at {file}`~/.config/nvim/init.vim` is no longer + loaded by default. + ''; + }; defaultEditor = mkOption { type = types.bool; diff --git a/nixos/modules/programs/tsm-client.nix b/nixos/modules/programs/tsm-client.nix index 89662cecaa48e..7adff7cd28cb0 100644 --- a/nixos/modules/programs/tsm-client.nix +++ b/nixos/modules/programs/tsm-client.nix @@ -223,7 +223,7 @@ let description = lib.mdDoc '' The TSM client derivation to be added to the system environment. - It will called with `.override` + It will be used with `.override` to add paths to the client system-options file. ''; }; diff --git a/nixos/modules/security/please.nix b/nixos/modules/security/please.nix new file mode 100644 index 0000000000000..88bb9cba2bfc0 --- /dev/null +++ b/nixos/modules/security/please.nix @@ -0,0 +1,122 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.security.please; + ini = pkgs.formats.ini { }; +in +{ + options.security.please = { + enable = mkEnableOption (mdDoc '' + please, a Sudo clone which allows a users to execute a command or edit a + file as another user + ''); + + package = mkOption { + type = types.package; + default = pkgs.please; + defaultText = literalExpression "pkgs.please"; + description = mdDoc '' + Which package to use for {command}`please`. + ''; + }; + + wheelNeedsPassword = mkOption { + type = types.bool; + default = true; + description = lib.mdDoc '' + Whether users of the `wheel` group must provide a password to run + commands or edit files with {command}`please` and + {command}`pleaseedit` respectively. + ''; + }; + + settings = mkOption { + type = ini.type; + default = { }; + example = { + jim_run_any_as_root = { + name = "jim"; + type = "run"; + target = "root"; + rule = ".*"; + require_pass = false; + }; + jim_edit_etc_hosts_as_root = { + name = "jim"; + type = "edit"; + target = "root"; + rule = "/etc/hosts"; + editmode = 644; + require_pass = true; + }; + }; + description = mdDoc '' + Please configuration. Refer to + <https://github.com/edneville/please/blob/master/please.ini.md> for + details. + ''; + }; + }; + + config = mkIf cfg.enable { + security.wrappers = + let + owner = "root"; + group = "root"; + setuid = true; + in + { + please = { + source = "${cfg.package}/bin/please"; + inherit owner group setuid; + }; + pleaseedit = { + source = "${cfg.package}/bin/pleaseedit"; + inherit owner group setuid; + }; + }; + + security.please.settings = rec { + # The "wheel" group is allowed to do anything by default but this can be + # overridden. + wheel_run_as_any = { + type = "run"; + group = true; + name = "wheel"; + target = ".*"; + rule = ".*"; + require_pass = cfg.wheelNeedsPassword; + }; + wheel_edit_as_any = wheel_run_as_any // { type = "edit"; }; + wheel_list_as_any = wheel_run_as_any // { type = "list"; }; + }; + + environment = { + systemPackages = [ cfg.package ]; + + etc."please.ini".source = ini.generate "please.ini" + (cfg.settings // (rec { + # The "root" user is allowed to do anything by default and this cannot + # be overridden. + root_run_as_any = { + type = "run"; + name = "root"; + target = ".*"; + rule = ".*"; + require_pass = false; + }; + root_edit_as_any = root_run_as_any // { type = "edit"; }; + root_list_as_any = root_run_as_any // { type = "list"; }; + })); + }; + + security.pam.services.please = { + sshAgentAuth = true; + usshAuth = true; + }; + + meta.maintainers = with maintainers; [ azahi ]; + }; +} diff --git a/nixos/modules/services/backup/restic.nix b/nixos/modules/services/backup/restic.nix index 65fe34b2d39e4..869ed5d9976c3 100644 --- a/nixos/modules/services/backup/restic.nix +++ b/nixos/modules/services/backup/restic.nix @@ -196,6 +196,18 @@ in ]; }; + checkOpts = mkOption { + type = types.listOf types.str; + default = [ ]; + description = lib.mdDoc '' + A list of options for 'restic check', which is run after + pruning. + ''; + example = [ + "--with-cache" + ]; + }; + dynamicFilesFrom = mkOption { type = with types; nullOr str; default = null; @@ -270,8 +282,8 @@ in then if (backup.paths != null) then concatStringsSep " " backup.paths else "" else "--files-from ${filesFromTmpFile}"; pruneCmd = optionals (builtins.length backup.pruneOpts > 0) [ - (resticCmd + " forget --prune " + (concatStringsSep " " backup.pruneOpts)) - (resticCmd + " check") + (resticCmd + " forget --prune --cache-dir=%C/restic-backups-${name} " + (concatStringsSep " " backup.pruneOpts)) + (resticCmd + " check --cache-dir=%C/restic-backups-${name} " + (concatStringsSep " " backup.checkOpts)) ]; # Helper functions for rclone remotes rcloneRemoteName = builtins.elemAt (splitString ":" backup.repository) 1; diff --git a/nixos/modules/services/cluster/kubernetes/apiserver.nix b/nixos/modules/services/cluster/kubernetes/apiserver.nix index 718244e742d9a..d5ec1e5e6d263 100644 --- a/nixos/modules/services/cluster/kubernetes/apiserver.nix +++ b/nixos/modules/services/cluster/kubernetes/apiserver.nix @@ -18,7 +18,8 @@ in imports = [ (mkRenamedOptionModule [ "services" "kubernetes" "apiserver" "admissionControl" ] [ "services" "kubernetes" "apiserver" "enableAdmissionPlugins" ]) (mkRenamedOptionModule [ "services" "kubernetes" "apiserver" "address" ] ["services" "kubernetes" "apiserver" "bindAddress"]) - (mkRenamedOptionModule [ "services" "kubernetes" "apiserver" "port" ] ["services" "kubernetes" "apiserver" "insecurePort"]) + (mkRemovedOptionModule [ "services" "kubernetes" "apiserver" "insecureBindAddress" ] "") + (mkRemovedOptionModule [ "services" "kubernetes" "apiserver" "insecurePort" ] "") (mkRemovedOptionModule [ "services" "kubernetes" "apiserver" "publicAddress" ] "") (mkRenamedOptionModule [ "services" "kubernetes" "etcd" "servers" ] [ "services" "kubernetes" "apiserver" "etcd" "servers" ]) (mkRenamedOptionModule [ "services" "kubernetes" "etcd" "keyFile" ] [ "services" "kubernetes" "apiserver" "etcd" "keyFile" ]) @@ -164,18 +165,6 @@ in type = listOf str; }; - insecureBindAddress = mkOption { - description = lib.mdDoc "The IP address on which to serve the --insecure-port."; - default = "127.0.0.1"; - type = str; - }; - - insecurePort = mkOption { - description = lib.mdDoc "Kubernetes apiserver insecure listening port. (0 = disabled)"; - default = 0; - type = int; - }; - kubeletClientCaFile = mkOption { description = lib.mdDoc "Path to a cert file for connecting to kubelet."; default = top.caFile; @@ -376,8 +365,6 @@ in "--proxy-client-cert-file=${cfg.proxyClientCertFile}"} \ ${optionalString (cfg.proxyClientKeyFile != null) "--proxy-client-key-file=${cfg.proxyClientKeyFile}"} \ - --insecure-bind-address=${cfg.insecureBindAddress} \ - --insecure-port=${toString cfg.insecurePort} \ ${optionalString (cfg.runtimeConfig != "") "--runtime-config=${cfg.runtimeConfig}"} \ --secure-port=${toString cfg.securePort} \ diff --git a/nixos/modules/services/cluster/kubernetes/controller-manager.nix b/nixos/modules/services/cluster/kubernetes/controller-manager.nix index b1a96e1c384dc..18c82fc235935 100644 --- a/nixos/modules/services/cluster/kubernetes/controller-manager.nix +++ b/nixos/modules/services/cluster/kubernetes/controller-manager.nix @@ -10,7 +10,7 @@ in { imports = [ (mkRenamedOptionModule [ "services" "kubernetes" "controllerManager" "address" ] ["services" "kubernetes" "controllerManager" "bindAddress"]) - (mkRenamedOptionModule [ "services" "kubernetes" "controllerManager" "port" ] ["services" "kubernetes" "controllerManager" "insecurePort"]) + (mkRemovedOptionModule [ "services" "kubernetes" "controllerManager" "insecurePort" ] "") ]; ###### interface @@ -50,12 +50,6 @@ in type = listOf str; }; - insecurePort = mkOption { - description = lib.mdDoc "Kubernetes controller manager insecure listening port."; - default = 0; - type = int; - }; - kubeconfig = top.lib.mkKubeConfigOptions "Kubernetes controller manager"; leaderElect = mkOption { @@ -133,7 +127,6 @@ in --leader-elect=${boolToString cfg.leaderElect} \ ${optionalString (cfg.rootCaFile!=null) "--root-ca-file=${cfg.rootCaFile}"} \ - --port=${toString cfg.insecurePort} \ --secure-port=${toString cfg.securePort} \ ${optionalString (cfg.serviceAccountKeyFile!=null) "--service-account-private-key-file=${cfg.serviceAccountKeyFile}"} \ diff --git a/nixos/modules/services/cluster/kubernetes/flannel.nix b/nixos/modules/services/cluster/kubernetes/flannel.nix index 5b591eaa8e0ea..3ca85a8183c34 100644 --- a/nixos/modules/services/cluster/kubernetes/flannel.nix +++ b/nixos/modules/services/cluster/kubernetes/flannel.nix @@ -26,7 +26,6 @@ in }; services.kubernetes.kubelet = { - networkPlugin = mkDefault "cni"; cni.config = mkDefault [{ name = "mynet"; type = "flannel"; diff --git a/nixos/modules/services/cluster/kubernetes/kubelet.nix b/nixos/modules/services/cluster/kubernetes/kubelet.nix index ae9548bdba22d..5dcd18293488a 100644 --- a/nixos/modules/services/cluster/kubernetes/kubelet.nix +++ b/nixos/modules/services/cluster/kubernetes/kubelet.nix @@ -62,6 +62,7 @@ in (mkRemovedOptionModule [ "services" "kubernetes" "kubelet" "applyManifests" ] "") (mkRemovedOptionModule [ "services" "kubernetes" "kubelet" "cadvisorPort" ] "") (mkRemovedOptionModule [ "services" "kubernetes" "kubelet" "allowPrivileged" ] "") + (mkRemovedOptionModule [ "services" "kubernetes" "kubelet" "networkPlugin" ] "") ]; ###### interface @@ -189,12 +190,6 @@ in default = {}; }; - networkPlugin = mkOption { - description = lib.mdDoc "Network plugin to use by Kubernetes."; - type = nullOr (enum ["cni" "kubenet"]); - default = "kubenet"; - }; - nodeIp = mkOption { description = lib.mdDoc "IP address of the node. If set, kubelet will use this IP address for the node."; default = null; @@ -315,7 +310,6 @@ in "--cluster-dns=${cfg.clusterDns}"} \ ${optionalString (cfg.clusterDomain != "") "--cluster-domain=${cfg.clusterDomain}"} \ - --cni-conf-dir=${cniConfig} \ ${optionalString (cfg.featureGates != []) "--feature-gates=${concatMapStringsSep "," (feature: "${feature}=true") cfg.featureGates}"} \ --hairpin-mode=hairpin-veth \ @@ -323,8 +317,6 @@ in --healthz-port=${toString cfg.healthz.port} \ --hostname-override=${cfg.hostname} \ --kubeconfig=${kubeconfig} \ - ${optionalString (cfg.networkPlugin != null) - "--network-plugin=${cfg.networkPlugin}"} \ ${optionalString (cfg.nodeIp != null) "--node-ip=${cfg.nodeIp}"} \ --pod-infra-container-image=pause \ diff --git a/nixos/modules/services/cluster/kubernetes/pki.nix b/nixos/modules/services/cluster/kubernetes/pki.nix index 507e74570e457..d68267883e45f 100644 --- a/nixos/modules/services/cluster/kubernetes/pki.nix +++ b/nixos/modules/services/cluster/kubernetes/pki.nix @@ -266,7 +266,7 @@ in in '' export KUBECONFIG=${clusterAdminKubeconfig} - ${kubernetes}/bin/kubectl apply -f ${concatStringsSep " \\\n -f " files} + ${top.package}/bin/kubectl apply -f ${concatStringsSep " \\\n -f " files} ''; })]); diff --git a/nixos/modules/services/continuous-integration/gitlab-runner.nix b/nixos/modules/services/continuous-integration/gitlab-runner.nix index fb148e7cffb5b..2050e04d55cd5 100644 --- a/nixos/modules/services/continuous-integration/gitlab-runner.nix +++ b/nixos/modules/services/continuous-integration/gitlab-runner.nix @@ -453,6 +453,43 @@ in }; }); }; + clear-docker-cache = { + enable = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Whether to periodically prune gitlab runner's Docker resources. If + enabled, a systemd timer will run {command}`clear-docker-cache` as + specified by the `dates` option. + ''; + }; + + flags = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "prune" ]; + description = lib.mdDoc '' + Any additional flags passed to {command}`clear-docker-cache`. + ''; + }; + + dates = mkOption { + default = "weekly"; + type = types.str; + description = lib.mdDoc '' + Specification (in the format described by + {manpage}`systemd.time(7)`) of the time at + which the prune will occur. + ''; + }; + + package = mkOption { + default = config.virtualisation.docker.package; + defaultText = literalExpression "config.virtualisation.docker.package"; + example = literalExpression "pkgs.docker"; + description = lib.mdDoc "Docker package to use for clearing up docker cache."; + }; + }; }; config = mkIf cfg.enable { warnings = (mapAttrsToList @@ -497,6 +534,22 @@ in KillMode = "process"; }; }; + # Enable periodic clear-docker-cache script + systemd.services.gitlab-runner-clear-docker-cache = { + description = "Prune gitlab-runner docker resources"; + restartIfChanged = false; + unitConfig.X-StopOnRemoval = false; + + serviceConfig.Type = "oneshot"; + + path = [ cfg.clear-docker-cache.package pkgs.gawk ]; + + script = '' + ${pkgs.gitlab-runner}/bin/clear-docker-cache ${toString cfg.clear-docker-cache.flags} + ''; + + startAt = optional cfg.clear-docker-cache.enable cfg.clear-docker-cache.dates; + }; # Enable docker if `docker` executor is used in any service virtualisation.docker.enable = mkIf ( any (s: s.executor == "docker") (attrValues cfg.services) diff --git a/nixos/modules/services/desktops/gnome/chrome-gnome-shell.nix b/nixos/modules/services/desktops/gnome/chrome-gnome-shell.nix deleted file mode 100644 index 7d0ee9ed02218..0000000000000 --- a/nixos/modules/services/desktops/gnome/chrome-gnome-shell.nix +++ /dev/null @@ -1,41 +0,0 @@ -# Chrome GNOME Shell native host connector. -{ config, lib, pkgs, ... }: - -with lib; - -{ - meta = { - maintainers = teams.gnome.members; - }; - - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "chrome-gnome-shell" "enable" ] - [ "services" "gnome" "chrome-gnome-shell" "enable" ] - ) - ]; - - ###### interface - options = { - services.gnome.chrome-gnome-shell.enable = mkEnableOption (lib.mdDoc '' - Chrome GNOME Shell native host connector, a DBus service - allowing to install GNOME Shell extensions from a web browser. - ''); - }; - - - ###### implementation - config = mkIf config.services.gnome.chrome-gnome-shell.enable { - environment.etc = { - "chromium/native-messaging-hosts/org.gnome.chrome_gnome_shell.json".source = "${pkgs.chrome-gnome-shell}/etc/chromium/native-messaging-hosts/org.gnome.chrome_gnome_shell.json"; - "opt/chrome/native-messaging-hosts/org.gnome.chrome_gnome_shell.json".source = "${pkgs.chrome-gnome-shell}/etc/opt/chrome/native-messaging-hosts/org.gnome.chrome_gnome_shell.json"; - }; - - environment.systemPackages = [ pkgs.chrome-gnome-shell ]; - - services.dbus.packages = [ pkgs.chrome-gnome-shell ]; - - nixpkgs.config.firefox.enableGnomeExtensions = true; - }; -} diff --git a/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix new file mode 100644 index 0000000000000..5d4ddce94220f --- /dev/null +++ b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix @@ -0,0 +1,47 @@ +{ config, lib, pkgs, ... }: + +let + inherit (lib) mdDoc mkEnableOption mkIf mkRenamedOptionModule teams; +in + +{ + meta = { + 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 (mdDoc '' + Native host connector for the GNOME Shell browser extension, a DBus service + allowing to install GNOME Shell extensions from a web browser. + ''); + }; + + config = mkIf config.services.gnome.gnome-browser-connector.enable { + environment.etc = { + "chromium/native-messaging-hosts/org.gnome.browser_connector.json".source = "${pkgs.gnome-browser-connector}/etc/chromium/native-messaging-hosts/org.gnome.browser_connector.json"; + "opt/chrome/native-messaging-hosts/org.gnome.browser_connector.json".source = "${pkgs.gnome-browser-connector}/etc/opt/chrome/native-messaging-hosts/org.gnome.browser_connector.json"; + # Legacy paths. + "chromium/native-messaging-hosts/org.gnome.chrome_gnome_shell.json".source = "${pkgs.gnome-browser-connector}/etc/chromium/native-messaging-hosts/org.gnome.chrome_gnome_shell.json"; + "opt/chrome/native-messaging-hosts/org.gnome.chrome_gnome_shell.json".source = "${pkgs.gnome-browser-connector}/etc/opt/chrome/native-messaging-hosts/org.gnome.chrome_gnome_shell.json"; + }; + + environment.systemPackages = [ pkgs.gnome-browser-connector ]; + + services.dbus.packages = [ pkgs.gnome-browser-connector ]; + + nixpkgs.config.firefox.enableGnomeExtensions = true; + }; +} diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix index fd3418b8f6bd0..15ca11a2e1642 100644 --- a/nixos/modules/services/monitoring/grafana.nix +++ b/nixos/modules/services/monitoring/grafana.nix @@ -720,6 +720,12 @@ in { assertion = cfg.smtp.password != opt.smtp.password.default -> cfg.smtp.passwordFile == null; message = "Cannot set both password and passwordFile"; } + { + assertion = all + ({ type, access, ... }: type == "prometheus" -> access != "direct") + cfg.provision.datasources; + message = "For datasources of type `prometheus`, the `direct` access mode is not supported anymore (since Grafana 9.2.0)"; + } ]; systemd.services.grafana = { diff --git a/nixos/modules/services/monitoring/karma.nix b/nixos/modules/services/monitoring/karma.nix new file mode 100644 index 0000000000000..85dbc81f443f0 --- /dev/null +++ b/nixos/modules/services/monitoring/karma.nix @@ -0,0 +1,128 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.services.karma; + yaml = pkgs.formats.yaml { }; +in +{ + options.services.karma = { + enable = mkEnableOption (mdDoc "the Karma dashboard service"); + + package = mkOption { + type = types.package; + default = pkgs.karma; + defaultText = literalExpression "pkgs.karma"; + description = mdDoc '' + The Karma package that should be used. + ''; + }; + + configFile = mkOption { + type = types.path; + default = yaml.generate "karma.yaml" cfg.settings; + defaultText = "A configuration file generated from the provided nix attributes settings option."; + description = mdDoc '' + A YAML config file which can be used to configure karma instead of the nix-generated file. + ''; + example = "/etc/karma/karma.conf"; + }; + + environment = mkOption { + type = with types; attrsOf str; + default = {}; + description = mdDoc '' + Additional environment variables to provide to karma. + ''; + example = { + ALERTMANAGER_URI = "https://alertmanager.example.com"; + ALERTMANAGER_NAME= "single"; + }; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = mdDoc '' + Whether to open ports in the firewall needed for karma to function. + ''; + }; + + extraOptions = mkOption { + type = with types; listOf str; + default = []; + description = mdDoc '' + Extra command line options. + ''; + example = [ + "--alertmanager.timeout 10s" + ]; + }; + + settings = mkOption { + type = types.submodule { + freeformType = yaml.type; + + options.listen = { + address = mkOption { + type = types.str; + default = "127.0.0.1"; + description = mdDoc '' + Hostname or IP to listen on. + ''; + example = "[::]"; + }; + + port = mkOption { + type = types.port; + default = 8080; + description = mdDoc '' + HTTP port to listen on. + ''; + example = 8182; + }; + }; + }; + default = { + listen = { + address = "127.0.0.1"; + }; + }; + description = mdDoc '' + Karma dashboard configuration as nix attributes. + + Reference: <https://github.com/prymitive/karma/blob/main/docs/CONFIGURATION.md> + ''; + example = { + listen = { + address = "192.168.1.4"; + port = "8000"; + prefix = "/dashboard"; + }; + alertmanager = { + interval = "15s"; + servers = [ + { + name = "prod"; + uri = "http://alertmanager.example.com"; + } + ]; + }; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.karma = { + description = "Alert dashboard for Prometheus Alertmanager"; + wantedBy = [ "multi-user.target" ]; + environment = cfg.environment; + serviceConfig = { + Type = "simple"; + DynamicUser = true; + Restart = "on-failure"; + ExecStart = "${pkgs.karma}/bin/karma --config.file ${cfg.configFile} ${concatStringsSep " " cfg.extraOptions}"; + }; + }; + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.listen.port ]; + }; +} diff --git a/nixos/modules/services/monitoring/vmagent.nix b/nixos/modules/services/monitoring/vmagent.nix new file mode 100644 index 0000000000000..c793bb073199c --- /dev/null +++ b/nixos/modules/services/monitoring/vmagent.nix @@ -0,0 +1,100 @@ +{ config, pkgs, lib, ... }: +with lib; +let + cfg = config.services.vmagent; + settingsFormat = pkgs.formats.json { }; +in { + options.services.vmagent = { + enable = mkEnableOption (lib.mdDoc "vmagent"); + + user = mkOption { + default = "vmagent"; + type = types.str; + description = lib.mdDoc '' + User account under which vmagent runs. + ''; + }; + + group = mkOption { + type = types.str; + default = "vmagent"; + description = lib.mdDoc '' + Group under which vmagent runs. + ''; + }; + + package = mkOption { + default = pkgs.vmagent; + defaultText = lib.literalMD "pkgs.vmagent"; + type = types.package; + description = lib.mdDoc '' + vmagent package to use. + ''; + }; + + dataDir = mkOption { + type = types.str; + default = "/var/lib/vmagent"; + description = lib.mdDoc '' + The directory where vmagent stores its data files. + ''; + }; + + remoteWriteUrl = mkOption { + default = "http://localhost:8428/api/v1/write"; + type = types.str; + description = lib.mdDoc '' + The storage endpoint such as VictoriaMetrics + ''; + }; + + prometheusConfig = mkOption { + type = lib.types.submodule { freeformType = settingsFormat.type; }; + description = lib.mdDoc '' + Config for prometheus style metrics + ''; + }; + + openFirewall = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Whether to open the firewall for the default ports. + ''; + }; + }; + + 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 ]; + + systemd.services.vmagent = let + prometheusConfig = settingsFormat.generate "prometheusConfig.yaml" cfg.prometheusConfig; + in { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + description = "vmagent system service"; + serviceConfig = { + User = cfg.user; + Group = cfg.group; + Type = "simple"; + Restart = "on-failure"; + WorkingDirectory = cfg.dataDir; + ExecStart = "${cfg.package}/bin/vmagent -remoteWrite.url=${cfg.remoteWriteUrl} -promscrape.config=${prometheusConfig}"; + }; + }; + + systemd.tmpfiles.rules = + [ "d '${cfg.dataDir}' 0755 ${cfg.user} ${cfg.group} -" ]; + }; +} diff --git a/nixos/modules/services/networking/ddclient.nix b/nixos/modules/services/networking/ddclient.nix index a0e9405343bad..5c32817979afd 100644 --- a/nixos/modules/services/networking/ddclient.nix +++ b/nixos/modules/services/networking/ddclient.nix @@ -200,6 +200,10 @@ with lib; type = lines; description = lib.mdDoc '' Extra configuration. Contents will be added verbatim to the configuration file. + + ::: {.note} + `daemon` should not be added here because it does not work great with the systemd-timer approach the service uses. + ::: ''; }; }; diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix index 7f42df0b08ff8..0242a3780ffc5 100644 --- a/nixos/modules/services/networking/firewall.nix +++ b/nixos/modules/services/networking/firewall.nix @@ -16,7 +16,7 @@ certain packets anyway, you can insert rules at the start of this chain. - - ‘nixos-fw-rpfilter’ is used as the main chain in the raw table, + - ‘nixos-fw-rpfilter’ is used as the main chain in the mangle table, called from the built-in ‘PREROUTING’ chain. If the kernel supports it and `cfg.checkReversePath` is set this chain will perform a reverse path filter test. @@ -109,28 +109,28 @@ let ip46tables -N nixos-fw # Clean up rpfilter rules - ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2> /dev/null || true - ip46tables -t raw -F nixos-fw-rpfilter 2> /dev/null || true - ip46tables -t raw -X nixos-fw-rpfilter 2> /dev/null || true + ip46tables -t mangle -D PREROUTING -j nixos-fw-rpfilter 2> /dev/null || true + ip46tables -t mangle -F nixos-fw-rpfilter 2> /dev/null || true + ip46tables -t mangle -X nixos-fw-rpfilter 2> /dev/null || true ${optionalString (kernelHasRPFilter && (cfg.checkReversePath != false)) '' # Perform a reverse-path test to refuse spoofers - # For now, we just drop, as the raw table doesn't have a log-refuse yet - ip46tables -t raw -N nixos-fw-rpfilter 2> /dev/null || true - ip46tables -t raw -A nixos-fw-rpfilter -m rpfilter --validmark ${optionalString (cfg.checkReversePath == "loose") "--loose"} -j RETURN + # For now, we just drop, as the mangle table doesn't have a log-refuse yet + ip46tables -t mangle -N nixos-fw-rpfilter 2> /dev/null || true + ip46tables -t mangle -A nixos-fw-rpfilter -m rpfilter --validmark ${optionalString (cfg.checkReversePath == "loose") "--loose"} -j RETURN # Allows this host to act as a DHCP4 client without first having to use APIPA - iptables -t raw -A nixos-fw-rpfilter -p udp --sport 67 --dport 68 -j RETURN + iptables -t mangle -A nixos-fw-rpfilter -p udp --sport 67 --dport 68 -j RETURN # Allows this host to act as a DHCPv4 server - iptables -t raw -A nixos-fw-rpfilter -s 0.0.0.0 -d 255.255.255.255 -p udp --sport 68 --dport 67 -j RETURN + iptables -t mangle -A nixos-fw-rpfilter -s 0.0.0.0 -d 255.255.255.255 -p udp --sport 68 --dport 67 -j RETURN ${optionalString cfg.logReversePathDrops '' - ip46tables -t raw -A nixos-fw-rpfilter -j LOG --log-level info --log-prefix "rpfilter drop: " + ip46tables -t mangle -A nixos-fw-rpfilter -j LOG --log-level info --log-prefix "rpfilter drop: " ''} - ip46tables -t raw -A nixos-fw-rpfilter -j DROP + ip46tables -t mangle -A nixos-fw-rpfilter -j DROP - ip46tables -t raw -A PREROUTING -j nixos-fw-rpfilter + ip46tables -t mangle -A PREROUTING -j nixos-fw-rpfilter ''} # Accept all traffic on the trusted interfaces. @@ -218,7 +218,7 @@ let ip46tables -D INPUT -j nixos-fw 2>/dev/null || true ${optionalString (kernelHasRPFilter && (cfg.checkReversePath != false)) '' - ip46tables -t raw -D PREROUTING -j nixos-fw-rpfilter 2>/dev/null || true + ip46tables -t mangle -D PREROUTING -j nixos-fw-rpfilter 2>/dev/null || true ''} ${cfg.extraStopCommands} diff --git a/nixos/modules/services/networking/iwd.nix b/nixos/modules/services/networking/iwd.nix index a9908b01a58a0..993a603c1ed5c 100644 --- a/nixos/modules/services/networking/iwd.nix +++ b/nixos/modules/services/networking/iwd.nix @@ -19,6 +19,15 @@ in options.networking.wireless.iwd = { enable = mkEnableOption (lib.mdDoc "iwd"); + package = mkOption { + type = types.package; + default = pkgs.iwd; + defaultText = lib.literalExpression "pkgs.iwd"; + description = lib.mdDoc '' + The iwd package to use. + ''; + }; + settings = mkOption { type = ini.type; default = { }; @@ -50,11 +59,11 @@ in environment.etc."iwd/${configFile.name}".source = configFile; # for iwctl - environment.systemPackages = [ pkgs.iwd ]; + environment.systemPackages = [ cfg.package ]; - services.dbus.packages = [ pkgs.iwd ]; + services.dbus.packages = [ cfg.package ]; - systemd.packages = [ pkgs.iwd ]; + systemd.packages = [ cfg.package ]; systemd.network.links."80-iwd" = { matchConfig.Type = "wlan"; diff --git a/nixos/modules/services/networking/mullvad-vpn.nix b/nixos/modules/services/networking/mullvad-vpn.nix index ca60682b4b8b5..42d55056084db 100644 --- a/nixos/modules/services/networking/mullvad-vpn.nix +++ b/nixos/modules/services/networking/mullvad-vpn.nix @@ -39,7 +39,7 @@ with lib; startLimitBurst = 5; startLimitIntervalSec = 20; serviceConfig = { - ExecStart = "${pkgs.mullvad-vpn}/bin/mullvad-daemon -v --disable-stdout-timestamps"; + ExecStart = "${pkgs.mullvad}/bin/mullvad-daemon -v --disable-stdout-timestamps"; Restart = "always"; RestartSec = 1; }; diff --git a/nixos/modules/services/networking/wg-quick.nix b/nixos/modules/services/networking/wg-quick.nix index b43c3e8513247..a678d743bb77b 100644 --- a/nixos/modules/services/networking/wg-quick.nix +++ b/nixos/modules/services/networking/wg-quick.nix @@ -328,9 +328,6 @@ in { config = mkIf (cfg.interfaces != {}) { boot.extraModulePackages = optional (versionOlder kernel.kernel.version "5.6") kernel.wireguard; environment.systemPackages = [ pkgs.wireguard-tools ]; - # This is forced to false for now because the default "--validmark" rpfilter we apply on reverse path filtering - # breaks the wg-quick routing because wireguard packets leave with a fwmark from wireguard. - networking.firewall.checkReversePath = false; systemd.services = mapAttrs' generateUnit cfg.interfaces; # Prevent networkd from clearing the rules set by wg-quick when restarted (e.g. when waking up from suspend). diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix index fea7ffb673ca0..ae59dcc226de8 100644 --- a/nixos/modules/services/printing/cupsd.nix +++ b/nixos/modules/services/printing/cupsd.nix @@ -134,6 +134,15 @@ in ''; }; + stateless = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + If set, all state directories relating to CUPS will be removed on + startup of the service. + ''; + }; + startWhenNeeded = mkOption { type = types.bool; default = true; @@ -343,8 +352,9 @@ in path = [ cups.out ]; - preStart = - '' + preStart = lib.optionalString cfg.stateless '' + rm -rf /var/cache/cups /var/lib/cups /var/spool/cups + '' + '' mkdir -m 0700 -p /var/cache/cups mkdir -m 0700 -p /var/spool/cups mkdir -m 0755 -p ${cfg.tempDir} diff --git a/nixos/modules/services/system/cachix-watch-store.nix b/nixos/modules/services/system/cachix-watch-store.nix new file mode 100644 index 0000000000000..ec73c0bcdcfe5 --- /dev/null +++ b/nixos/modules/services/system/cachix-watch-store.nix @@ -0,0 +1,87 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.cachix-watch-store; +in +{ + meta.maintainers = [ lib.maintainers.jfroche lib.maintainers.domenkozar ]; + + options.services.cachix-watch-store = { + enable = mkEnableOption (lib.mdDoc "Cachix Watch Store: https://docs.cachix.org"); + + cacheName = mkOption { + type = types.str; + description = lib.mdDoc "Cachix binary cache name"; + }; + + cachixTokenFile = mkOption { + type = types.path; + description = lib.mdDoc '' + Required file that needs to contain the cachix auth token. + ''; + }; + + compressionLevel = mkOption { + type = types.nullOr types.int; + description = lib.mdDoc "The compression level for XZ compression (between 0 and 9)"; + default = null; + }; + + jobs = mkOption { + type = types.nullOr types.int; + description = lib.mdDoc "Number of threads used for pushing store paths"; + default = null; + }; + + host = mkOption { + type = types.nullOr types.str; + default = null; + description = lib.mdDoc "Cachix host to connect to"; + }; + + verbose = mkOption { + type = types.bool; + description = lib.mdDoc "Enable verbose output"; + default = false; + }; + + package = mkOption { + type = types.package; + default = pkgs.cachix; + defaultText = literalExpression "pkgs.cachix"; + description = lib.mdDoc "Cachix Client package to use."; + }; + + }; + + config = mkIf cfg.enable { + systemd.services.cachix-watch-store-agent = { + description = "Cachix watch store Agent"; + after = [ "network-online.target" ]; + path = [ config.nix.package ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + # we don't want to kill children processes as those are deployments + KillMode = "process"; + Restart = "on-failure"; + DynamicUser = true; + LoadCredential = [ + "cachix-token:${toString cfg.cachixTokenFile}" + ]; + }; + script = + let + command = [ "${cfg.package}/bin/cachix" ] + ++ (lib.optional cfg.verbose "--verbose") ++ (lib.optionals (cfg.host != null) [ "--host" cfg.host ]) + ++ [ "watch-store" ] ++ (lib.optionals (cfg.compressionLevel != null) [ "--compression-level" (toString cfg.compressionLevel) ]) + ++ (lib.optionals (cfg.jobs != null) [ "--jobs" (toString cfg.jobs) ]) ++ [ cfg.cacheName ]; + in + '' + export CACHIX_AUTH_TOKEN="$(<"$CREDENTIALS_DIRECTORY/cachix-token")" + ${lib.escapeShellArgs command} + ''; + }; + }; +} diff --git a/nixos/modules/services/web-apps/wordpress.nix b/nixos/modules/services/web-apps/wordpress.nix index d3dda27c3d695..660f1b2d7f868 100644 --- a/nixos/modules/services/web-apps/wordpress.nix +++ b/nixos/modules/services/web-apps/wordpress.nix @@ -22,6 +22,7 @@ let ln -s ${wpConfig hostName cfg} $out/share/wordpress/wp-config.php # symlink uploads directory ln -s ${cfg.uploadsDir} $out/share/wordpress/wp-content/uploads + ln -s ${cfg.fontsDir} $out/share/wordpress/wp-content/fonts # https://github.com/NixOS/nixpkgs/pull/53399 # @@ -95,6 +96,15 @@ let ''; }; + fontsDir = mkOption { + type = types.path; + default = "/var/lib/wordpress/${name}/fonts"; + description = lib.mdDoc '' + This directory is used to download fonts from a remote location, e.g. + to host google fonts locally. + ''; + }; + plugins = mkOption { type = types.listOf types.path; default = []; diff --git a/nixos/modules/services/x11/desktop-managers/gnome.nix b/nixos/modules/services/x11/desktop-managers/gnome.nix index d3db98cb4e2ae..9c1978e362bc7 100644 --- a/nixos/modules/services/x11/desktop-managers/gnome.nix +++ b/nixos/modules/services/x11/desktop-managers/gnome.nix @@ -389,8 +389,8 @@ in ++ utils.removePackagesByName optionalPackages config.environment.gnome.excludePackages; services.colord.enable = mkDefault true; - services.gnome.chrome-gnome-shell.enable = mkDefault true; services.gnome.glib-networking.enable = true; + services.gnome.gnome-browser-connector.enable = mkDefault true; services.gnome.gnome-initial-setup.enable = mkDefault true; services.gnome.gnome-remote-desktop.enable = mkDefault true; services.gnome.gnome-settings-daemon.enable = true; @@ -520,7 +520,7 @@ in # Let nautilus find extensions # TODO: Create nautilus-with-extensions package - environment.sessionVariables.NAUTILUS_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-3.0"; + environment.sessionVariables.NAUTILUS_4_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-4"; # Override default mimeapps for nautilus environment.sessionVariables.XDG_DATA_DIRS = [ "${mimeAppsList}/share" ]; diff --git a/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixos/modules/services/x11/desktop-managers/pantheon.nix index 90a8787ed227e..5c0203224e139 100644 --- a/nixos/modules/services/x11/desktop-managers/pantheon.nix +++ b/nixos/modules/services/x11/desktop-managers/pantheon.nix @@ -285,7 +285,7 @@ in elementary-music elementary-photos elementary-screenshot - elementary-tasks + # elementary-tasks elementary-terminal elementary-videos epiphany diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix index 3e04f6d0e6bb2..44faa19bc22ab 100644 --- a/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -228,6 +228,14 @@ in is not strictly required for Plasma Mobile to run. ''; }; + + bigscreen.enable = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc '' + Enable support for running the Plasma Bigscreen session. + ''; + }; }; imports = [ @@ -237,7 +245,7 @@ in config = mkMerge [ # Common Plasma dependencies - (mkIf (cfg.enable || cfg.mobile.enable) { + (mkIf (cfg.enable || cfg.mobile.enable || cfg.bigscreen.enable) { security.wrappers = { kscreenlocker_greet = { @@ -595,5 +603,29 @@ in services.xserver.displayManager.sessionPackages = [ pkgs.libsForQt5.plasma5.plasma-mobile ]; }) + + # Plasma Bigscreen + (mkIf cfg.bigscreen.enable { + environment.systemPackages = + with pkgs.plasma5Packages; + [ + plasma-nano + plasma-settings + plasma-bigscreen + plasma-remotecontrollers + + aura-browser + plank-player + + plasma-pa + plasma-nm + kdeconnect-kde + ]; + + services.xserver.displayManager.sessionPackages = [ pkgs.plasma5Packages.plasma-bigscreen ]; + + # required for plasma-remotecontrollers to work correctly + hardware.uinput.enable = true; + }) ]; } diff --git a/nixos/modules/services/x11/window-managers/dwm.nix b/nixos/modules/services/x11/window-managers/dwm.nix index 2dac41dbe988f..1881826944aac 100644 --- a/nixos/modules/services/x11/window-managers/dwm.nix +++ b/nixos/modules/services/x11/window-managers/dwm.nix @@ -13,7 +13,27 @@ in ###### interface options = { - services.xserver.windowManager.dwm.enable = mkEnableOption (lib.mdDoc "dwm"); + services.xserver.windowManager.dwm = { + enable = mkEnableOption (lib.mdDoc "dwm"); + package = mkOption { + type = types.package; + default = pkgs.dwm; + defaultText = literalExpression "pkgs.dwm"; + example = literalExpression '' + pkgs.dwm.overrideAttrs (oldAttrs: rec { + patches = [ + (super.fetchpatch { + url = "https://dwm.suckless.org/patches/steam/dwm-steam-6.2.diff"; + sha256 = "1ld1z3fh6p5f8gr62zknx3axsinraayzxw3rz1qwg73mx2zk5y1f"; + }) + ]; + }) + ''; + description = lib.mdDoc '' + dwm package to use. + ''; + }; + }; }; @@ -30,7 +50,7 @@ in ''; }; - environment.systemPackages = [ pkgs.dwm ]; + environment.systemPackages = [ cfg.package ]; }; diff --git a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py index 5398ef6b84eb8..68da20615917b 100644 --- a/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py +++ b/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py @@ -175,22 +175,22 @@ def get_specialisations(profile: Optional[str], generation: int, _: Optional[str def remove_old_entries(gens: List[SystemIdentifier]) -> None: rex_profile = re.compile("^@efiSysMountPoint@/loader/entries/nixos-(.*)-generation-.*\.conf$") - rex_generation = re.compile("^@efiSysMountPoint@/loader/entries/nixos.*-generation-(.*)\.conf$") + rex_generation = re.compile("^@efiSysMountPoint@/loader/entries/nixos.*-generation-([0-9]+)(-specialisation-.*)?\.conf$") known_paths = [] for gen in gens: known_paths.append(copy_from_profile(*gen, "kernel", True)) known_paths.append(copy_from_profile(*gen, "initrd", True)) for path in glob.iglob("@efiSysMountPoint@/loader/entries/nixos*-generation-[1-9]*.conf"): + if rex_profile.match(path): + prof = rex_profile.sub(r"\1", path) + else: + prof = None try: - if rex_profile.match(path): - prof = rex_profile.sub(r"\1", path) - else: - prof = "system" gen_number = int(rex_generation.sub(r"\1", path)) - if not (prof, gen_number) in gens: - os.unlink(path) except ValueError: - pass + continue + if not (prof, gen_number, None) in gens: + os.unlink(path) for path in glob.iglob("@efiSysMountPoint@/efi/nixos/*"): if not path in known_paths and not os.path.isdir(path): os.unlink(path) diff --git a/nixos/modules/system/boot/luksroot.nix b/nixos/modules/system/boot/luksroot.nix index 38f8b6fd87c21..02b020b61eb60 100644 --- a/nixos/modules/system/boot/luksroot.nix +++ b/nixos/modules/system/boot/luksroot.nix @@ -481,8 +481,8 @@ let ++ optional v.allowDiscards "discard" ++ optionals v.bypassWorkqueues [ "no-read-workqueue" "no-write-workqueue" ] ++ optional (v.header != null) "header=${v.header}" - ++ optional (v.keyFileOffset != null) "keyfile-offset=${v.keyFileOffset}" - ++ optional (v.keyFileSize != null) "keyfile-size=${v.keyFileSize}" + ++ optional (v.keyFileOffset != null) "keyfile-offset=${toString v.keyFileOffset}" + ++ optional (v.keyFileSize != null) "keyfile-size=${toString v.keyFileSize}" ; in "${n} ${v.device} ${if v.keyFile == null then "-" else v.keyFile} ${lib.concatStringsSep "," opts}") luks.devices)); diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix index cb60117f0eb82..a9b81dd116bbd 100644 --- a/nixos/modules/system/boot/networkd.nix +++ b/nixos/modules/system/boot/networkd.nix @@ -501,7 +501,6 @@ let "LinkLocalAddressing" "IPv4LLRoute" "DefaultRouteOnDevice" - "IPv6Token" "LLMNR" "MulticastDNS" "DNSOverTLS" @@ -526,7 +525,7 @@ let "IPv6ProxyNDP" "IPv6ProxyNDPAddress" "IPv6SendRA" - "DHCPv6PrefixDelegation" + "DHCPPrefixDelegation" "IPv6MTUBytes" "Bridge" "Bond" @@ -569,12 +568,11 @@ let (assertValueOneOf "IPv4ProxyARP" boolValues) (assertValueOneOf "IPv6ProxyNDP" boolValues) (assertValueOneOf "IPv6SendRA" boolValues) - (assertValueOneOf "DHCPv6PrefixDelegation" boolValues) + (assertValueOneOf "DHCPPrefixDelegation" boolValues) (assertByteFormat "IPv6MTUBytes") (assertValueOneOf "ActiveSlave" boolValues) (assertValueOneOf "PrimarySlave" boolValues) (assertValueOneOf "ConfigureWithoutCarrier" boolValues) - (assertValueOneOf "IgnoreCarrierLoss" boolValues) (assertValueOneOf "KeepConfiguration" (boolValues ++ ["static" "dhcp-on-stop" "dhcp"])) ]; @@ -619,6 +617,7 @@ let "User" "SuppressPrefixLength" "Type" + "SuppressInterfaceGroup" ]) (assertInt "TypeOfService") (assertRange "TypeOfService" 0 255) @@ -632,6 +631,7 @@ let (assertInt "SuppressPrefixLength") (assertRange "SuppressPrefixLength" 0 128) (assertValueOneOf "Type" ["blackhole" "unreachable" "prohibit"]) + (assertRange "SuppressInterfaceGroup" 0 2147483647) ]; sectionRoute = checkUnitConfig "Route" [ @@ -711,6 +711,9 @@ let "BlackList" "RequestOptions" "SendOption" + "FallbackLeaseLifetimeSec" + "Label" + "Use6RD" ]) (assertValueOneOf "UseDNS" boolValues) (assertValueOneOf "RoutesToDNS" boolValues) @@ -733,6 +736,8 @@ let (assertPort "ListenPort") (assertValueOneOf "SendRelease" boolValues) (assertValueOneOf "SendDecline" boolValues) + (assertValueOneOf "FallbackLeaseLifetimeSec" ["forever" "infinity"]) + (assertValueOneOf "Use6RD" boolValues) ]; sectionDHCPv6 = checkUnitConfig "DHCPv6" [ @@ -745,7 +750,6 @@ let "MUDURL" "RequestOptions" "SendVendorOption" - "ForceDHCPv6PDOtherInformation" "PrefixDelegationHint" "WithoutRA" "SendOption" @@ -754,27 +758,33 @@ let "DUIDType" "DUIDRawData" "IAID" + "UseDelegatedPrefix" ]) (assertValueOneOf "UseAddress" boolValues) (assertValueOneOf "UseDNS" boolValues) (assertValueOneOf "UseNTP" boolValues) (assertInt "RouteMetric") (assertValueOneOf "RapidCommit" boolValues) - (assertValueOneOf "ForceDHCPv6PDOtherInformation" boolValues) - (assertValueOneOf "WithoutRA" ["solicit" "information-request"]) + (assertValueOneOf "WithoutRA" ["no" "solicit" "information-request"]) (assertRange "SendOption" 1 65536) (assertInt "IAID") + (assertValueOneOf "UseDelegatedPrefix" boolValues) ]; - sectionDHCPv6PrefixDelegation = checkUnitConfig "DHCPv6PrefixDelegation" [ + sectionDHCPPrefixDelegation = checkUnitConfig "DHCPPrefixDelegation" [ (assertOnlyFields [ + "UplinkInterface" "SubnetId" "Announce" "Assign" "Token" + "ManageTemporaryAddress" + "RouteMetric" ]) (assertValueOneOf "Announce" boolValues) (assertValueOneOf "Assign" boolValues) + (assertValueOneOf "ManageTemporaryAddress" boolValues) + (assertRange "RouteMetric" 0 4294967295) ]; sectionIPv6AcceptRA = checkUnitConfig "IPv6AcceptRA" [ @@ -792,6 +802,10 @@ let "RouteAllowList" "DHCPv6Client" "RouteMetric" + "UseMTU" + "UseGateway" + "UseRoutePrefix" + "Token" ]) (assertValueOneOf "UseDNS" boolValues) (assertValueOneOf "UseDomains" (boolValues ++ ["route"])) @@ -799,6 +813,9 @@ let (assertValueOneOf "UseAutonomousPrefix" boolValues) (assertValueOneOf "UseOnLinkPrefix" boolValues) (assertValueOneOf "DHCPv6Client" (boolValues ++ ["always"])) + (assertValueOneOf "UseMTU" boolValues) + (assertValueOneOf "UseGateway" boolValues) + (assertValueOneOf "UseRoutePrefix" boolValues) ]; sectionDHCPServer = checkUnitConfig "DHCPServer" [ @@ -874,6 +891,7 @@ let "Prefix" "PreferredLifetimeSec" "ValidLifetimeSec" + "Token" ]) (assertValueOneOf "AddressAutoconfiguration" boolValues) (assertValueOneOf "OnLink" boolValues) @@ -1338,12 +1356,17 @@ let }; dhcpV6PrefixDelegationConfig = mkOption { + visible = false; + apply = _: throw "The option `systemd.network.networks.<name>.dhcpV6PrefixDelegationConfig` has been renamed to `systemd.network.networks.<name>.dhcpPrefixDelegationConfig`."; + }; + + dhcpPrefixDelegationConfig = mkOption { default = {}; example = { SubnetId = "auto"; Announce = true; }; - type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPv6PrefixDelegation; + type = types.addCheck (types.attrsOf unitOption) check.network.sectionDHCPPrefixDelegation; description = lib.mdDoc '' Each attribute in this set specifies an option in the - `[DHCPv6PrefixDelegation]` section of the unit. See + `[DHCPPrefixDelegation]` section of the unit. See {manpage}`systemd.network(5)` for details. ''; }; @@ -1789,9 +1812,9 @@ let [DHCPv6] ${attrsToSection def.dhcpV6Config} '' - + optionalString (def.dhcpV6PrefixDelegationConfig != { }) '' - [DHCPv6PrefixDelegation] - ${attrsToSection def.dhcpV6PrefixDelegationConfig} + + optionalString (def.dhcpPrefixDelegationConfig != { }) '' + [DHCPPrefixDelegation] + ${attrsToSection def.dhcpPrefixDelegationConfig} '' + optionalString (def.ipv6AcceptRAConfig != { }) '' [IPv6AcceptRA] diff --git a/nixos/modules/virtualisation/oci-containers.nix b/nixos/modules/virtualisation/oci-containers.nix index 81cdf1dd72b46..61066c3cbd758 100644 --- a/nixos/modules/virtualisation/oci-containers.nix +++ b/nixos/modules/virtualisation/oci-containers.nix @@ -227,6 +227,7 @@ let mkService = name: container: let dependsOn = map (x: "${cfg.backend}-${x}.service") container.dependsOn; + escapedName = escapeShellArg name; in { wantedBy = [] ++ optional (container.autoStart) "multi-user.target"; after = lib.optionals (cfg.backend == "docker") [ "docker.service" "docker.socket" ] ++ dependsOn; @@ -250,16 +251,25 @@ let ${optionalString (container.imageFile != null) '' ${cfg.backend} load -i ${container.imageFile} ''} + ${optionalString (cfg.backend == "podman") '' + rm -f /run/podman-${escapedName}.ctr-id + ''} ''; script = concatStringsSep " \\\n " ([ "exec ${cfg.backend} run" "--rm" - "--name=${escapeShellArg name}" + "--name=${escapedName}" "--log-driver=${container.log-driver}" ] ++ optional (container.entrypoint != null) "--entrypoint=${escapeShellArg container.entrypoint}" - ++ (mapAttrsToList (k: v: "-e ${escapeShellArg k}=${escapeShellArg v}") container.environment) + ++ lib.optionals (cfg.backend == "podman") [ + "--cidfile=/run/podman-${escapedName}.ctr-id" + "--cgroups=no-conmon" + "--sdnotify=conmon" + "-d" + "--replace" + ] ++ (mapAttrsToList (k: v: "-e ${escapeShellArg k}=${escapeShellArg v}") container.environment) ++ map (f: "--env-file ${escapeShellArg f}") container.environmentFiles ++ map (p: "-p ${escapeShellArg p}") container.ports ++ optional (container.user != null) "-u ${escapeShellArg container.user}" @@ -270,8 +280,12 @@ let ++ map escapeShellArg container.cmd ); - preStop = "[ $SERVICE_RESULT = success ] || ${cfg.backend} stop ${name}"; - postStop = "${cfg.backend} rm -f ${name} || true"; + preStop = if cfg.backend == "podman" + then "[ $SERVICE_RESULT = success ] || podman stop --ignore --cidfile=/run/podman-${escapedName}.ctr-id" + else "[ $SERVICE_RESULT = success ] || ${cfg.backend} stop ${name}"; + postStop = if cfg.backend == "podman" + then "podman rm -f --ignore --cidfile=/run/podman-${escapedName}.ctr-id" + else "${cfg.backend} rm -f ${name} || true"; serviceConfig = { ### There is no generalized way of supporting `reload` for docker @@ -293,6 +307,10 @@ let TimeoutStartSec = 0; TimeoutStopSec = 120; Restart = "always"; + } // optionalAttrs (cfg.backend == "podman") { + Environment="PODMAN_SYSTEMD_UNIT=podman-${name}.service"; + Type="notify"; + NotifyAccess="all"; }; }; diff --git a/nixos/release-combined.nix b/nixos/release-combined.nix index e8677f7e1e975..a11ee31ab8d04 100644 --- a/nixos/release-combined.nix +++ b/nixos/release-combined.nix @@ -4,8 +4,8 @@ { nixpkgs ? { outPath = (import ../lib).cleanSource ./..; revCount = 56789; shortRev = "gfedcba"; } , stableBranch ? false -, supportedSystems ? [ "x86_64-linux" ] -, limitedSupportedSystems ? [ "i686-linux" "aarch64-linux" ] +, supportedSystems ? [ "aarch64-linux" "x86_64-linux" ] +, limitedSupportedSystems ? [ "i686-linux" ] }: let @@ -50,17 +50,17 @@ in rec { (onFullSupported "nixos.dummy") (onAllSupported "nixos.iso_minimal") (onSystems ["x86_64-linux" "aarch64-linux"] "nixos.amazonImage") - (onSystems ["x86_64-linux"] "nixos.iso_plasma5") - (onSystems ["x86_64-linux"] "nixos.iso_gnome") + (onFullSupported "nixos.iso_plasma5") + (onFullSupported "nixos.iso_gnome") (onFullSupported "nixos.manual") (onSystems ["x86_64-linux"] "nixos.ova") (onSystems ["aarch64-linux"] "nixos.sd_image") (onSystems ["x86_64-linux"] "nixos.tests.boot.biosCdrom") (onSystems ["x86_64-linux"] "nixos.tests.boot.biosUsb") (onFullSupported "nixos.tests.boot-stage1") - (onSystems ["x86_64-linux"] "nixos.tests.boot.uefiCdrom") - (onSystems ["x86_64-linux"] "nixos.tests.boot.uefiUsb") - (onSystems ["x86_64-linux"] "nixos.tests.chromium") + (onFullSupported "nixos.tests.boot.uefiCdrom") + (onFullSupported "nixos.tests.boot.uefiUsb") + (onFullSupported "nixos.tests.chromium") (onFullSupported "nixos.tests.containers-imperative") (onFullSupported "nixos.tests.containers-ip") (onSystems ["x86_64-linux"] "nixos.tests.docker") diff --git a/nixos/release-small.nix b/nixos/release-small.nix index 8367610fb7f71..1719d6738c5cd 100644 --- a/nixos/release-small.nix +++ b/nixos/release-small.nix @@ -4,7 +4,7 @@ { nixpkgs ? { outPath = (import ../lib).cleanSource ./..; revCount = 56789; shortRev = "gfedcba"; } , stableBranch ? false -, supportedSystems ? [ "x86_64-linux" ] # no i686-linux +, supportedSystems ? [ "aarch64-linux" "x86_64-linux" ] # no i686-linux }: let @@ -53,7 +53,8 @@ in rec { }; boot = { inherit (nixos'.tests.boot) - biosCdrom; + biosCdrom + uefiCdrom; }; }; }; @@ -83,45 +84,56 @@ in rec { vim; }; - tested = pkgs.releaseTools.aggregate { + tested = let + onSupported = x: map (system: "${x}.${system}") supportedSystems; + onSystems = systems: x: map (system: "${x}.${system}") + (pkgs.lib.intersectLists systems supportedSystems); + in pkgs.releaseTools.aggregate { name = "nixos-${nixos.channel.version}"; meta = { description = "Release-critical builds for the NixOS channel"; maintainers = [ lib.maintainers.eelco ]; }; - constituents = - [ "nixos.channel" - "nixos.dummy.x86_64-linux" - "nixos.iso_minimal.x86_64-linux" - "nixos.amazonImage.x86_64-linux" - "nixos.manual.x86_64-linux" - "nixos.tests.boot.biosCdrom.x86_64-linux" - "nixos.tests.containers-imperative.x86_64-linux" - "nixos.tests.containers-ip.x86_64-linux" - "nixos.tests.firewall.x86_64-linux" - "nixos.tests.installer.lvm.x86_64-linux" - "nixos.tests.installer.separateBoot.x86_64-linux" - "nixos.tests.installer.simple.x86_64-linux" - "nixos.tests.ipv6.x86_64-linux" - "nixos.tests.login.x86_64-linux" - "nixos.tests.misc.x86_64-linux" - "nixos.tests.nat.firewall-conntrack.x86_64-linux" - "nixos.tests.nat.firewall.x86_64-linux" - "nixos.tests.nat.standalone.x86_64-linux" - # fails with kernel >= 5.15 https://github.com/NixOS/nixpkgs/pull/152505#issuecomment-1005049314 - #"nixos.tests.nfs3.simple.x86_64-linux" - "nixos.tests.openssh.x86_64-linux" - "nixos.tests.php.fpm.x86_64-linux" - "nixos.tests.php.pcre.x86_64-linux" - "nixos.tests.predictable-interface-names.predictable.x86_64-linux" - "nixos.tests.predictable-interface-names.predictableNetworkd.x86_64-linux" - "nixos.tests.predictable-interface-names.unpredictable.x86_64-linux" - "nixos.tests.predictable-interface-names.unpredictableNetworkd.x86_64-linux" - "nixos.tests.proxy.x86_64-linux" - "nixos.tests.simple.x86_64-linux" - "nixpkgs.jdk.x86_64-linux" + constituents = lib.flatten [ + [ + "nixos.channel" "nixpkgs.tarball" - ]; + ] + (map (onSystems [ "x86_64-linux" ]) [ + "nixos.tests.boot.biosCdrom" + "nixos.tests.installer.lvm" + "nixos.tests.installer.separateBoot" + "nixos.tests.installer.simple" + ]) + (map onSupported [ + "nixos.dummy" + "nixos.iso_minimal" + "nixos.amazonImage" + "nixos.manual" + "nixos.tests.boot.uefiCdrom" + "nixos.tests.containers-imperative" + "nixos.tests.containers-ip" + "nixos.tests.firewall" + "nixos.tests.ipv6" + "nixos.tests.login" + "nixos.tests.misc" + "nixos.tests.nat.firewall-conntrack" + "nixos.tests.nat.firewall" + "nixos.tests.nat.standalone" + # fails with kernel >= 5.15 https://github.com/NixOS/nixpkgs/pull/152505#issuecomment-1005049314 + #"nixos.tests.nfs3.simple" + "nixos.tests.openssh" + "nixos.tests.php.fpm" + "nixos.tests.php.pcre" + "nixos.tests.predictable-interface-names.predictable" + "nixos.tests.predictable-interface-names.predictableNetworkd" + "nixos.tests.predictable-interface-names.unpredictable" + "nixos.tests.predictable-interface-names.unpredictableNetworkd" + "nixos.tests.proxy" + "nixos.tests.simple" + "nixpkgs.jdk" + ]) + ]; }; } diff --git a/nixos/release.nix b/nixos/release.nix index 4f27e5dbb215a..919aa86a2d639 100644 --- a/nixos/release.nix +++ b/nixos/release.nix @@ -169,13 +169,13 @@ in rec { inherit system; }); - iso_plasma5 = forMatchingSystems [ "x86_64-linux" ] (system: makeIso { + iso_plasma5 = forMatchingSystems supportedSystems (system: makeIso { module = ./modules/installer/cd-dvd/installation-cd-graphical-calamares-plasma5.nix; type = "plasma5"; inherit system; }); - iso_gnome = forMatchingSystems [ "x86_64-linux" ] (system: makeIso { + iso_gnome = forMatchingSystems supportedSystems (system: makeIso { module = ./modules/installer/cd-dvd/installation-cd-graphical-calamares-gnome.nix; type = "gnome"; inherit system; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 643f1181eb5d1..32342510f70f4 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -117,9 +117,9 @@ in { ceph-single-node = handleTestOn ["x86_64-linux"] ./ceph-single-node.nix {}; ceph-single-node-bluestore = handleTestOn ["x86_64-linux"] ./ceph-single-node-bluestore.nix {}; certmgr = handleTest ./certmgr.nix {}; - cfssl = handleTestOn ["x86_64-linux"] ./cfssl.nix {}; + cfssl = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cfssl.nix {}; charliecloud = handleTest ./charliecloud.nix {}; - chromium = (handleTestOn ["x86_64-linux"] ./chromium.nix {}).stable or {}; + chromium = (handleTestOn ["aarch64-linux" "x86_64-linux"] ./chromium.nix {}).stable or {}; cinnamon = handleTest ./cinnamon.nix {}; cjdns = handleTest ./cjdns.nix {}; clickhouse = handleTest ./clickhouse.nix {}; @@ -147,7 +147,7 @@ in { corerad = handleTest ./corerad.nix {}; coturn = handleTest ./coturn.nix {}; couchdb = handleTest ./couchdb.nix {}; - cri-o = handleTestOn ["x86_64-linux"] ./cri-o.nix {}; + cri-o = handleTestOn ["aarch64-linux" "x86_64-linux"] ./cri-o.nix {}; custom-ca = handleTest ./custom-ca.nix {}; croc = handleTest ./croc.nix {}; deluge = handleTest ./deluge.nix {}; @@ -160,8 +160,8 @@ in { dnscrypt-wrapper = handleTestOn ["x86_64-linux"] ./dnscrypt-wrapper {}; dnsdist = handleTest ./dnsdist.nix {}; doas = handleTest ./doas.nix {}; - docker = handleTestOn ["x86_64-linux"] ./docker.nix {}; - docker-rootless = handleTestOn ["x86_64-linux"] ./docker-rootless.nix {}; + docker = handleTestOn ["aarch64-linux" "x86_64-linux"] ./docker.nix {}; + docker-rootless = handleTestOn ["aarch64-linux" "x86_64-linux"] ./docker-rootless.nix {}; docker-registry = handleTest ./docker-registry.nix {}; docker-tools = handleTestOn ["x86_64-linux"] ./docker-tools.nix {}; docker-tools-cross = handleTestOn ["x86_64-linux" "aarch64-linux"] ./docker-tools-cross.nix {}; @@ -253,7 +253,7 @@ in { herbstluftwm = handleTest ./herbstluftwm.nix {}; installed-tests = pkgs.recurseIntoAttrs (handleTest ./installed-tests {}); invidious = handleTest ./invidious.nix {}; - oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {}; + oci-containers = handleTestOn ["aarch64-linux" "x86_64-linux"] ./oci-containers.nix {}; odoo = handleTest ./odoo.nix {}; # 9pnet_virtio used to mount /nix partition doesn't support # hibernation. This test happens to work on x86_64-linux but @@ -299,6 +299,7 @@ in { k3s = handleTest ./k3s {}; kafka = handleTest ./kafka.nix {}; kanidm = handleTest ./kanidm.nix {}; + karma = handleTest ./karma.nix {}; kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {}; kbd-update-search-paths-patch = handleTest ./kbd-update-search-paths-patch.nix {}; kea = handleTest ./kea.nix {}; @@ -441,6 +442,7 @@ in { non-default-filesystems = handleTest ./non-default-filesystems.nix {}; noto-fonts = handleTest ./noto-fonts.nix {}; novacomd = handleTestOn ["x86_64-linux"] ./novacomd.nix {}; + nscd = handleTest ./nscd.nix {}; nsd = handleTest ./nsd.nix {}; nzbget = handleTest ./nzbget.nix {}; nzbhydra2 = handleTest ./nzbhydra2.nix {}; @@ -486,16 +488,18 @@ in { phylactery = handleTest ./web-apps/phylactery.nix {}; pict-rs = handleTest ./pict-rs.nix {}; pinnwand = handleTest ./pinnwand.nix {}; + plasma-bigscreen = handleTest ./plasma-bigscreen.nix {}; plasma5 = handleTest ./plasma5.nix {}; plasma5-systemd-start = handleTest ./plasma5-systemd-start.nix {}; plausible = handleTest ./plausible.nix {}; + please = handleTest ./please.nix {}; pleroma = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./pleroma.nix {}; plikd = handleTest ./plikd.nix {}; plotinus = handleTest ./plotinus.nix {}; podgrab = handleTest ./podgrab.nix {}; - podman = handleTestOn ["x86_64-linux"] ./podman/default.nix {}; - podman-dnsname = handleTestOn ["x86_64-linux"] ./podman/dnsname.nix {}; - podman-tls-ghostunnel = handleTestOn ["x86_64-linux"] ./podman/tls-ghostunnel.nix {}; + podman = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/default.nix {}; + podman-dnsname = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/dnsname.nix {}; + podman-tls-ghostunnel = handleTestOn ["aarch64-linux" "x86_64-linux"] ./podman/tls-ghostunnel.nix {}; polaris = handleTest ./polaris.nix {}; pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {}; postfix = handleTest ./postfix.nix {}; @@ -530,7 +534,6 @@ in { rasdaemon = handleTest ./rasdaemon.nix {}; redis = handleTest ./redis.nix {}; redmine = handleTest ./redmine.nix {}; - resolv = handleTest ./resolv.nix {}; restartByActivationScript = handleTest ./restart-by-activation-script.nix {}; restic = handleTest ./restic.nix {}; retroarch = handleTest ./retroarch.nix {}; @@ -630,8 +633,7 @@ in { tmate-ssh-server = handleTest ./tmate-ssh-server.nix { }; tomcat = handleTest ./tomcat.nix {}; tor = handleTest ./tor.nix {}; - # traefik test relies on docker-containers - traefik = handleTestOn ["x86_64-linux"] ./traefik.nix {}; + traefik = handleTestOn ["aarch64-linux" "x86_64-linux"] ./traefik.nix {}; trafficserver = handleTest ./trafficserver.nix {}; transmission = handleTest ./transmission.nix {}; # tracee requires bpf diff --git a/nixos/tests/cloud-init.nix b/nixos/tests/cloud-init.nix index 9feb8d5c1526e..a86cd569e4215 100644 --- a/nixos/tests/cloud-init.nix +++ b/nixos/tests/cloud-init.nix @@ -60,6 +60,7 @@ in makeTest { name = "cloud-init"; meta = with pkgs.lib.maintainers; { maintainers = [ lewo ]; + broken = true; # almost always times out after spending many hours }; nodes.machine = { ... }: { diff --git a/nixos/tests/custom-ca.nix b/nixos/tests/custom-ca.nix index 73e47c3c9d0d6..25a7b6fdea46e 100644 --- a/nixos/tests/custom-ca.nix +++ b/nixos/tests/custom-ca.nix @@ -191,5 +191,5 @@ in firefox = { error = "Security Risk"; }; chromium = { error = "not private"; }; qutebrowser = { args = "-T"; error = "Certificate error"; }; - midori = { error = "Security"; }; + midori = { args = "-p"; error = "Security"; }; } diff --git a/nixos/tests/domination.nix b/nixos/tests/domination.nix index 09027740ab8de..409a7f3029c42 100644 --- a/nixos/tests/domination.nix +++ b/nixos/tests/domination.nix @@ -20,7 +20,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { machine.wait_for_x() machine.execute("domination >&2 &") machine.wait_for_window("Menu") - machine.wait_for_text("New Game") + machine.wait_for_text(r"(New Game|Start Server|Load Game|Help Manual|Join Game|About|Play Online)") machine.screenshot("screen") ''; }) diff --git a/nixos/tests/grafana.nix b/nixos/tests/grafana.nix index 174d664d8772b..5364f0ca8b0b4 100644 --- a/nixos/tests/grafana.nix +++ b/nixos/tests/grafana.nix @@ -81,8 +81,11 @@ in { with subtest("Successful API query as admin user with sqlite db"): sqlite.wait_for_unit("grafana.service") sqlite.wait_for_open_port(3000) + print(sqlite.succeed( + "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users -i" + )) sqlite.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep testadmin\@localhost" + "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost" ) sqlite.shutdown() @@ -92,7 +95,7 @@ in { postgresql.wait_for_open_port(3000) postgresql.wait_for_open_port(5432) postgresql.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep testadmin\@localhost" + "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost" ) postgresql.shutdown() @@ -102,7 +105,7 @@ in { mysql.wait_for_open_port(3000) mysql.wait_for_open_port(3306) mysql.succeed( - "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep testadmin\@localhost" + "curl -sSfN -u testadmin:snakeoilpwd http://127.0.0.1:3000/api/org/users | grep admin\@localhost" ) mysql.shutdown() ''; diff --git a/nixos/tests/installed-tests/default.nix b/nixos/tests/installed-tests/default.nix index b2c1b43f90ee9..2e38cd389c74a 100644 --- a/nixos/tests/installed-tests/default.nix +++ b/nixos/tests/installed-tests/default.nix @@ -101,7 +101,6 @@ in json-glib = callInstalledTest ./json-glib.nix {}; ibus = callInstalledTest ./ibus.nix {}; libgdata = callInstalledTest ./libgdata.nix {}; - librsvg = callInstalledTest ./librsvg.nix {}; glib-testing = callInstalledTest ./glib-testing.nix {}; libjcat = callInstalledTest ./libjcat.nix {}; libxmlb = callInstalledTest ./libxmlb.nix {}; diff --git a/nixos/tests/installed-tests/librsvg.nix b/nixos/tests/installed-tests/librsvg.nix deleted file mode 100644 index 378e7cce3ff4c..0000000000000 --- a/nixos/tests/installed-tests/librsvg.nix +++ /dev/null @@ -1,9 +0,0 @@ -{ pkgs, makeInstalledTest, ... }: - -makeInstalledTest { - tested = pkgs.librsvg; - - testConfig = { - virtualisation.memorySize = 2047; - }; -} diff --git a/nixos/tests/karma.nix b/nixos/tests/karma.nix new file mode 100644 index 0000000000000..5ac2983b8aa3e --- /dev/null +++ b/nixos/tests/karma.nix @@ -0,0 +1,84 @@ +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "karma"; + nodes = { + server = { ... }: { + services.prometheus.alertmanager = { + enable = true; + logLevel = "debug"; + port = 9093; + openFirewall = true; + configuration = { + global = { + resolve_timeout = "1m"; + }; + route = { + # Root route node + receiver = "test"; + group_by = ["..."]; + continue = false; + group_wait = "1s"; + group_interval="15s"; + repeat_interval = "24h"; + }; + receivers = [ + { + name = "test"; + webhook_configs = [ + { + url = "http://localhost:1234"; + send_resolved = true; + max_alerts = 0; + } + ]; + } + ]; + }; + }; + services.karma = { + enable = true; + openFirewall = true; + settings = { + listen = { + address = "0.0.0.0"; + port = 8081; + }; + alertmanager = { + servers = [ + { + name = "alertmanager"; + uri = "https://127.0.0.1:9093"; + } + ]; + }; + karma.name = "test-dashboard"; + log.config = true; + log.requests = true; + log.timestamp = true; + }; + }; + }; + }; + + testScript = '' + start_all() + + with subtest("Wait for server to come up"): + + server.wait_for_unit("alertmanager.service") + server.wait_for_unit("karma.service") + + server.sleep(5) # wait for both services to settle + + server.wait_for_open_port(9093) + server.wait_for_open_port(8081) + + with subtest("Test alertmanager readiness"): + server.succeed("curl -s http://127.0.0.1:9093/-/ready") + + # Karma only starts serving the dashboard once it has established connectivity to all alertmanagers in its config + # Therefore, this will fail if karma isn't able to reach alertmanager + server.succeed("curl -s http://127.0.0.1:8081") + + server.shutdown() + ''; +}) diff --git a/nixos/tests/kubernetes/base.nix b/nixos/tests/kubernetes/base.nix index 714ac3098c0d7..ba7b2d9b1d2de 100644 --- a/nixos/tests/kubernetes/base.nix +++ b/nixos/tests/kubernetes/base.nix @@ -43,7 +43,7 @@ let trustedInterfaces = ["mynet"]; extraCommands = concatMapStrings (node: '' - iptables -A INPUT -s ${node.config.networking.primaryIPAddress} -j ACCEPT + iptables -A INPUT -s ${node.networking.primaryIPAddress} -j ACCEPT '') (attrValues nodes); }; }; diff --git a/nixos/tests/kubernetes/default.nix b/nixos/tests/kubernetes/default.nix index 60ba482758fbe..a3de9ed115d4c 100644 --- a/nixos/tests/kubernetes/default.nix +++ b/nixos/tests/kubernetes/default.nix @@ -4,8 +4,6 @@ let dns = import ./dns.nix { inherit system pkgs; }; rbac = import ./rbac.nix { inherit system pkgs; }; - # TODO kubernetes.e2e should eventually replace kubernetes.rbac when it works - # e2e = import ./e2e.nix { inherit system pkgs; }; in { dns-single-node = dns.singlenode.test; diff --git a/nixos/tests/kubernetes/e2e.nix b/nixos/tests/kubernetes/e2e.nix deleted file mode 100644 index fb29d9cc6953f..0000000000000 --- a/nixos/tests/kubernetes/e2e.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ system ? builtins.currentSystem, pkgs ? import ../../.. { inherit system; } }: -with import ./base.nix { inherit system; }; -let - domain = "my.zyx"; - certs = import ./certs.nix { externalDomain = domain; kubelets = ["machine1" "machine2"]; }; - kubeconfig = pkgs.writeText "kubeconfig.json" (builtins.toJSON { - apiVersion = "v1"; - kind = "Config"; - clusters = [{ - name = "local"; - cluster.certificate-authority = "${certs.master}/ca.pem"; - cluster.server = "https://api.${domain}"; - }]; - users = [{ - name = "kubelet"; - user = { - client-certificate = "${certs.admin}/admin.pem"; - client-key = "${certs.admin}/admin-key.pem"; - }; - }]; - contexts = [{ - context = { - cluster = "local"; - user = "kubelet"; - }; - current-context = "kubelet-context"; - }]; - }); - - base = { - name = "e2e"; - inherit domain certs; - test = '' - $machine1->succeed("e2e.test -kubeconfig ${kubeconfig} -provider local -ginkgo.focus '\\[Conformance\\]' -ginkgo.skip '\\[Flaky\\]|\\[Serial\\]'"); - ''; - }; -in { - singlenode = mkKubernetesSingleNodeTest base; - multinode = mkKubernetesMultiNodeTest base; -} diff --git a/nixos/tests/make-test-python.nix b/nixos/tests/make-test-python.nix index c3bbd67423726..7a96f538d8d7a 100644 --- a/nixos/tests/make-test-python.nix +++ b/nixos/tests/make-test-python.nix @@ -6,6 +6,4 @@ f: { with import ../lib/testing-python.nix { inherit system pkgs; }; -let testConfig = makeTest (if pkgs.lib.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f); -in testConfig.test # For nix-build - // testConfig # For all-tests.nix +makeTest (if pkgs.lib.isFunction f then f (args // { inherit pkgs; inherit (pkgs) lib; }) else f) diff --git a/nixos/tests/matrix/mjolnir.nix b/nixos/tests/matrix/mjolnir.nix index cb843e2e9e3e8..b1ac55d951cef 100644 --- a/nixos/tests/matrix/mjolnir.nix +++ b/nixos/tests/matrix/mjolnir.nix @@ -32,6 +32,7 @@ import ../make-test-python.nix ( name = "mjolnir"; meta = with pkgs.lib; { maintainers = teams.matrix.members; + broken = true; # times out after spending many hours }; nodes = { diff --git a/nixos/tests/nscd.nix b/nixos/tests/nscd.nix new file mode 100644 index 0000000000000..7bb6d90c3d4e0 --- /dev/null +++ b/nixos/tests/nscd.nix @@ -0,0 +1,107 @@ +import ./make-test-python.nix ({ pkgs, ... }: +let + # build a getent that itself doesn't see anything in /etc/hosts and + # /etc/nsswitch.conf, by using libredirect to steer its own requests to + # /dev/null. + # This means is /has/ to go via nscd to actuallly resolve any of the + # additionally configured hosts. + getent' = pkgs.writeScript "getent-without-etc-hosts" '' + export NIX_REDIRECTS=/etc/hosts=/dev/null:/etc/nsswitch.conf=/dev/null + export LD_PRELOAD=${pkgs.libredirect}/lib/libredirect.so + exec getent $@ + ''; +in +{ + name = "nscd"; + + nodes.machine = { pkgs, ... }: { + imports = [ common/user-account.nix ]; + networking.extraHosts = '' + 2001:db8::1 somehost.test + 192.0.2.1 somehost.test + ''; + + specialisation = { + withUnscd.configuration = { ... }: { + services.nscd.package = pkgs.unscd; + }; + }; + }; + + testScript = { nodes, ... }: + let + specialisations = "${nodes.machine.system.build.toplevel}/specialisation"; + in + '' + # Regression test for https://github.com/NixOS/nixpkgs/issues/50273 + def test_dynamic_user(): + with subtest("DynamicUser actually allocates a user"): + assert "iamatest" in machine.succeed( + "systemd-run --pty --property=Type=oneshot --property=DynamicUser=yes --property=User=iamatest whoami" + ) + + # Test resolution of somehost.test with getent', to make sure we go via nscd + def test_host_lookups(): + with subtest("host lookups via nscd"): + # ahosts + output = machine.succeed("${getent'} ahosts somehost.test") + assert "192.0.2.1" in output + assert "2001:db8::1" in output + + # ahostsv4 + output = machine.succeed("${getent'} ahostsv4 somehost.test") + assert "192.0.2.1" in output + assert "2001:db8::1" not in output + + # ahostsv6 + output = machine.succeed("${getent'} ahostsv6 somehost.test") + assert "192.0.2.1" not in output + assert "2001:db8::1" in output + + # reverse lookups (hosts) + assert "somehost.test" in machine.succeed("${getent'} hosts 2001:db8::1") + assert "somehost.test" in machine.succeed("${getent'} hosts 192.0.2.1") + + # Test host resolution via nss modules works + # We rely on nss-myhostname in this case, which resolves *.localhost and + # _gateway. + # We don't need to use getent' here, as non-glibc nss modules can only be + # discovered via nscd. + def test_nss_myhostname(): + with subtest("nss-myhostname provides hostnames (ahosts)"): + # ahosts + output = machine.succeed("getent ahosts foobar.localhost") + assert "::1" in output + assert "127.0.0.1" in output + + # ahostsv4 + output = machine.succeed("getent ahostsv4 foobar.localhost") + assert "::1" not in output + assert "127.0.0.1" in output + + # ahostsv6 + output = machine.succeed("getent ahostsv6 foobar.localhost") + assert "::1" in output + assert "127.0.0.1" not in output + + start_all() + machine.wait_for_unit("default.target") + + # Test all tests with glibc-nscd. + test_dynamic_user() + test_host_lookups() + test_nss_myhostname() + + with subtest("unscd"): + machine.succeed('${specialisations}/withUnscd/bin/switch-to-configuration test') + machine.wait_for_unit("default.target") + + # known to fail, unscd doesn't load external NSS modules + # test_dynamic_user() + + test_host_lookups() + + # known to fail, unscd doesn't load external NSS modules + # test_nss_myhostname() + ''; +}) diff --git a/nixos/tests/oci-containers.nix b/nixos/tests/oci-containers.nix index 68077e3540a5e..1bcfb276dbeea 100644 --- a/nixos/tests/oci-containers.nix +++ b/nixos/tests/oci-containers.nix @@ -12,7 +12,7 @@ let name = "oci-containers-${backend}"; meta = { - maintainers = with lib.maintainers; [ adisbladis benley ] ++ lib.teams.serokell.members; + maintainers = with lib.maintainers; [ adisbladis benley mkaito ] ++ lib.teams.serokell.members; }; nodes = { diff --git a/nixos/tests/plasma-bigscreen.nix b/nixos/tests/plasma-bigscreen.nix new file mode 100644 index 0000000000000..1c61cafcbff33 --- /dev/null +++ b/nixos/tests/plasma-bigscreen.nix @@ -0,0 +1,38 @@ +import ./make-test-python.nix ({ pkgs, ...} : + +{ + name = "plasma-bigscreen"; + meta = with pkgs.lib.maintainers; { + maintainers = [ ttuegel k900 ]; + }; + + nodes.machine = { ... }: + + { + imports = [ ./common/user-account.nix ]; + services.xserver.enable = true; + services.xserver.displayManager.sddm.enable = true; + services.xserver.displayManager.defaultSession = "plasma-bigscreen-x11"; + services.xserver.desktopManager.plasma5.bigscreen.enable = true; + services.xserver.displayManager.autoLogin = { + enable = true; + user = "alice"; + }; + + users.users.alice.extraGroups = ["uinput"]; + }; + + testScript = { nodes, ... }: let + user = nodes.machine.users.users.alice; + xdo = "${pkgs.xdotool}/bin/xdotool"; + in '' + with subtest("Wait for login"): + start_all() + machine.wait_for_file("${user.home}/.Xauthority") + machine.succeed("xauth merge ${user.home}/.Xauthority") + + with subtest("Check plasmashell started"): + machine.wait_until_succeeds("pgrep plasmashell") + machine.wait_for_window("Plasma Big Screen") + ''; +}) diff --git a/nixos/tests/please.nix b/nixos/tests/please.nix new file mode 100644 index 0000000000000..2437cfe16130f --- /dev/null +++ b/nixos/tests/please.nix @@ -0,0 +1,66 @@ +import ./make-test-python.nix ({ lib, ... }: +{ + name = "please"; + meta.maintainers = with lib.maintainers; [ azahi ]; + + nodes.machine = + { ... }: + { + users.users = with lib; mkMerge [ + (listToAttrs (map + (n: nameValuePair n { isNormalUser = true; }) + (genList (x: "user${toString x}") 6))) + { + user0.extraGroups = [ "wheel" ]; + } + ]; + + security.please = { + enable = true; + wheelNeedsPassword = false; + settings = { + user2_run_true_as_root = { + name = "user2"; + target = "root"; + rule = "/run/current-system/sw/bin/true"; + require_pass = false; + }; + user4_edit_etc_hosts_as_root = { + name = "user4"; + type = "edit"; + target = "root"; + rule = "/etc/hosts"; + editmode = 644; + require_pass = false; + }; + }; + }; + }; + + testScript = '' + with subtest("root: can run anything by default"): + machine.succeed('please true') + with subtest("root: can edit anything by default"): + machine.succeed('EDITOR=cat pleaseedit /etc/hosts') + + with subtest("user0: can run as root because it's in the wheel group"): + machine.succeed('su - user0 -c "please -u root true"') + with subtest("user1: cannot run as root because it's not in the wheel group"): + machine.fail('su - user1 -c "please -u root true"') + + with subtest("user0: can edit as root"): + machine.succeed('su - user0 -c "EDITOR=cat pleaseedit /etc/hosts"') + with subtest("user1: cannot edit as root"): + machine.fail('su - user1 -c "EDITOR=cat pleaseedit /etc/hosts"') + + with subtest("user2: can run 'true' as root"): + machine.succeed('su - user2 -c "please -u root true"') + with subtest("user3: cannot run 'true' as root"): + machine.fail('su - user3 -c "please -u root true"') + + with subtest("user4: can edit /etc/hosts"): + machine.succeed('su - user4 -c "EDITOR=cat pleaseedit /etc/hosts"') + with subtest("user5: cannot edit /etc/hosts"): + machine.fail('su - user5 -c "EDITOR=cat pleaseedit /etc/hosts"') + ''; +}) diff --git a/nixos/tests/printing.nix b/nixos/tests/printing.nix index 6338fd8d8ac10..cfebe232d92a0 100644 --- a/nixos/tests/printing.nix +++ b/nixos/tests/printing.nix @@ -4,6 +4,7 @@ import ./make-test-python.nix ({pkgs, ... }: let printingServer = startWhenNeeded: { services.printing.enable = true; + services.printing.stateless = true; services.printing.startWhenNeeded = startWhenNeeded; services.printing.listenAddresses = [ "*:631" ]; services.printing.defaultShared = true; diff --git a/nixos/tests/resolv.nix b/nixos/tests/resolv.nix deleted file mode 100644 index f0aa7e42aaf35..0000000000000 --- a/nixos/tests/resolv.nix +++ /dev/null @@ -1,46 +0,0 @@ -# Test whether DNS resolving returns multiple records and all address families. -import ./make-test-python.nix ({ pkgs, ... } : { - name = "resolv"; - meta = with pkgs.lib.maintainers; { - maintainers = [ ckauhaus ]; - }; - - nodes.resolv = { ... }: { - networking.extraHosts = '' - # IPv4 only - 192.0.2.1 host-ipv4.example.net - 192.0.2.2 host-ipv4.example.net - # IP6 only - 2001:db8::2:1 host-ipv6.example.net - 2001:db8::2:2 host-ipv6.example.net - # dual stack - 192.0.2.1 host-dual.example.net - 192.0.2.2 host-dual.example.net - 2001:db8::2:1 host-dual.example.net - 2001:db8::2:2 host-dual.example.net - ''; - }; - - testScript = '' - def addrs_in(hostname, addrs): - res = resolv.succeed("getent ahosts {}".format(hostname)) - for addr in addrs: - assert addr in res, "Expected output '{}' not found in\n{}".format(addr, res) - - - start_all() - resolv.wait_for_unit("nscd") - - ipv4 = ["192.0.2.1", "192.0.2.2"] - ipv6 = ["2001:db8::2:1", "2001:db8::2:2"] - - with subtest("IPv4 resolves"): - addrs_in("host-ipv4.example.net", ipv4) - - with subtest("IPv6 resolves"): - addrs_in("host-ipv6.example.net", ipv6) - - with subtest("Dual stack resolves"): - addrs_in("host-dual.example.net", ipv4 + ipv6) - ''; -}) diff --git a/nixos/tests/restic.nix b/nixos/tests/restic.nix index 75fffe9d9a84d..16dd5f8c5c8a3 100644 --- a/nixos/tests/restic.nix +++ b/nixos/tests/restic.nix @@ -68,6 +68,9 @@ import ./make-test-python.nix ( package = pkgs.writeShellScriptBin "restic" '' echo "$@" >> /tmp/fake-restic.log; ''; + + pruneOpts = [ "--keep-last 1" ]; + checkOpts = [ "--some-check-option" ]; }; }; @@ -98,6 +101,7 @@ import ./make-test-python.nix ( '${pkgs.restic}/bin/restic -r ${rcloneRepository} -p ${passwordFile} snapshots -c | grep -e "^1 snapshot"', "systemctl start restic-backups-custompackage.service", "grep 'backup .* /opt' /tmp/fake-restic.log", + "grep 'check .* --some-check-option' /tmp/fake-restic.log", "timedatectl set-time '2017-12-13 13:45'", "systemctl start restic-backups-remotebackup.service", "rm /opt/backupCleanupCommand", diff --git a/nixos/tests/stratis/default.nix b/nixos/tests/stratis/default.nix index 6964852e30a09..42daadd5fcaac 100644 --- a/nixos/tests/stratis/default.nix +++ b/nixos/tests/stratis/default.nix @@ -4,4 +4,5 @@ { simple = import ./simple.nix { inherit system pkgs; }; + encryption = import ./encryption.nix { inherit system pkgs; }; } diff --git a/nixos/tests/stratis/encryption.nix b/nixos/tests/stratis/encryption.nix new file mode 100644 index 0000000000000..3faa3171843f7 --- /dev/null +++ b/nixos/tests/stratis/encryption.nix @@ -0,0 +1,33 @@ +import ../make-test-python.nix ({ pkgs, ... }: + { + name = "stratis"; + + meta = with pkgs.lib.maintainers; { + maintainers = [ nickcao ]; + }; + + nodes.machine = { pkgs, ... }: { + services.stratis.enable = true; + virtualisation.emptyDiskImages = [ 2048 ]; + }; + + testScript = + let + testkey1 = pkgs.writeText "testkey1" "supersecret1"; + testkey2 = pkgs.writeText "testkey2" "supersecret2"; + in + '' + machine.wait_for_unit("stratisd") + # test creation of encrypted pool and filesystem + machine.succeed("stratis key set testkey1 --keyfile-path ${testkey1}") + machine.succeed("stratis key set testkey2 --keyfile-path ${testkey2}") + machine.succeed("stratis pool create testpool /dev/vdb --key-desc testkey1") + machine.succeed("stratis fs create testpool testfs") + # test rebinding encrypted pool + machine.succeed("stratis pool rebind keyring testpool testkey2") + # test restarting encrypted pool + uuid = machine.succeed("stratis pool list | grep -oE '[0-9a-fA-F-]{36}'").rstrip('\n') + machine.succeed(" stratis pool stop testpool") + machine.succeed(f"stratis pool start {uuid} --unlock-method keyring") + ''; + }) diff --git a/nixos/tests/systemd-cryptenroll.nix b/nixos/tests/systemd-cryptenroll.nix index 055ae7d1681f2..9ee2d280fbbea 100644 --- a/nixos/tests/systemd-cryptenroll.nix +++ b/nixos/tests/systemd-cryptenroll.nix @@ -2,6 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }: { name = "systemd-cryptenroll"; meta = with pkgs.lib.maintainers; { maintainers = [ ymatsiuk ]; + broken = true; # times out after two hours, details -> https://github.com/NixOS/nixpkgs/issues/167994 }; nodes.machine = { pkgs, lib, ... }: { diff --git a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix index 37a89fc21e442..279b9aac8edb6 100644 --- a/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix +++ b/nixos/tests/systemd-networkd-ipv6-prefix-delegation.nix @@ -7,10 +7,10 @@ # - VLAN 1 is the connection between the ISP and the router # - VLAN 2 is the connection between the router and the client -import ./make-test-python.nix ({pkgs, ...}: { +import ./make-test-python.nix ({ pkgs, lib, ... }: { name = "systemd-networkd-ipv6-prefix-delegation"; - meta = with pkgs.lib.maintainers; { - maintainers = [ andir ]; + meta = with lib.maintainers; { + maintainers = [ andir hexa ]; }; nodes = { @@ -22,26 +22,38 @@ import ./make-test-python.nix ({pkgs, ...}: { # # Note: On the ISPs device we don't really care if we are using networkd in # this example. That being said we can't use it (yet) as networkd doesn't - # implement the serving side of DHCPv6. We will use ISC's well aged dhcpd6 - # for that task. + # implement the serving side of DHCPv6. We will use ISC Kea for that task. isp = { lib, pkgs, ... }: { virtualisation.vlans = [ 1 ]; networking = { useDHCP = false; firewall.enable = false; - interfaces.eth1.ipv4.addresses = lib.mkForce []; # no need for legacy IP - interfaces.eth1.ipv6.addresses = lib.mkForce [ - { address = "2001:DB8::1"; prefixLength = 64; } - ]; + interfaces.eth1 = lib.mkForce {}; # Don't use scripted networking + }; + + systemd.network = { + enable = true; + + networks = { + "eth1" = { + matchConfig.Name = "eth1"; + address = [ + "2001:DB8::1/64" + ]; + networkConfig.IPForward = true; + }; + }; }; # Since we want to program the routes that we delegate to the "customer" - # into our routing table we must give dhcpd the required privs. - systemd.services.dhcpd6.serviceConfig.AmbientCapabilities = - [ "CAP_NET_ADMIN" ]; + # into our routing table we must provide kea with the required capability. + systemd.services.kea-dhcp6-server.serviceConfig = { + AmbientCapabilities = [ "CAP_NET_ADMIN" ]; + CapabilityBoundingSet = [ "CAP_NET_ADMIN" ]; + }; services = { - # Configure the DHCPv6 server + # Configure the DHCPv6 server to hand out both IA_NA and IA_PD. # # We will hand out /48 prefixes from the subnet 2001:DB8:F000::/36. # That gives us ~8k prefixes. That should be enough for this test. @@ -49,31 +61,70 @@ import ./make-test-python.nix ({pkgs, ...}: { # Since (usually) you will not receive a prefix with the router # advertisements we also hand out /128 leases from the range # 2001:DB8:0000:0000:FFFF::/112. - dhcpd6 = { + kea.dhcp6 = { enable = true; - interfaces = [ "eth1" ]; - extraConfig = '' - subnet6 2001:DB8::/36 { - range6 2001:DB8:0000:0000:FFFF:: 2001:DB8:0000:0000:FFFF::FFFF; - prefix6 2001:DB8:F000:: 2001:DB8:FFFF:: /48; - } - - # This is the secret sauce. We have to extract the prefix and the - # next hop when commiting the lease to the database. dhcpd6 - # (rightfully) has not concept of adding routes to the systems - # routing table. It really depends on the setup. + settings = { + interfaces-config.interfaces = [ "eth1" ]; + subnet6 = [ { + interface = "eth1"; + subnet = "2001:DB8:F::/36"; + pd-pools = [ { + prefix = "2001:DB8:F::"; + prefix-len = 36; + delegated-len = 48; + } ]; + pools = [ { + pool = "2001:DB8:0000:0000:FFFF::-2001:DB8:0000:0000:FFFF::FFFF"; + } ]; + } ]; + + # This is the glue between Kea and the Kernel FIB. DHCPv6 + # rightfully has no concept of setting up a route in your + # FIB. This step really depends on your setup. # - # In a production environment your DHCPv6 server is likely not the - # router. You might want to consider BGP, custom NetConf calls, … - # in those cases. - on commit { - set IP = pick-first-value(binary-to-ascii(16, 16, ":", substring(option dhcp6.ia-na, 16, 16)), "n/a"); - set Prefix = pick-first-value(binary-to-ascii(16, 16, ":", suffix(option dhcp6.ia-pd, 16)), "n/a"); - set PrefixLength = pick-first-value(binary-to-ascii(10, 8, ":", substring(suffix(option dhcp6.ia-pd, 17), 0, 1)), "n/a"); - log(concat(IP, " ", Prefix, " ", PrefixLength)); - execute("${pkgs.iproute2}/bin/ip", "-6", "route", "replace", concat(Prefix,"/",PrefixLength), "via", IP); - } - ''; + # In a production environment your DHCPv6 server is likely + # not the router. You might want to consider BGP, NETCONF + # calls, … in those cases. + # + # In this example we use the run script hook, that lets use + # execute anything and passes information via the environment. + # https://kea.readthedocs.io/en/kea-2.2.0/arm/hooks.html#run-script-run-script-support-for-external-hook-scripts + hooks-libraries = [ { + library = "${pkgs.kea}/lib/kea/hooks/libdhcp_run_script.so"; + parameters = { + name = pkgs.writeShellScript "kea-run-hooks" '' + export PATH="${lib.makeBinPath (with pkgs; [ coreutils iproute2 ])}" + + set -euxo pipefail + + leases6_committed() { + for i in $(seq $LEASES6_SIZE); do + idx=$((i-1)) + prefix_var="LEASES6_AT''${idx}_ADDRESS" + plen_var="LEASES6_AT''${idx}_PREFIX_LEN" + + ip -6 route replace ''${!prefix_var}/''${!plen_var} via $QUERY6_REMOTE_ADDR dev $QUERY6_IFACE_NAME + done + } + + unknown_handler() { + echo "Unhandled function call ''${*}" + exit 123 + } + + case "$1" in + "leases6_committed") + leases6_committed + ;; + *) + unknown_handler "''${@}" + ;; + esac + ''; + sync = false; + }; + } ]; + }; }; # Finally we have to set up the router advertisements. While we could be @@ -176,7 +227,7 @@ import ./make-test-python.nix ({pkgs, ...}: { IPv6AcceptRA = false; # Delegate prefixes from the DHCPv6 PD pool. - DHCPv6PrefixDelegation = true; + DHCPPrefixDelegation = true; IPv6SendRA = true; }; diff --git a/nixos/tests/systemd.nix b/nixos/tests/systemd.nix index 3317823e03f76..3c36291b733d2 100644 --- a/nixos/tests/systemd.nix +++ b/nixos/tests/systemd.nix @@ -87,12 +87,6 @@ import ./make-test-python.nix ({ pkgs, ... }: { machine.succeed("test -e /home/alice/user_conf_read") machine.succeed("test -z $(ls -1 /var/log/journal)") - # Regression test for https://github.com/NixOS/nixpkgs/issues/50273 - with subtest("DynamicUser actually allocates a user"): - assert "iamatest" in machine.succeed( - "systemd-run --pty --property=Type=oneshot --property=DynamicUser=yes --property=User=iamatest whoami" - ) - with subtest("regression test for https://bugs.freedesktop.org/show_bug.cgi?id=77507"): retcode, output = machine.execute("systemctl status testservice1.service") assert retcode in [0, 3] # https://bugs.freedesktop.org/show_bug.cgi?id=77507 diff --git a/nixos/tests/terminal-emulators.nix b/nixos/tests/terminal-emulators.nix index c724608b91554..4269d05056d8c 100644 --- a/nixos/tests/terminal-emulators.nix +++ b/nixos/tests/terminal-emulators.nix @@ -23,8 +23,9 @@ with pkgs.lib; let tests = { alacritty.pkg = p: p.alacritty; - contour.pkg = p: p.contour; - contour.cmd = "contour $command"; + # times out after spending many hours + #contour.pkg = p: p.contour; + #contour.cmd = "contour $command"; cool-retro-term.pkg = p: p.cool-retro-term; cool-retro-term.colourTest = false; # broken by gloss effect @@ -103,7 +104,8 @@ let tests = { wayst.pkg = p: p.wayst; wayst.pinkValue = "#FF0066"; - wezterm.pkg = p: p.wezterm; + # times out after spending many hours + #wezterm.pkg = p: p.wezterm; xfce4-terminal.pkg = p: p.xfce.xfce4-terminal; diff --git a/nixos/tests/vscodium.nix b/nixos/tests/vscodium.nix index 3bdb99947a40b..ee884cc4295dd 100644 --- a/nixos/tests/vscodium.nix +++ b/nixos/tests/vscodium.nix @@ -70,15 +70,15 @@ let # Save the file machine.send_key('ctrl-s') - machine.wait_for_text('Save') + machine.wait_for_text('(Save|Desktop|alice|Size)') machine.screenshot('save_window') machine.send_key('ret') # (the default filename is the first line of the file) machine.wait_for_file(f'/home/alice/{test_string}') - machine.send_key('ctrl-q') - machine.wait_until_fails('pgrep -x codium') + # machine.send_key('ctrl-q') + # machine.wait_until_fails('pgrep -x codium') ''; }); diff --git a/nixos/tests/wine.nix b/nixos/tests/wine.nix index 8a64c3179c518..7cbe7ac94f1e7 100644 --- a/nixos/tests/wine.nix +++ b/nixos/tests/wine.nix @@ -44,5 +44,8 @@ in listToAttrs ( map (makeWineTest "winePackages" [ hello32 ]) variants ++ optionals pkgs.stdenv.is64bit - (map (makeWineTest "wineWowPackages" [ hello32 hello64 ]) variants) + (map (makeWineTest "wineWowPackages" [ hello32 hello64 ]) + # This wayland combination times out after spending many hours. + # https://hydra.nixos.org/job/nixos/trunk-combined/nixos.tests.wine.wineWowPackages-wayland.x86_64-linux + (pkgs.lib.remove "wayland" variants)) ) |