diff options
Diffstat (limited to 'nixos')
62 files changed, 488 insertions, 257 deletions
diff --git a/nixos/doc/manual/development/option-declarations.section.md b/nixos/doc/manual/development/option-declarations.section.md index f89aae5730682..aa747f47c9c81 100644 --- a/nixos/doc/manual/development/option-declarations.section.md +++ b/nixos/doc/manual/development/option-declarations.section.md @@ -88,7 +88,7 @@ lib.mkOption { } ``` -### `mkPackageOption` {#sec-option-declarations-util-mkPackageOption} +### `mkPackageOption`, `mkPackageOptionMD` {#sec-option-declarations-util-mkPackageOption} Usage: @@ -106,6 +106,8 @@ The second argument is the name of the option, used in the description "The \<na You can omit the default path if the name of the option is also attribute path in nixpkgs. +During the transition to CommonMark documentation `mkPackageOption` creates an option with a DocBook description attribute, once the transition is completed it will create a CommonMark description instead. `mkPackageOptionMD` always creates an option with a CommonMark description attribute and will be removed some time after the transition is completed. + ::: {#ex-options-declarations-util-mkPackageOption .title} Examples: diff --git a/nixos/doc/manual/from_md/development/option-declarations.section.xml b/nixos/doc/manual/from_md/development/option-declarations.section.xml index 2e6a12d530953..cc4893939c280 100644 --- a/nixos/doc/manual/from_md/development/option-declarations.section.xml +++ b/nixos/doc/manual/from_md/development/option-declarations.section.xml @@ -138,7 +138,8 @@ lib.mkOption { } </programlisting> <section xml:id="sec-option-declarations-util-mkPackageOption"> - <title><literal>mkPackageOption</literal></title> + <title><literal>mkPackageOption</literal>, + <literal>mkPackageOptionMD</literal></title> <para> Usage: </para> @@ -172,6 +173,15 @@ mkPackageOption pkgs "name" { default = [ "path" "in&qu You can omit the default path if the name of the option is also attribute path in nixpkgs. </para> + <para> + During the transition to CommonMark documentation + <literal>mkPackageOption</literal> creates an option with a + DocBook description attribute, once the transition is + completed it will create a CommonMark description instead. + <literal>mkPackageOptionMD</literal> always creates an option + with a CommonMark description attribute and will be removed + some time after the transition is completed. + </para> <anchor xml:id="ex-options-declarations-util-mkPackageOption" /> <para> Examples: diff --git a/nixos/doc/manual/from_md/installation/upgrading.chapter.xml b/nixos/doc/manual/from_md/installation/upgrading.chapter.xml index 9f4cfaf36b628..99882784b46fc 100644 --- a/nixos/doc/manual/from_md/installation/upgrading.chapter.xml +++ b/nixos/doc/manual/from_md/installation/upgrading.chapter.xml @@ -12,7 +12,7 @@ <listitem> <para> <emphasis>Stable channels</emphasis>, such as - <link xlink:href="https://nixos.org/channels/nixos-22.05"><literal>nixos-22.11</literal></link>. + <link xlink:href="https://nixos.org/channels/nixos-22.11"><literal>nixos-22.11</literal></link>. These only get conservative bug fixes and package upgrades. For instance, a channel update may cause the Linux kernel on your system to be upgraded from 4.19.34 to 4.19.38 (a minor bug fix), @@ -33,7 +33,7 @@ <listitem> <para> <emphasis>Small channels</emphasis>, such as - <link xlink:href="https://nixos.org/channels/nixos-22.05-small"><literal>nixos-22.11-small</literal></link> + <link xlink:href="https://nixos.org/channels/nixos-22.11-small"><literal>nixos-22.11-small</literal></link> or <link xlink:href="https://nixos.org/channels/nixos-unstable-small"><literal>nixos-unstable-small</literal></link>. These are identical to the stable and unstable channels diff --git a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml index ea3be31a20606..12e4d490300ec 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2305.section.xml @@ -117,6 +117,15 @@ </listitem> <listitem> <para> + <literal>podman</literal> now uses the + <literal>netavark</literal> network stack. Users will need to + delete all of their local containers, images, volumes, etc, by + running <literal>podman system reset --force</literal> once + before upgrading their systems. + </para> + </listitem> + <listitem> + <para> The EC2 image module no longer fetches instance metadata in stage-1. This results in a significantly smaller initramfs, since network drivers no longer need to be included, and @@ -341,6 +350,13 @@ </listitem> <listitem> <para> + <literal>services.chronyd</literal> is now started with + additional systemd sandbox/hardening options for better + security. + </para> + </listitem> + <listitem> + <para> The module <literal>services.headscale</literal> was refactored to be compliant with <link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC diff --git a/nixos/doc/manual/installation/upgrading.chapter.md b/nixos/doc/manual/installation/upgrading.chapter.md index 249bcd97cec84..26b6b8cc23ef1 100644 --- a/nixos/doc/manual/installation/upgrading.chapter.md +++ b/nixos/doc/manual/installation/upgrading.chapter.md @@ -6,7 +6,7 @@ expressions and associated binaries. The NixOS channels are updated automatically from NixOS's Git repository after certain tests have passed and all packages have been built. These channels are: -- *Stable channels*, such as [`nixos-22.11`](https://nixos.org/channels/nixos-22.05). +- *Stable channels*, such as [`nixos-22.11`](https://nixos.org/channels/nixos-22.11). These only get conservative bug fixes and package upgrades. For instance, a channel update may cause the Linux kernel on your system to be upgraded from 4.19.34 to 4.19.38 (a minor bug fix), but not @@ -19,7 +19,7 @@ passed and all packages have been built. These channels are: radical changes between channel updates. It's not recommended for production systems. -- *Small channels*, such as [`nixos-22.11-small`](https://nixos.org/channels/nixos-22.05-small) +- *Small channels*, such as [`nixos-22.11-small`](https://nixos.org/channels/nixos-22.11-small) or [`nixos-unstable-small`](https://nixos.org/channels/nixos-unstable-small). These are identical to the stable and unstable channels described above, except that they contain fewer binary packages. This means they get updated diff --git a/nixos/doc/manual/release-notes/rl-2305.section.md b/nixos/doc/manual/release-notes/rl-2305.section.md index df0ec622e56e7..07ee346c2c872 100644 --- a/nixos/doc/manual/release-notes/rl-2305.section.md +++ b/nixos/doc/manual/release-notes/rl-2305.section.md @@ -40,6 +40,8 @@ In addition to numerous new and upgraded packages, this release has the followin - `borgbackup` module now has an option for inhibiting system sleep while backups are running, defaulting to off (not inhibiting sleep), available as [`services.borgbackup.jobs.<name>.inhibitsSleep`](#opt-services.borgbackup.jobs._name_.inhibitsSleep). +- `podman` now uses the `netavark` network stack. Users will need to delete all of their local containers, images, volumes, etc, by running `podman system reset --force` once before upgrading their systems. + - The EC2 image module no longer fetches instance metadata in stage-1. This results in a significantly smaller initramfs, since network drivers no longer need to be included, and faster boots, since metadata fetching can happen in parallel with startup of other services. This breaks services which rely on metadata being present by the time stage-2 is entered. Anything which reads EC2 metadata from `/etc/ec2-metadata` should now have an `after` dependency on `fetch-ec2-metadata.service` @@ -94,6 +96,8 @@ In addition to numerous new and upgraded packages, this release has the followin And backup your data. +- `services.chronyd` is now started with additional systemd sandbox/hardening options for better security. + - The module `services.headscale` was refactored to be compliant with [RFC 0042](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md). To be precise, this means that the following things have changed: - Most settings has been migrated under [services.headscale.settings](#opt-services.headscale.settings) which is an attribute-set that diff --git a/nixos/lib/make-options-doc/mergeJSON.py b/nixos/lib/make-options-doc/mergeJSON.py index 750cd24fc653d..7b14af40c313b 100644 --- a/nixos/lib/make-options-doc/mergeJSON.py +++ b/nixos/lib/make-options-doc/mergeJSON.py @@ -306,14 +306,17 @@ if hasDocBookErrors: print("Explanation: The documentation contains descriptions, examples, or defaults written in DocBook. " + "NixOS is in the process of migrating from DocBook to Markdown, and " + "DocBook is disallowed for in-tree modules. To change your contribution to "+ - "use Markdown, apply mdDoc and literalMD. For example:\n" + + "use Markdown, apply mdDoc and literalMD and use the *MD variants of option creation " + + "functions where they are available. For example:\n" + "\n" + " example.foo = mkOption {\n" + " description = lib.mdDoc ''your description'';\n" + " defaultText = lib.literalMD ''your description of default'';\n" + - " }\n" + + " };\n" + "\n" + - " example.enable = mkEnableOption (lib.mdDoc ''your thing'');", + " example.enable = mkEnableOption (lib.mdDoc ''your thing'');\n" + + " example.package = mkPackageOptionMD pkgs \"your-package\" {};\n" + + " imports = [ (mkAliasOptionModuleMD [ \"example\" \"args\" ] [ \"example\" \"settings\" ]) ];", file = sys.stderr) if hasErrors: diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix index 19319b9309cd1..76092e738ebd4 100644 --- a/nixos/modules/config/users-groups.nix +++ b/nixos/modules/config/users-groups.nix @@ -444,8 +444,8 @@ let in { imports = [ - (mkAliasOptionModule [ "users" "extraUsers" ] [ "users" "users" ]) - (mkAliasOptionModule [ "users" "extraGroups" ] [ "users" "groups" ]) + (mkAliasOptionModuleMD [ "users" "extraUsers" ] [ "users" "users" ]) + (mkAliasOptionModuleMD [ "users" "extraGroups" ] [ "users" "groups" ]) (mkRenamedOptionModule ["security" "initialRootPassword"] ["users" "users" "root" "initialHashedPassword"]) ]; diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix index 64a8f7846b463..e44a9899772f1 100644 --- a/nixos/modules/misc/documentation.nix +++ b/nixos/modules/misc/documentation.nix @@ -50,7 +50,7 @@ let (name: value: let wholeName = "${namePrefix}.${name}"; - guard = lib.warn "Attempt to evaluate package ${wholeName} in option documentation; this is not supported and will eventually be an error. Use `mkPackageOption` or `literalExpression` instead."; + guard = lib.warn "Attempt to evaluate package ${wholeName} in option documentation; this is not supported and will eventually be an error. Use `mkPackageOption{,MD}` or `literalExpression` instead."; in if isAttrs value then scrubDerivations wholeName value // optionalAttrs (isDerivation value) { diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix index 1067b21a22b07..c9e06382b7ac2 100644 --- a/nixos/modules/misc/version.nix +++ b/nixos/modules/misc/version.nix @@ -28,6 +28,8 @@ let DOCUMENTATION_URL = "https://nixos.org/learn.html"; SUPPORT_URL = "https://nixos.org/community.html"; BUG_REPORT_URL = "https://github.com/NixOS/nixpkgs/issues"; + } // lib.optionalAttrs (cfg.variant_id != null) { + VARIANT_ID = cfg.variant_id; }; initrdReleaseContents = osReleaseContents // { @@ -87,6 +89,13 @@ in description = lib.mdDoc "The NixOS release code name (e.g. `Emu`)."; }; + nixos.variant_id = mkOption { + type = types.nullOr (types.strMatching "^[a-z0-9._-]+$"); + default = null; + description = lib.mdDoc "A lower-case string identifying a specific variant or edition of the operating system"; + example = "installer"; + }; + stateVersion = mkOption { type = types.str; # TODO Remove this and drop the default of the option so people are forced to set it. diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 41b953dc34733..b2e80b10fc243 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -179,6 +179,7 @@ ./programs/haguichi.nix ./programs/hamster.nix ./programs/htop.nix + ./programs/iay.nix ./programs/iftop.nix ./programs/i3lock.nix ./programs/iotop.nix diff --git a/nixos/modules/profiles/installation-device.nix b/nixos/modules/profiles/installation-device.nix index ae9be08c8d859..4d9bd69666c09 100644 --- a/nixos/modules/profiles/installation-device.nix +++ b/nixos/modules/profiles/installation-device.nix @@ -20,6 +20,7 @@ with lib; ]; config = { + system.nixos.variant_id = lib.mkDefault "installer"; # Enable in installer, even if the minimal profile disables it. documentation.enable = mkImageMediaOverride true; diff --git a/nixos/modules/profiles/macos-builder.nix b/nixos/modules/profiles/macos-builder.nix index fddf19ad12517..4a5359582bce0 100644 --- a/nixos/modules/profiles/macos-builder.nix +++ b/nixos/modules/profiles/macos-builder.nix @@ -59,10 +59,14 @@ in trusted-users = [ "root" user ]; }; - services.openssh = { - enable = true; + services = { + getty.autologinUser = user; - authorizedKeysFiles = [ "${keysDirectory}/%u_${keyType}.pub" ]; + openssh = { + enable = true; + + authorizedKeysFiles = [ "${keysDirectory}/%u_${keyType}.pub" ]; + }; }; system.build.macos-builder-installer = diff --git a/nixos/modules/programs/_1password-gui.nix b/nixos/modules/programs/_1password-gui.nix index 83ef6037fb5a3..27c0d34a2eedf 100644 --- a/nixos/modules/programs/_1password-gui.nix +++ b/nixos/modules/programs/_1password-gui.nix @@ -27,7 +27,7 @@ in ''; }; - package = mkPackageOption pkgs "1Password GUI" { + package = mkPackageOptionMD pkgs "1Password GUI" { default = [ "_1password-gui" ]; }; }; diff --git a/nixos/modules/programs/_1password.nix b/nixos/modules/programs/_1password.nix index 91246150755d5..8537484c7e67d 100644 --- a/nixos/modules/programs/_1password.nix +++ b/nixos/modules/programs/_1password.nix @@ -18,7 +18,7 @@ in programs._1password = { enable = mkEnableOption (lib.mdDoc "the 1Password CLI tool"); - package = mkPackageOption pkgs "1Password CLI" { + package = mkPackageOptionMD pkgs "1Password CLI" { default = [ "_1password" ]; }; }; diff --git a/nixos/modules/programs/flashrom.nix b/nixos/modules/programs/flashrom.nix index ff495558c9e04..294b208a37208 100644 --- a/nixos/modules/programs/flashrom.nix +++ b/nixos/modules/programs/flashrom.nix @@ -16,7 +16,7 @@ in group. ''; }; - package = mkPackageOption pkgs "flashrom" { }; + package = mkPackageOptionMD pkgs "flashrom" { }; }; config = mkIf cfg.enable { diff --git a/nixos/modules/programs/gnupg.nix b/nixos/modules/programs/gnupg.nix index 828f24f99111d..cb8d0ecff4cb8 100644 --- a/nixos/modules/programs/gnupg.nix +++ b/nixos/modules/programs/gnupg.nix @@ -135,7 +135,7 @@ in # The SSH agent protocol doesn't have support for changing TTYs; however we # can simulate this with the `exec` feature of openssh (see ssh_config(5)) # that hooks a command to the shell currently running the ssh program. - Match host * exec "${cfg.package}/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1" + Match host * exec "${pkgs.runtimeShell} -c '${cfg.package}/bin/gpg-connect-agent --quiet updatestartuptty /bye >/dev/null 2>&1'" ''; environment.extraInit = mkIf cfg.agent.enableSSHSupport '' diff --git a/nixos/modules/programs/iay.nix b/nixos/modules/programs/iay.nix new file mode 100644 index 0000000000000..1fa00e43795ad --- /dev/null +++ b/nixos/modules/programs/iay.nix @@ -0,0 +1,37 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.programs.iay; + inherit (lib) mkEnableOption mkIf mkOption mkPackageOption optionalString types; +in { + options.programs.iay = { + enable = mkEnableOption (lib.mdDoc "iay"); + package = mkPackageOption pkgs "iay" {}; + + minimalPrompt = mkOption { + type = types.bool; + default = false; + description = lib.mdDoc "Use minimal one-liner prompt."; + }; + }; + + config = mkIf cfg.enable { + programs.bash.promptInit = '' + if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then + PS1='$(iay ${optionalString cfg.minimalPrompt "-m"})' + fi + ''; + + programs.zsh.promptInit = '' + if [[ $TERM != "dumb" && (-z $INSIDE_EMACS || $INSIDE_EMACS == "vterm") ]]; then + autoload -Uz add-zsh-hook + _iay_prompt() { + PROMPT="$(iay -z ${optionalString cfg.minimalPrompt "-m"})" + } + add-zsh-hook precmd _iay_prompt + fi + ''; + }; + + meta.maintainers = pkgs.iay.meta.maintainers; +} diff --git a/nixos/modules/programs/nix-ld.nix b/nixos/modules/programs/nix-ld.nix index f753cf5f97e5b..9a12b4ca5c74f 100644 --- a/nixos/modules/programs/nix-ld.nix +++ b/nixos/modules/programs/nix-ld.nix @@ -36,23 +36,22 @@ let in { meta.maintainers = [ lib.maintainers.mic92 ]; - options = { - programs.nix-ld = { - enable = lib.mkEnableOption (lib.mdDoc ''nix-ld, Documentation: <https://github.com/Mic92/nix-ld>''); - package = lib.mkOption { - type = lib.types.package; - description = lib.mdDoc "Which package to use for the nix-ld."; - default = pkgs.nix-ld; - defaultText = lib.mdDoc "pkgs.nix-ld"; - }; - libraries = lib.mkOption { - type = lib.types.listOf lib.types.package; - description = lib.mdDoc "Libraries that automatically become available to all programs. The default set includes common libraries."; - default = baseLibraries; - defaultText = lib.mdDoc "baseLibraries"; - }; + options.programs.nix-ld = { + enable = lib.mkEnableOption (lib.mdDoc ''nix-ld, Documentation: <https://github.com/Mic92/nix-ld>''); + package = lib.mkOption { + type = lib.types.package; + description = lib.mdDoc "Which package to use for the nix-ld."; + default = pkgs.nix-ld; + defaultText = lib.literalExpression "pkgs.nix-ld"; + }; + libraries = lib.mkOption { + type = lib.types.listOf lib.types.package; + description = lib.mdDoc "Libraries that automatically become available to all programs. The default set includes common libraries."; + default = baseLibraries; + defaultText = lib.literalExpression "baseLibraries derived from systemd and nix dependencies."; }; }; + config = lib.mkIf config.programs.nix-ld.enable { systemd.tmpfiles.packages = [ cfg.package ]; diff --git a/nixos/modules/programs/skim.nix b/nixos/modules/programs/skim.nix index 57a5d68ec3d5a..8dadf322606e2 100644 --- a/nixos/modules/programs/skim.nix +++ b/nixos/modules/programs/skim.nix @@ -1,6 +1,6 @@ { pkgs, config, lib, ... }: let - inherit (lib) mdDoc mkEnableOption mkPackageOption optional optionalString; + inherit (lib) mdDoc mkEnableOption mkPackageOptionMD optional optionalString; cfg = config.programs.skim; in { @@ -8,7 +8,7 @@ in programs.skim = { fuzzyCompletion = mkEnableOption (mdDoc "fuzzy completion with skim"); keybindings = mkEnableOption (mdDoc "skim keybindings"); - package = mkPackageOption pkgs "skim" {}; + package = mkPackageOptionMD pkgs "skim" {}; }; }; diff --git a/nixos/modules/programs/streamdeck-ui.nix b/nixos/modules/programs/streamdeck-ui.nix index 113d1d49e151a..4c055029e39b9 100644 --- a/nixos/modules/programs/streamdeck-ui.nix +++ b/nixos/modules/programs/streamdeck-ui.nix @@ -15,7 +15,7 @@ in description = lib.mdDoc "Whether streamdeck-ui should be started automatically."; }; - package = mkPackageOption pkgs "streamdeck-ui" { + package = mkPackageOptionMD pkgs "streamdeck-ui" { default = [ "streamdeck-ui" ]; }; diff --git a/nixos/modules/rename.nix b/nixos/modules/rename.nix index aef42d0f4db10..d88baac7a5d4d 100644 --- a/nixos/modules/rename.nix +++ b/nixos/modules/rename.nix @@ -14,7 +14,7 @@ with lib; # This alias module can't be where _module.check is defined because it would # be added to submodules as well there - (mkAliasOptionModule [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ]) + (mkAliasOptionModuleMD [ "environment" "checkConfigurationOptions" ] [ "_module" "check" ]) # Completely removed modules (mkRemovedOptionModule [ "environment" "blcr" "enable" ] "The BLCR module has been removed") diff --git a/nixos/modules/services/continuous-integration/gitlab-runner.nix b/nixos/modules/services/continuous-integration/gitlab-runner.nix index 7b1c4da862606..d18c4cff04057 100644 --- a/nixos/modules/services/continuous-integration/gitlab-runner.nix +++ b/nixos/modules/services/continuous-integration/gitlab-runner.nix @@ -4,24 +4,41 @@ with lib; let cfg = config.services.gitlab-runner; hasDocker = config.virtualisation.docker.enable; + + /* The whole logic of this module is to diff the hashes of the desired vs existing runners + The hash is recorded in the runner's name because we can't do better yet + See https://gitlab.com/gitlab-org/gitlab-runner/-/issues/29350 for more details + */ + genRunnerName = service: let + hash = substring 0 12 (hashString "md5" (unsafeDiscardStringContext (toJSON service))); + in if service ? description + then "${hash} ${service.description}" + else "${name}_${config.networking.hostName}_${hash}"; + hashedServices = mapAttrs' - (name: service: nameValuePair - "${name}_${config.networking.hostName}_${ - substring 0 12 - (hashString "md5" (unsafeDiscardStringContext (toJSON service)))}" - service) - cfg.services; - configPath = "$HOME/.gitlab-runner/config.toml"; - configureScript = pkgs.writeShellScriptBin "gitlab-runner-configure" ( - if (cfg.configFile != null) then '' - mkdir -p $(dirname ${configPath}) + (name: service: nameValuePair (genRunnerName service) service) cfg.services; + configPath = ''"$HOME"/.gitlab-runner/config.toml''; + configureScript = pkgs.writeShellApplication { + name = "gitlab-runner-configure"; + runtimeInputs = with pkgs; [ + bash + gawk + jq + moreutils + remarshal + util-linux + cfg.package + perl + python3 + ]; + text = if (cfg.configFile != null) then '' cp ${cfg.configFile} ${configPath} # make config file readable by service chown -R --reference=$HOME $(dirname ${configPath}) '' else '' export CONFIG_FILE=${configPath} - mkdir -p $(dirname ${configPath}) + mkdir -p "$(dirname "${configPath}")" touch ${configPath} # update global options @@ -34,22 +51,43 @@ let # remove no longer existing services gitlab-runner verify --delete - # current and desired state - NEEDED_SERVICES=$(echo ${concatStringsSep " " (attrNames hashedServices)} | tr " " "\n") - REGISTERED_SERVICES=$(gitlab-runner list 2>&1 | grep 'Executor' | awk '{ print $1 }') + ${toShellVar "NEEDED_SERVICES" (lib.mapAttrs (name: value: 1) hashedServices)} + + declare -A REGISTERED_SERVICES + + while IFS="," read -r name token; + do + REGISTERED_SERVICES["$name"]="$token" + done < <(gitlab-runner --log-format json list 2>&1 | grep Token | jq -r '.msg +"," + .Token') + + echo "NEEDED_SERVICES: " "''${!NEEDED_SERVICES[@]}" + echo "REGISTERED_SERVICES:" "''${!REGISTERED_SERVICES[@]}" # difference between current and desired state - NEW_SERVICES=$(grep -vxF -f <(echo "$REGISTERED_SERVICES") <(echo "$NEEDED_SERVICES") || true) - OLD_SERVICES=$(grep -vxF -f <(echo "$NEEDED_SERVICES") <(echo "$REGISTERED_SERVICES") || true) + declare -A NEW_SERVICES + for name in "''${!NEEDED_SERVICES[@]}"; do + if [ ! -v 'REGISTERED_SERVICES[$name]' ]; then + NEW_SERVICES[$name]=1 + fi + done + + declare -A OLD_SERVICES + # shellcheck disable=SC2034 + for name in "''${!REGISTERED_SERVICES[@]}"; do + if [ ! -v 'NEEDED_SERVICES[$name]' ]; then + OLD_SERVICES[$name]=1 + fi + done # register new services ${concatStringsSep "\n" (mapAttrsToList (name: service: '' - if echo "$NEW_SERVICES" | grep -xq "${name}"; then + # TODO so here we should mention NEW_SERVICES + if [ -v 'NEW_SERVICES["${name}"]' ] ; then bash -c ${escapeShellArg (concatStringsSep " \\\n " ([ "set -a && source ${service.registrationConfigFile} &&" "gitlab-runner register" "--non-interactive" - (if service.description != null then "--description \"${service.description}\"" else "--name '${name}'") + "--name '${name}'" "--executor ${service.executor}" "--limit ${toString service.limit}" "--request-concurrency ${toString service.requestConcurrency}" @@ -92,22 +130,26 @@ let fi '') hashedServices)} + # check key is in array https://stackoverflow.com/questions/30353951/how-to-check-if-dictionary-contains-a-key-in-bash + + echo "NEW_SERVICES: ''${NEW_SERVICES[*]}" + echo "OLD_SERVICES: ''${OLD_SERVICES[*]}" # unregister old services - for NAME in $(echo "$OLD_SERVICES") + for NAME in "''${!OLD_SERVICES[@]}" do - [ ! -z "$NAME" ] && gitlab-runner unregister \ + [ -n "$NAME" ] && gitlab-runner unregister \ --name "$NAME" && sleep 1 done # make config file readable by service - chown -R --reference=$HOME $(dirname ${configPath}) - ''); + chown -R --reference="$HOME" "$(dirname ${configPath})" + ''; + }; startScript = pkgs.writeShellScriptBin "gitlab-runner-start" '' export CONFIG_FILE=${configPath} exec gitlab-runner run --working-directory $HOME ''; -in -{ +in { options.services.gitlab-runner = { enable = mkEnableOption (lib.mdDoc "Gitlab Runner"); configFile = mkOption { diff --git a/nixos/modules/services/databases/dgraph.nix b/nixos/modules/services/databases/dgraph.nix index 5726851a43f95..887164fa5b943 100644 --- a/nixos/modules/services/databases/dgraph.nix +++ b/nixos/modules/services/databases/dgraph.nix @@ -55,7 +55,7 @@ in services.dgraph = { enable = mkEnableOption (lib.mdDoc "Dgraph native GraphQL database with a graph backend"); - package = lib.mkPackageOption pkgs "dgraph" { }; + package = lib.mkPackageOptionMD pkgs "dgraph" { }; settings = mkOption { type = settingsFormat.type; diff --git a/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json b/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json index 128178bfa027f..4a173f7322972 100644 --- a/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json +++ b/nixos/modules/services/desktops/pipewire/daemon/jack.conf.json @@ -33,6 +33,31 @@ "actions": { "update-props": {} } + }, + { + "matches": [ + { + "application.process.binary": "jack_bufsize" + } + ], + "actions": { + "update-props": { + "jack.global-buffer-size": true + } + } + }, + { + "matches": [ + { + "application.process.binary": "qsynth" + } + ], + "actions": { + "update-props": { + "node.pause-on-idle": false, + "node.passive": true + } + } } ] } diff --git a/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json b/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json index 114afbfb0ea46..b1a864853325c 100644 --- a/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json +++ b/nixos/modules/services/desktops/pipewire/daemon/pipewire-pulse.conf.json @@ -32,10 +32,12 @@ "args": {} } ], - "context.exec": [ + "context.exec": [], + "pulse.cmd": [ { - "path": "pactl", - "args": "load-module module-always-sink" + "cmd": "load-module", + "args": "module-always-sink", + "flags": [] } ], "stream.properties": {}, @@ -89,13 +91,14 @@ { "matches": [ { - "application.name": "~speech-dispatcher*" + "application.name": "~speech-dispatcher.*" } ], "actions": { "update-props": { - "pulse.min.req": "1024/48000", - "pulse.min.quantum": "1024/48000" + "pulse.min.req": "512/48000", + "pulse.min.quantum": "512/48000", + "pulse.idle.timeout": 5 } } } diff --git a/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json b/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json index bf3b2d660827a..53fc103d22144 100644 --- a/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json +++ b/nixos/modules/services/desktops/pipewire/daemon/pipewire.conf.json @@ -70,6 +70,14 @@ }, { "name": "libpipewire-module-session-manager" + }, + { + "name": "libpipewire-module-x11-bell", + "args": {}, + "flags": [ + "ifexists", + "nofail" + ] } ], "context.objects": [ diff --git a/nixos/modules/services/mail/listmonk.nix b/nixos/modules/services/mail/listmonk.nix index 8b636bd5b1ff6..251362fdd89d3 100644 --- a/nixos/modules/services/mail/listmonk.nix +++ b/nixos/modules/services/mail/listmonk.nix @@ -128,7 +128,7 @@ in { ''; }; }; - package = mkPackageOption pkgs "listmonk" {}; + package = mkPackageOptionMD pkgs "listmonk" {}; settings = mkOption { type = types.submodule { freeformType = tomlFormat.type; }; description = lib.mdDoc '' diff --git a/nixos/modules/services/misc/input-remapper.nix b/nixos/modules/services/misc/input-remapper.nix index 51e1abdc98a08..6353966f5c3ff 100644 --- a/nixos/modules/services/misc/input-remapper.nix +++ b/nixos/modules/services/misc/input-remapper.nix @@ -7,7 +7,7 @@ let cfg = config.services.input-remapper; in options = { services.input-remapper = { enable = mkEnableOption (lib.mdDoc "input-remapper, an easy to use tool to change the mapping of your input device buttons."); - package = options.mkPackageOption pkgs "input-remapper" { }; + package = mkPackageOptionMD pkgs "input-remapper" { }; enableUdevRules = mkEnableOption (lib.mdDoc "udev rules added by input-remapper to handle hotplugged devices. Currently disabled by default due to https://github.com/sezanzeb/input-remapper/issues/140"); serviceWantedBy = mkOption { default = [ "graphical.target" ]; diff --git a/nixos/modules/services/misc/paperless.nix b/nixos/modules/services/misc/paperless.nix index 33a8394dff2d2..1dddd147ac095 100644 --- a/nixos/modules/services/misc/paperless.nix +++ b/nixos/modules/services/misc/paperless.nix @@ -212,14 +212,14 @@ in systemd.services.paperless-scheduler = { description = "Paperless Celery Beat"; + wantedBy = [ "multi-user.target" ]; + wants = [ "paperless-consumer.service" "paperless-web.service" "paperless-task-queue.service" ]; serviceConfig = defaultServiceConfig // { User = cfg.user; ExecStart = "${pkg}/bin/celery --app paperless beat --loglevel INFO"; Restart = "on-failure"; }; environment = env; - wantedBy = [ "multi-user.target" ]; - wants = [ "paperless-consumer.service" "paperless-web.service" "paperless-task-queue.service" ]; preStart = '' ln -sf ${manage} ${cfg.dataDir}/paperless-manage @@ -248,6 +248,7 @@ in systemd.services.paperless-task-queue = { description = "Paperless Celery Workers"; + after = [ "paperless-scheduler.service" ]; serviceConfig = defaultServiceConfig // { User = cfg.user; ExecStart = "${pkg}/bin/celery --app paperless worker --loglevel INFO"; @@ -275,20 +276,24 @@ in systemd.services.paperless-consumer = { description = "Paperless document consumer"; + # Bind to `paperless-scheduler` so that the consumer never runs + # during migrations + bindsTo = [ "paperless-scheduler.service" ]; + after = [ "paperless-scheduler.service" ]; serviceConfig = defaultServiceConfig // { User = cfg.user; ExecStart = "${pkg}/bin/paperless-ngx document_consumer"; Restart = "on-failure"; }; environment = env; - # Bind to `paperless-scheduler` so that the consumer never runs - # during migrations - bindsTo = [ "paperless-scheduler.service" ]; - after = [ "paperless-scheduler.service" ]; }; systemd.services.paperless-web = { description = "Paperless web server"; + # Bind to `paperless-scheduler` so that the web server never runs + # during migrations + bindsTo = [ "paperless-scheduler.service" ]; + after = [ "paperless-scheduler.service" ]; serviceConfig = defaultServiceConfig // { User = cfg.user; ExecStart = '' @@ -312,10 +317,6 @@ in # Allow the web interface to access the private /tmp directory of the server. # This is required to support uploading files via the web interface. unitConfig.JoinsNamespaceOf = "paperless-task-queue.service"; - # Bind to `paperless-scheduler` so that the web server never runs - # during migrations - bindsTo = [ "paperless-scheduler.service" ]; - after = [ "paperless-scheduler.service" ]; }; users = optionalAttrs (cfg.user == defaultUser) { diff --git a/nixos/modules/services/misc/polaris.nix b/nixos/modules/services/misc/polaris.nix index 83da486083b42..70f097f028406 100644 --- a/nixos/modules/services/misc/polaris.nix +++ b/nixos/modules/services/misc/polaris.nix @@ -13,7 +13,7 @@ in services.polaris = { enable = mkEnableOption (lib.mdDoc "Polaris Music Server"); - package = mkPackageOption pkgs "polaris" { }; + package = mkPackageOptionMD pkgs "polaris" { }; user = mkOption { type = types.str; diff --git a/nixos/modules/services/monitoring/apcupsd.nix b/nixos/modules/services/monitoring/apcupsd.nix index d4216b44cdc8c..666479c78a84d 100644 --- a/nixos/modules/services/monitoring/apcupsd.nix +++ b/nixos/modules/services/monitoring/apcupsd.nix @@ -62,6 +62,21 @@ let ); + # Ensure the CLI uses our generated configFile + wrappedBinaries = pkgs.runCommandLocal "apcupsd-wrapped-binaries" + { nativeBuildInputs = [ pkgs.makeWrapper ]; } + '' + for p in "${lib.getBin pkgs.apcupsd}/bin/"*; do + bname=$(basename "$p") + makeWrapper "$p" "$out/bin/$bname" --add-flags "-f ${configFile}" + done + ''; + + apcupsdWrapped = pkgs.symlinkJoin { + name = "apcupsd-wrapped"; + # Put wrappers first so they "win" + paths = [ wrappedBinaries pkgs.apcupsd ]; + }; in { @@ -138,7 +153,7 @@ in } ]; # Give users access to the "apcaccess" tool - environment.systemPackages = [ pkgs.apcupsd ]; + environment.systemPackages = [ apcupsdWrapped ]; # NOTE 1: apcupsd runs as root because it needs permission to run # "shutdown" diff --git a/nixos/modules/services/monitoring/parsedmarc.md b/nixos/modules/services/monitoring/parsedmarc.md index d93134a4cc767..5a17f79da5d46 100644 --- a/nixos/modules/services/monitoring/parsedmarc.md +++ b/nixos/modules/services/monitoring/parsedmarc.md @@ -17,7 +17,6 @@ services.parsedmarc = { host = "imap.example.com"; user = "alice@example.com"; password = "/path/to/imap_password_file"; - watch = true; }; provision.geoIp = false; # Not recommended! }; diff --git a/nixos/modules/services/monitoring/parsedmarc.nix b/nixos/modules/services/monitoring/parsedmarc.nix index 3540d91fc9f37..40c76b804559c 100644 --- a/nixos/modules/services/monitoring/parsedmarc.nix +++ b/nixos/modules/services/monitoring/parsedmarc.nix @@ -123,7 +123,10 @@ in host = "imap.example.com"; user = "alice@example.com"; password = { _secret = "/run/keys/imap_password" }; + }; + mailbox = { watch = true; + batch_size = 30; }; splunk_hec = { url = "https://splunkhec.example.com"; @@ -170,6 +173,24 @@ in }; }; + mailbox = { + watch = lib.mkOption { + type = lib.types.bool; + default = true; + description = lib.mdDoc '' + Use the IMAP IDLE command to process messages as they arrive. + ''; + }; + + delete = lib.mkOption { + type = lib.types.bool; + default = false; + description = lib.mdDoc '' + Delete messages after processing them, instead of archiving them. + ''; + }; + }; + imap = { host = lib.mkOption { type = lib.types.str; @@ -216,22 +237,6 @@ in ''; apply = x: if isAttrs x || x == null then x else { _secret = x; }; }; - - watch = lib.mkOption { - type = lib.types.bool; - default = true; - description = lib.mdDoc '' - Use the IMAP IDLE command to process messages as they arrive. - ''; - }; - - delete = lib.mkOption { - type = lib.types.bool; - default = false; - description = lib.mdDoc '' - Delete messages after processing them, instead of archiving them. - ''; - }; }; smtp = { @@ -360,6 +365,13 @@ in config = lib.mkIf cfg.enable { + warnings = let + deprecationWarning = optname: "Starting in 8.0.0, the `${optname}` option has been moved from the `services.parsedmarc.settings.imap`" + + "configuration section to the `services.parsedmarc.settings.mailbox` configuration section."; + hasImapOpt = lib.flip builtins.hasAttr cfg.settings.imap; + movedOptions = [ "reports_folder" "archive_folder" "watch" "delete" "test" "batch_size" ]; + in builtins.map deprecationWarning (builtins.filter hasImapOpt movedOptions); + services.elasticsearch.enable = lib.mkDefault cfg.provision.elasticsearch; services.geoipupdate = lib.mkIf cfg.provision.geoIp { @@ -444,6 +456,8 @@ in ssl = false; user = cfg.provision.localMail.recipientName; password = "${pkgs.writeText "imap-password" "@imap-password@"}"; + }; + mailbox = { watch = true; }; }) diff --git a/nixos/modules/services/monitoring/parsedmarc.xml b/nixos/modules/services/monitoring/parsedmarc.xml index 7167b52d0357d..b6a4bcf8ff5a5 100644 --- a/nixos/modules/services/monitoring/parsedmarc.xml +++ b/nixos/modules/services/monitoring/parsedmarc.xml @@ -15,14 +15,13 @@ email address and saves them to a local Elasticsearch instance looks like this: </para> - <programlisting language="bash"> + <programlisting> services.parsedmarc = { enable = true; settings.imap = { host = "imap.example.com"; user = "alice@example.com"; password = "/path/to/imap_password_file"; - watch = true; }; provision.geoIp = false; # Not recommended! }; @@ -45,7 +44,7 @@ services.parsedmarc = { email address that should be configured in the domain’s dmarc policy is <literal>dmarc@monitoring.example.com</literal>. </para> - <programlisting language="bash"> + <programlisting> services.parsedmarc = { enable = true; provision = { @@ -68,7 +67,7 @@ services.parsedmarc = { Elasticsearch instance is automatically added as a Grafana datasource, and the dashboard is added to Grafana as well. </para> - <programlisting language="bash"> + <programlisting> services.parsedmarc = { enable = true; provision = { diff --git a/nixos/modules/services/networking/ntp/chrony.nix b/nixos/modules/services/networking/ntp/chrony.nix index 7e3bb565d10bf..dc180d4a4f954 100644 --- a/nixos/modules/services/networking/ntp/chrony.nix +++ b/nixos/modules/services/networking/ntp/chrony.nix @@ -147,9 +147,9 @@ in systemd.services.systemd-timedated.environment = { SYSTEMD_TIMEDATED_NTP_SERVICES = "chronyd.service"; }; systemd.tmpfiles.rules = [ - "d ${stateDir} 0755 chrony chrony - -" - "f ${driftFile} 0640 chrony chrony -" - "f ${keyFile} 0640 chrony chrony -" + "d ${stateDir} 0750 chrony chrony - -" + "f ${driftFile} 0640 chrony chrony - -" + "f ${keyFile} 0640 chrony chrony - -" ]; systemd.services.chronyd = @@ -164,15 +164,47 @@ in path = [ chronyPkg ]; unitConfig.ConditionCapability = "CAP_SYS_TIME"; - serviceConfig = - { Type = "simple"; - ExecStart = "${chronyPkg}/bin/chronyd ${builtins.toString chronyFlags}"; - - ProtectHome = "yes"; - ProtectSystem = "full"; - PrivateTmp = "yes"; - }; - + serviceConfig = { + Type = "simple"; + ExecStart = "${chronyPkg}/bin/chronyd ${builtins.toString chronyFlags}"; + + # Proc filesystem + ProcSubset = "pid"; + ProtectProc = "invisible"; + # Access write directories + ReadWritePaths = [ "${stateDir}" ]; + UMask = "0027"; + # Capabilities + CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_DAC_OVERRIDE" "CAP_NET_BIND_SERVICE" "CAP_SETGID" "CAP_SETUID" "CAP_SYS_RESOURCE" "CAP_SYS_TIME" ]; + # Device Access + DeviceAllow = [ "char-pps rw" "char-ptp rw" "char-rtc rw" ]; + DevicePolicy = "closed"; + # Security + NoNewPrivileges = true; + # Sandboxing + ProtectSystem = "full"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + PrivateUsers = false; + ProtectHostname = true; + ProtectClock = false; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + # System Call Filtering + SystemCallArchitectures = "native"; + SystemCallFilter = [ "~@cpu-emulation @debug @keyring @mount @obsolete @privileged @resources" "@clock" "@setuid" "capset" "chown" ]; + }; }; }; } diff --git a/nixos/modules/services/networking/openconnect.nix b/nixos/modules/services/networking/openconnect.nix index 4676b1733af68..5a02bd072257f 100644 --- a/nixos/modules/services/networking/openconnect.nix +++ b/nixos/modules/services/networking/openconnect.nix @@ -116,7 +116,7 @@ let }; in { options.networking.openconnect = { - package = mkPackageOption pkgs "openconnect" { }; + package = mkPackageOptionMD pkgs "openconnect" { }; interfaces = mkOption { description = lib.mdDoc "OpenConnect interfaces."; diff --git a/nixos/modules/services/networking/radicale.nix b/nixos/modules/services/networking/radicale.nix index 9ec507fe2ab6a..8e4789c7ca597 100644 --- a/nixos/modules/services/networking/radicale.nix +++ b/nixos/modules/services/networking/radicale.nix @@ -200,5 +200,5 @@ in { }; }; - meta.maintainers = with lib.maintainers; [ aneeshusa infinisil dotlambda ]; + meta.maintainers = with lib.maintainers; [ infinisil dotlambda ]; } diff --git a/nixos/modules/services/networking/shellhub-agent.nix b/nixos/modules/services/networking/shellhub-agent.nix index ad33c50f9d633..7cce23cb9c4e3 100644 --- a/nixos/modules/services/networking/shellhub-agent.nix +++ b/nixos/modules/services/networking/shellhub-agent.nix @@ -14,7 +14,7 @@ in enable = mkEnableOption (lib.mdDoc "ShellHub Agent daemon"); - package = mkPackageOption pkgs "shellhub-agent" { }; + package = mkPackageOptionMD pkgs "shellhub-agent" { }; preferredHostname = mkOption { type = types.str; diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index af8200c7e2951..37d7518ab3c4e 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -79,8 +79,8 @@ in { imports = [ - (mkAliasOptionModule [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ]) - (mkAliasOptionModule [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ]) + (mkAliasOptionModuleMD [ "services" "sshd" "enable" ] [ "services" "openssh" "enable" ]) + (mkAliasOptionModuleMD [ "services" "openssh" "knownHosts" ] [ "programs" "ssh" "knownHosts" ]) (mkRenamedOptionModule [ "services" "openssh" "challengeResponseAuthentication" ] [ "services" "openssh" "kbdInteractiveAuthentication" ]) ]; diff --git a/nixos/modules/services/networking/vdirsyncer.nix b/nixos/modules/services/networking/vdirsyncer.nix index 6a069943434da..f9b880c763e3d 100644 --- a/nixos/modules/services/networking/vdirsyncer.nix +++ b/nixos/modules/services/networking/vdirsyncer.nix @@ -71,7 +71,7 @@ in services.vdirsyncer = { enable = mkEnableOption (mdDoc "vdirsyncer"); - package = mkPackageOption pkgs "vdirsyncer" {}; + package = mkPackageOptionMD pkgs "vdirsyncer" {}; jobs = mkOption { description = mdDoc "vdirsyncer job configurations"; diff --git a/nixos/modules/services/networking/webhook.nix b/nixos/modules/services/networking/webhook.nix index b020db6961c32..2a78491941cf9 100644 --- a/nixos/modules/services/networking/webhook.nix +++ b/nixos/modules/services/networking/webhook.nix @@ -36,7 +36,7 @@ in { which execute configured commands for any person or service that knows the URL ''); - package = mkPackageOption pkgs "webhook" {}; + package = mkPackageOptionMD pkgs "webhook" {}; user = mkOption { type = types.str; default = defaultUser; diff --git a/nixos/modules/services/torrent/transmission.nix b/nixos/modules/services/torrent/transmission.nix index 4378233848338..752ab91fe6315 100644 --- a/nixos/modules/services/torrent/transmission.nix +++ b/nixos/modules/services/torrent/transmission.nix @@ -19,8 +19,8 @@ in imports = [ (mkRenamedOptionModule ["services" "transmission" "port"] ["services" "transmission" "settings" "rpc-port"]) - (mkAliasOptionModule ["services" "transmission" "openFirewall"] - ["services" "transmission" "openPeerPorts"]) + (mkAliasOptionModuleMD ["services" "transmission" "openFirewall"] + ["services" "transmission" "openPeerPorts"]) ]; options = { services.transmission = { @@ -174,7 +174,7 @@ in }; }; - package = mkPackageOption pkgs "transmission" {}; + package = mkPackageOptionMD pkgs "transmission" {}; downloadDirPermissions = mkOption { type = with types; nullOr str; diff --git a/nixos/modules/services/web-apps/snipe-it.nix b/nixos/modules/services/web-apps/snipe-it.nix index 314a69a73a872..93b0aafab64bf 100644 --- a/nixos/modules/services/web-apps/snipe-it.nix +++ b/nixos/modules/services/web-apps/snipe-it.nix @@ -454,8 +454,9 @@ in { # A placeholder file for invalid barcodes invalid_barcode_location="${cfg.dataDir}/public/uploads/barcodes/invalid_barcode.gif" - [ ! -e "$invalid_barcode_location" ] \ - && cp ${snipe-it}/share/snipe-it/invalid_barcode.gif "$invalid_barcode_location" + if [ ! -e "$invalid_barcode_location" ]; then + cp ${snipe-it}/share/snipe-it/invalid_barcode.gif "$invalid_barcode_location" + fi ''; }; diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix index 95e600ea79a5a..d31f3d5d4650b 100644 --- a/nixos/modules/services/web-servers/nginx/default.nix +++ b/nixos/modules/services/web-servers/nginx/default.nix @@ -571,7 +571,7 @@ in defaultText = literalExpression "pkgs.nginxStable"; type = types.package; apply = p: p.override { - modules = p.modules ++ cfg.additionalModules; + modules = lib.unique (p.modules ++ cfg.additionalModules); }; description = lib.mdDoc '' Nginx package to use. This defaults to the stable version. Note diff --git a/nixos/modules/services/x11/desktop-managers/cinnamon.nix b/nixos/modules/services/x11/desktop-managers/cinnamon.nix index 08c5625fc7ddd..df1b6f731a4e4 100644 --- a/nixos/modules/services/x11/desktop-managers/cinnamon.nix +++ b/nixos/modules/services/x11/desktop-managers/cinnamon.nix @@ -180,6 +180,7 @@ in mint-themes mint-x-icons mint-y-icons + xapp # provides some xapp-* icons ] config.environment.cinnamon.excludePackages); xdg.mime.enable = true; diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix index 9fcb408c287d5..8270b64787f8f 100644 --- a/nixos/modules/services/x11/desktop-managers/plasma5.nix +++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix @@ -32,7 +32,7 @@ let inherit (lib) getBin optionalString literalExpression mkRemovedOptionModule mkRenamedOptionModule - mkDefault mkIf mkMerge mkOption types; + mkDefault mkIf mkMerge mkOption mkPackageOptionMD types; ini = pkgs.formats.ini { }; @@ -198,6 +198,11 @@ in example = literalExpression "[ pkgs.plasma5Packages.oxygen ]"; }; + notoPackage = mkPackageOptionMD pkgs "Noto fonts" { + default = [ "noto-fonts" ]; + example = "noto-fonts-lgc-plus"; + }; + # Internally allows configuring kdeglobals globally kdeglobals = mkOption { internal = true; @@ -401,7 +406,7 @@ in # Enable GTK applications to load SVG icons services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ]; - fonts.fonts = with pkgs; [ noto-fonts hack-font ]; + fonts.fonts = with pkgs; [ cfg.notoPackage hack-font ]; fonts.fontconfig.defaultFonts = { monospace = [ "Hack" "Noto Sans Mono" ]; sansSerif = [ "Noto Sans" ]; @@ -545,7 +550,7 @@ in } { # The user interface breaks without pulse - assertion = config.hardware.pulseaudio.enable; + assertion = config.hardware.pulseaudio.enable || (config.services.pipewire.enable && config.services.pipewire.pulse.enable); message = "Plasma Mobile requires pulseaudio."; } ]; diff --git a/nixos/modules/services/x11/picom.nix b/nixos/modules/services/x11/picom.nix index 4a0578de09cb5..1d6f3daa40225 100644 --- a/nixos/modules/services/x11/picom.nix +++ b/nixos/modules/services/x11/picom.nix @@ -41,7 +41,7 @@ let in { imports = [ - (mkAliasOptionModule [ "services" "compton" ] [ "services" "picom" ]) + (mkAliasOptionModuleMD [ "services" "compton" ] [ "services" "picom" ]) (mkRemovedOptionModule [ "services" "picom" "refreshRate" ] '' This option corresponds to `refresh-rate`, which has been unused since picom v6 and was subsequently removed by upstream. diff --git a/nixos/modules/services/x11/window-managers/i3.nix b/nixos/modules/services/x11/window-managers/i3.nix index 64109e0c39fdd..5bb73cd0bfb17 100644 --- a/nixos/modules/services/x11/window-managers/i3.nix +++ b/nixos/modules/services/x11/window-managers/i3.nix @@ -31,7 +31,6 @@ in type = types.package; default = pkgs.i3; defaultText = literalExpression "pkgs.i3"; - example = literalExpression "pkgs.i3-gaps"; description = lib.mdDoc '' i3 package to use. ''; @@ -73,6 +72,6 @@ in imports = [ (mkRemovedOptionModule [ "services" "xserver" "windowManager" "i3-gaps" "enable" ] - "Use services.xserver.windowManager.i3.enable and set services.xserver.windowManager.i3.package to pkgs.i3-gaps to use i3-gaps.") + "i3-gaps was merged into i3. Use services.xserver.windowManager.i3.enable instead.") ]; } diff --git a/nixos/modules/services/x11/window-managers/katriawm.nix b/nixos/modules/services/x11/window-managers/katriawm.nix index 106631792ff4e..9a3fd5f3ca44a 100644 --- a/nixos/modules/services/x11/window-managers/katriawm.nix +++ b/nixos/modules/services/x11/window-managers/katriawm.nix @@ -1,7 +1,7 @@ { config, lib, pkgs, ... }: let - inherit (lib) mdDoc mkEnableOption mkIf mkPackageOption singleton; + inherit (lib) mdDoc mkEnableOption mkIf mkPackageOptionMD singleton; cfg = config.services.xserver.windowManager.katriawm; in { @@ -9,7 +9,7 @@ in options = { services.xserver.windowManager.katriawm = { enable = mkEnableOption (mdDoc "katriawm"); - package = mkPackageOption pkgs "katriawm" {}; + package = mkPackageOptionMD pkgs "katriawm" {}; }; }; diff --git a/nixos/modules/services/x11/window-managers/qtile.nix b/nixos/modules/services/x11/window-managers/qtile.nix index 523642591d947..fc27566d49ee6 100644 --- a/nixos/modules/services/x11/window-managers/qtile.nix +++ b/nixos/modules/services/x11/window-managers/qtile.nix @@ -10,7 +10,7 @@ in options.services.xserver.windowManager.qtile = { enable = mkEnableOption (lib.mdDoc "qtile"); - package = mkPackageOption pkgs "qtile" { }; + package = mkPackageOptionMD pkgs "qtile" { }; }; config = mkIf cfg.enable { diff --git a/nixos/modules/system/boot/systemd/initrd.nix b/nixos/modules/system/boot/systemd/initrd.nix index 196f44ccd783c..d30f61146e189 100644 --- a/nixos/modules/system/boot/systemd/initrd.nix +++ b/nixos/modules/system/boot/systemd/initrd.nix @@ -142,7 +142,7 @@ in { ''; }; - package = (mkPackageOption pkgs "systemd" { + package = (mkPackageOptionMD pkgs "systemd" { default = "systemdStage1"; }) // { visible = false; diff --git a/nixos/modules/virtualisation/podman/default.nix b/nixos/modules/virtualisation/podman/default.nix index 13bbb4471ea5d..6c00fabaa1858 100644 --- a/nixos/modules/virtualisation/podman/default.nix +++ b/nixos/modules/virtualisation/podman/default.nix @@ -1,7 +1,6 @@ { config, lib, pkgs, ... }: let cfg = config.virtualisation.podman; - toml = pkgs.formats.toml { }; json = pkgs.formats.json { }; inherit (lib) mkOption types; @@ -27,24 +26,13 @@ let done ''; - net-conflist = pkgs.runCommand "87-podman-bridge.conflist" - { - nativeBuildInputs = [ pkgs.jq ]; - extraPlugins = builtins.toJSON cfg.defaultNetwork.extraPlugins; - jqScript = '' - . + { "plugins": (.plugins + $extraPlugins) } - ''; - } '' - jq <${cfg.package}/etc/cni/net.d/87-podman-bridge.conflist \ - --argjson extraPlugins "$extraPlugins" \ - "$jqScript" \ - >$out - ''; - in { imports = [ - ./dnsname.nix + (lib.mkRemovedOptionModule [ "virtualisation" "podman" "defaultNetwork" "dnsname" ] + "Use virtualisation.podman.defaultNetwork.settings.dns_enabled instead.") + (lib.mkRemovedOptionModule [ "virtualisation" "podman" "defaultNetwork" "extraPlugins" ] + "Netavark isn't compatible with CNI plugins.") ./network-socket.nix ]; @@ -149,11 +137,11 @@ in ''; }; - defaultNetwork.extraPlugins = lib.mkOption { - type = types.listOf json.type; - default = [ ]; + defaultNetwork.settings = lib.mkOption { + type = json.type; + default = { }; description = lib.mdDoc '' - Extra CNI plugin configurations to add to podman's default network. + Settings for podman's default network. ''; }; @@ -164,11 +152,26 @@ in environment.systemPackages = [ cfg.package ] ++ lib.optional cfg.dockerCompat dockerCompat; - environment.etc."cni/net.d/87-podman-bridge.conflist".source = net-conflist; + # https://github.com/containers/podman/blob/097cc6eb6dd8e598c0e8676d21267b4edb11e144/docs/tutorials/basic_networking.md#default-network + environment.etc."containers/networks/podman.json" = lib.mkIf (cfg.defaultNetwork.settings != { }) { + source = json.generate "podman.json" ({ + dns_enabled = false; + driver = "bridge"; + id = "0000000000000000000000000000000000000000000000000000000000000000"; + internal = false; + ipam_options = { driver = "host-local"; }; + ipv6_enabled = false; + name = "podman"; + network_interface = "podman0"; + subnets = [{ gateway = "10.88.0.1"; subnet = "10.88.0.0/16"; }]; + } // cfg.defaultNetwork.settings); + }; virtualisation.containers = { enable = true; # Enable common /etc/containers configuration - containersConf.settings = lib.optionalAttrs cfg.enableNvidia { + containersConf.settings = { + network.network_backend = "netavark"; + } // lib.optionalAttrs cfg.enableNvidia { engine = { conmon_env_vars = [ "PATH=${lib.makeBinPath [ pkgs.nvidia-podman ]}" ]; runtimes.nvidia = [ "${pkgs.nvidia-podman}/bin/nvidia-container-runtime" ]; diff --git a/nixos/modules/virtualisation/podman/dnsname.nix b/nixos/modules/virtualisation/podman/dnsname.nix deleted file mode 100644 index 3e7d35ae1e44d..0000000000000 --- a/nixos/modules/virtualisation/podman/dnsname.nix +++ /dev/null @@ -1,36 +0,0 @@ -{ config, lib, pkgs, ... }: -let - inherit (lib) - mkOption - mkIf - types - ; - - cfg = config.virtualisation.podman; - -in -{ - options = { - virtualisation.podman = { - - defaultNetwork.dnsname.enable = mkOption { - type = types.bool; - default = false; - description = lib.mdDoc '' - Enable DNS resolution in the default podman network. - ''; - }; - - }; - }; - - config = { - virtualisation.containers.containersConf.cniPlugins = mkIf cfg.defaultNetwork.dnsname.enable [ pkgs.dnsname-cni ]; - virtualisation.podman.defaultNetwork.extraPlugins = - lib.optional cfg.defaultNetwork.dnsname.enable { - type = "dnsname"; - domainName = "dns.podman"; - capabilities.aliases = true; - }; - }; -} diff --git a/nixos/modules/virtualisation/waydroid.nix b/nixos/modules/virtualisation/waydroid.nix index a2cfd806f322e..46e5f901015d9 100644 --- a/nixos/modules/virtualisation/waydroid.nix +++ b/nixos/modules/virtualisation/waydroid.nix @@ -56,12 +56,8 @@ in wantedBy = [ "multi-user.target" ]; - unitConfig = { - ConditionPathExists = "/var/lib/waydroid/lxc/waydroid"; - }; - serviceConfig = { - ExecStart = "${pkgs.waydroid}/bin/waydroid container start"; + ExecStart = "${pkgs.waydroid}/bin/waydroid -w container start"; ExecStop = "${pkgs.waydroid}/bin/waydroid container stop"; ExecStopPost = "${pkgs.waydroid}/bin/waydroid session stop"; }; diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix index 75f01d888b218..83ad7c48a0892 100644 --- a/nixos/tests/all-tests.nix +++ b/nixos/tests/all-tests.nix @@ -78,6 +78,7 @@ in { allTerminfo = handleTest ./all-terminfo.nix {}; alps = handleTest ./alps.nix {}; amazon-init-shell = handleTest ./amazon-init-shell.nix {}; + apcupsd = handleTest ./apcupsd.nix {}; apfs = handleTest ./apfs.nix {}; apparmor = handleTest ./apparmor.nix {}; atd = handleTest ./atd.nix {}; @@ -527,7 +528,6 @@ in { plotinus = handleTest ./plotinus.nix {}; podgrab = handleTest ./podgrab.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 {}; diff --git a/nixos/tests/apcupsd.nix b/nixos/tests/apcupsd.nix new file mode 100644 index 0000000000000..287140f039d85 --- /dev/null +++ b/nixos/tests/apcupsd.nix @@ -0,0 +1,41 @@ +let + # arbitrary address + ipAddr = "192.168.42.42"; +in +import ./make-test-python.nix ({ lib, pkgs, ... }: { + name = "apcupsd"; + meta.maintainers = with lib.maintainers; [ bjornfor ]; + + nodes = { + machine = { + services.apcupsd = { + enable = true; + configText = '' + UPSTYPE usb + BATTERYLEVEL 42 + # Configure NISIP so that the only way apcaccess can work is to read + # this config. + NISIP ${ipAddr} + ''; + }; + networking.interfaces.eth1 = { + ipv4.addresses = [{ + address = ipAddr; + prefixLength = 24; + }]; + }; + }; + }; + + # Check that the service starts, that the CLI (apcaccess) works and that it + # uses the config (ipAddr) defined in the service config. + testScript = '' + start_all() + machine.wait_for_unit("apcupsd.service") + machine.wait_for_open_port(3551, "${ipAddr}") + res = machine.succeed("apcaccess") + expect_line="MBATTCHG : 42 Percent" + assert "MBATTCHG : 42 Percent" in res, f"expected apcaccess output to contain '{expect_line}' but got '{res}'" + machine.shutdown() + ''; +}) diff --git a/nixos/tests/paperless.nix b/nixos/tests/paperless.nix index b97834835c2c9..7f36de4c29b71 100644 --- a/nixos/tests/paperless.nix +++ b/nixos/tests/paperless.nix @@ -26,6 +26,10 @@ import ./make-test-python.nix ({ lib, ... }: { # Wait until server accepts connections machine.wait_until_succeeds("curl -fs localhost:28981") + # Required for consuming documents via the web interface + with subtest("Task-queue gets ready"): + machine.wait_for_unit("paperless-task-queue.service") + with subtest("Add a document via the web interface"): machine.succeed( "convert -size 400x40 xc:white -font 'DejaVu-Sans' -pointsize 20 -fill black " diff --git a/nixos/tests/parsedmarc/default.nix b/nixos/tests/parsedmarc/default.nix index 50b977723e9c7..837cf9d7e6dce 100644 --- a/nixos/tests/parsedmarc/default.nix +++ b/nixos/tests/parsedmarc/default.nix @@ -155,7 +155,6 @@ in ssl = true; user = "alice"; password = "${pkgs.writeText "imap-password" "foobar"}"; - watch = true; }; }; diff --git a/nixos/tests/podman/default.nix b/nixos/tests/podman/default.nix index 106ba2057d063..c2ea399d65af3 100644 --- a/nixos/tests/podman/default.nix +++ b/nixos/tests/podman/default.nix @@ -13,6 +13,13 @@ import ../make-test-python.nix ( isNormalUser = true; }; }; + dns = { pkgs, ... }: { + virtualisation.podman.enable = true; + + virtualisation.podman.defaultNetwork.settings.dns_enabled = true; + + networking.firewall.allowedUDPPorts = [ 53 ]; + }; docker = { pkgs, ... }: { virtualisation.podman.enable = true; @@ -43,6 +50,7 @@ import ../make-test-python.nix ( podman.wait_for_unit("sockets.target") + dns.wait_for_unit("sockets.target") docker.wait_for_unit("sockets.target") start_all() @@ -120,6 +128,23 @@ import ../make-test-python.nix ( pid = podman.succeed("podman run --rm --init busybox readlink /proc/self").strip() assert pid == "2" + with subtest("aardvark-dns"): + dns.succeed("tar cv --files-from /dev/null | podman import - scratchimg") + dns.succeed( + "podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${pkgs.writeTextDir "index.html" "<h1>Hi</h1>"} scratchimg ${pkgs.python3}/bin/python -m http.server 8000" + ) + dns.succeed("podman ps | grep webserver") + dns.succeed(""" + for i in `seq 0 120`; do + podman run --rm --name=client -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg ${pkgs.curl}/bin/curl http://webserver:8000 >/dev/console \ + && exit 0 + sleep 0.5 + done + exit 1 + """) + dns.succeed("podman stop webserver") + dns.succeed("podman rm webserver") + with subtest("A podman member can use the docker cli"): docker.succeed(su_cmd("docker version")) diff --git a/nixos/tests/podman/dnsname.nix b/nixos/tests/podman/dnsname.nix deleted file mode 100644 index 3768ae79e0676..0000000000000 --- a/nixos/tests/podman/dnsname.nix +++ /dev/null @@ -1,42 +0,0 @@ -import ../make-test-python.nix ( - { pkgs, lib, ... }: - let - inherit (pkgs) writeTextDir python3 curl; - webroot = writeTextDir "index.html" "<h1>Hi</h1>"; - in - { - name = "podman-dnsname"; - meta = { - maintainers = with lib.maintainers; [ roberth ] ++ lib.teams.podman.members; - }; - - nodes = { - podman = { pkgs, ... }: { - virtualisation.podman.enable = true; - virtualisation.podman.defaultNetwork.dnsname.enable = true; - }; - }; - - testScript = '' - podman.wait_for_unit("sockets.target") - - with subtest("DNS works"): # also tests inter-container tcp routing - podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg") - podman.succeed( - "podman run -d --name=webserver -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin -w ${webroot} scratchimg ${python3}/bin/python -m http.server 8000" - ) - podman.succeed("podman ps | grep webserver") - podman.succeed(""" - for i in `seq 0 120`; do - podman run --rm --name=client -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg ${curl}/bin/curl http://webserver:8000 >/dev/console \ - && exit 0 - sleep 0.5 - done - exit 1 - """) - podman.succeed("podman stop webserver") - podman.succeed("podman rm webserver") - - ''; - } -) diff --git a/nixos/tests/wordpress.nix b/nixos/tests/wordpress.nix index 416a20aa7fe81..6a460dbce3547 100644 --- a/nixos/tests/wordpress.nix +++ b/nixos/tests/wordpress.nix @@ -1,6 +1,6 @@ -import ./make-test-python.nix ({ pkgs, ... }: +import ./make-test-python.nix ({ lib, pkgs, ... }: -{ +rec { name = "wordpress"; meta = with pkgs.lib.maintainers; { maintainers = [ @@ -10,17 +10,22 @@ import ./make-test-python.nix ({ pkgs, ... }: ]; }; - nodes = { - wp_httpd = { ... }: { + nodes = lib.foldl (a: version: let + package = pkgs."wordpress${version}"; + in a // { + "wp${version}_httpd" = _: { services.httpd.adminAddr = "webmaster@site.local"; services.httpd.logPerVirtualHost = true; + services.wordpress.webserver = "httpd"; services.wordpress.sites = { "site1.local" = { database.tablePrefix = "site1_"; + inherit package; }; "site2.local" = { database.tablePrefix = "site2_"; + inherit package; }; }; @@ -28,14 +33,16 @@ import ./make-test-python.nix ({ pkgs, ... }: networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ]; }; - wp_nginx = { ... }: { + "wp${version}_nginx" = _: { services.wordpress.webserver = "nginx"; services.wordpress.sites = { "site1.local" = { database.tablePrefix = "site1_"; + inherit package; }; "site2.local" = { database.tablePrefix = "site2_"; + inherit package; }; }; @@ -43,34 +50,38 @@ import ./make-test-python.nix ({ pkgs, ... }: networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ]; }; - wp_caddy = { ... }: { + "wp${version}_caddy" = _: { services.wordpress.webserver = "caddy"; services.wordpress.sites = { "site1.local" = { database.tablePrefix = "site1_"; + inherit package; }; "site2.local" = { database.tablePrefix = "site2_"; + inherit package; }; }; networking.firewall.allowedTCPPorts = [ 80 ]; networking.hosts."127.0.0.1" = [ "site1.local" "site2.local" ]; }; - }; + }) {} [ + "6_1" + ]; testScript = '' import re start_all() - wp_httpd.wait_for_unit("httpd") - wp_nginx.wait_for_unit("nginx") - wp_caddy.wait_for_unit("caddy") + ${lib.concatStrings (lib.mapAttrsToList (name: value: '' + ${name}.wait_for_unit("${(value null).services.wordpress.webserver}") + '') nodes)} site_names = ["site1.local", "site2.local"] - for machine in (wp_httpd, wp_nginx, wp_caddy): + for machine in (${lib.concatStringsSep ", " (builtins.attrNames nodes)}): for site_name in site_names: machine.wait_for_unit(f"phpfpm-wordpress-{site_name}") |