diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 219efb6e2a54..432191b92de4 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -105,3 +105,6 @@ fb0e5be84331188a69b3edd31679ca6576edb75a # {pkgs/development/cuda-modules,pkgs/test/cuda,pkgs/top-level/cuda-packages.nix}: reformat all CUDA files with nixfmt-rfc-style 2023-03-01 802a1b4d3338f24cbc4efd704616654456d75a94 + +# postgresql: move packages.nix to ext/default.nix +719034f6f6749d624faa28dff259309fc0e3e730 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index aff7aee0f797..3d45e69971b1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -13,7 +13,6 @@ # GitHub actions /.github/workflows @NixOS/Security @Mic92 @zowoq -/.github/workflows/merge-staging @FRidh # EditorConfig /.editorconfig @Mic92 @zowoq @@ -42,7 +41,7 @@ /pkgs/top-level/splice.nix @Ericson2314 /pkgs/top-level/release-cross.nix @Ericson2314 /pkgs/stdenv/generic @Ericson2314 -/pkgs/stdenv/generic/check-meta.nix @Ericson2314 @piegamesde +/pkgs/stdenv/generic/check-meta.nix @Ericson2314 /pkgs/stdenv/cross @Ericson2314 /pkgs/build-support/cc-wrapper @Ericson2314 /pkgs/build-support/bintools-wrapper @Ericson2314 @@ -125,10 +124,8 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @raitobezarius @ma27 /pkgs/common-updater/scripts/update-source-version @jtojnar # Python-related code and docs -/maintainers/scripts/update-python-libraries @FRidh -/pkgs/development/interpreters/python @FRidh -/doc/languages-frameworks/python.section.md @FRidh @mweinelt -/pkgs/development/interpreters/python/hooks @FRidh @jonringer +/doc/languages-frameworks/python.section.md @mweinelt +/pkgs/development/interpreters/python/hooks @jonringer # Haskell /doc/languages-frameworks/haskell.section.md @sternenseemann @maralorn @ncfavier @@ -148,10 +145,6 @@ nixos/modules/installer/tools/nix-fallback-paths.nix @raitobezarius @ma27 /pkgs/applications/science/math/R @jbedo /pkgs/development/r-modules @jbedo -# Ruby -/pkgs/development/interpreters/ruby @marsam -/pkgs/development/ruby-modules @marsam - # Rust /pkgs/development/compilers/rust @Mic92 @zowoq @winterqt @figsoda /pkgs/build-support/rust @zowoq @winterqt @figsoda @@ -185,20 +178,20 @@ pkgs/development/python-modules/buildcatrust/ @ajs124 @lukegb @mweinelt /lib/licenses.nix @alyssais # Qt -/pkgs/development/libraries/qt-5 @NixOS/qt-kde -/pkgs/development/libraries/qt-6 @NixOS/qt-kde +/pkgs/development/libraries/qt-5 @K900 @NickCao @SuperSandro2000 @ttuegel +/pkgs/development/libraries/qt-6 @K900 @NickCao @SuperSandro2000 @ttuegel # KDE / Plasma 5 -/pkgs/applications/kde @NixOS/qt-kde -/pkgs/desktops/plasma-5 @NixOS/qt-kde -/pkgs/development/libraries/kde-frameworks @NixOS/qt-kde +/pkgs/applications/kde @K900 @NickCao @SuperSandro2000 @ttuegel +/pkgs/desktops/plasma-5 @K900 @NickCao @SuperSandro2000 @ttuegel +/pkgs/development/libraries/kde-frameworks @K900 @NickCao @SuperSandro2000 @ttuegel # KDE / Plasma 6 -/pkgs/kde @NixOS/qt-kde -/maintainers/scripts/kde @NixOS/qt-kde +/pkgs/kde @K900 @NickCao @SuperSandro2000 @ttuegel +/maintainers/scripts/kde @K900 @NickCao @SuperSandro2000 @ttuegel # PostgreSQL and related stuff -/pkgs/servers/sql/postgresql @thoughtpolice @marsam +/pkgs/servers/sql/postgresql @thoughtpolice /nixos/modules/services/databases/postgresql.xml @thoughtpolice /nixos/modules/services/databases/postgresql.nix @thoughtpolice /nixos/tests/postgresql.nix @thoughtpolice @@ -298,7 +291,7 @@ nixos/modules/services/networking/networkmanager.nix @Janik-Haag # GNOME /pkgs/desktops/gnome @jtojnar -/pkgs/desktops/gnome/extensions @piegamesde @jtojnar +/pkgs/desktops/gnome/extensions @jtojnar /pkgs/build-support/make-hardcode-gsettings-patch @jtojnar # Cinnamon @@ -312,13 +305,6 @@ nixos/modules/services/networking/networkmanager.nix @Janik-Haag # terraform providers /pkgs/applications/networking/cluster/terraform-providers @zowoq -# Matrix -/pkgs/servers/heisenbridge @piegamesde -/pkgs/servers/matrix-conduit @piegamesde -/nixos/modules/services/misc/heisenbridge.nix @piegamesde -/nixos/modules/services/misc/matrix-conduit.nix @piegamesde -/nixos/tests/matrix-conduit.nix @piegamesde - # Forgejo nixos/modules/services/misc/forgejo.nix @bendlas @emilylange pkgs/applications/version-management/forgejo @bendlas @emilylange diff --git a/.github/labeler.yml b/.github/labeler.yml index d7adc601e580..b88f7f5179ec 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -369,3 +369,8 @@ - changed-files: - any-glob-to-any-file: - nixos/modules/**/* +"8.has: maintainer-list (update)": + - any: + - changed-files: + - any-glob-to-any-file: + - maintainers/maintainer-list.nix diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index d4e91e6a2a0c..7a168d14a479 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -20,7 +20,7 @@ jobs: if: github.repository_owner == 'NixOS' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name)) runs-on: ubuntu-latest steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Create backport PRs diff --git a/.github/workflows/basic-eval.yml b/.github/workflows/basic-eval.yml index 9008ca208e17..6059ba784959 100644 --- a/.github/workflows/basic-eval.yml +++ b/.github/workflows/basic-eval.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest # we don't limit this action to only NixOS repo since the checks are cheap and useful developer feedback steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26 - uses: cachix/cachix-action@18cf96c7c98e048e10a83abd92116114cd8504be # v14 with: @@ -26,4 +26,4 @@ jobs: name: nixpkgs-ci signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' # explicit list of supportedSystems is needed until aarch64-darwin becomes part of the trunk jobset - - run: nix-build pkgs/top-level/release.nix -A tarball.nixpkgs-basic-release-checks --arg supportedSystems '[ "aarch64-darwin" "aarch64-linux" "x86_64-linux" "x86_64-darwin" ]' + - run: nix-build pkgs/top-level/release.nix -A release-checks --arg supportedSystems '[ "aarch64-darwin" "aarch64-linux" "x86_64-linux" "x86_64-darwin" ]' diff --git a/.github/workflows/check-by-name.yml b/.github/workflows/check-by-name.yml index bdc223e3d32c..8e2011cb6d52 100644 --- a/.github/workflows/check-by-name.yml +++ b/.github/workflows/check-by-name.yml @@ -20,6 +20,13 @@ permissions: # We need this permission to cancel the workflow run if there's a merge conflict actions: write +# Create a check-by-name concurrency group based on the pull request number. if +# an event triggers a run on the same PR while a previous run is still in +# progress, the previous run will be canceled and the new one will start. +concurrency: + group: check-by-name-${{ github.event.pull_request.number }} + cancel-in-progress: true + jobs: check: # This needs to be x86_64-linux, because we depend on the tooling being pre-built in the GitHub releases @@ -39,7 +46,7 @@ jobs: # https://docs.github.com/en/rest/guides/using-the-rest-api-to-interact-with-your-git-database?apiVersion=2022-11-28#checking-mergeability-of-pull-requests # Retry the API query this many times - retryCount=3 + retryCount=5 # Start with 5 seconds, but double every retry retryInterval=5 while true; do @@ -84,7 +91,7 @@ jobs: exit 1 fi echo "mergedSha=$mergedSha" >> "$GITHUB_ENV" - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # pull_request_target checks out the base branch by default ref: ${{ env.mergedSha }} @@ -107,6 +114,10 @@ jobs: # Adds a result symlink as a GC root nix-store --realise "$toolPath" --add-root result - name: Running nixpkgs-check-by-name + env: + # Force terminal colors to be enabled. The library that + # nixpkgs-check-by-name uses respects: https://bixense.com/clicolors/ + CLICOLOR_FORCE: 1 run: | if result/bin/nixpkgs-check-by-name --base "$base" .; then exit 0 diff --git a/.github/workflows/check-cherry-picks.yml b/.github/workflows/check-cherry-picks.yml index 8dfc3f6c0606..f8d244594165 100644 --- a/.github/workflows/check-cherry-picks.yml +++ b/.github/workflows/check-cherry-picks.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest if: github.repository_owner == 'NixOS' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: fetch-depth: 0 filter: blob:none diff --git a/.github/workflows/check-maintainers-sorted.yaml b/.github/workflows/check-maintainers-sorted.yaml index 74012e266365..062522928c2a 100644 --- a/.github/workflows/check-maintainers-sorted.yaml +++ b/.github/workflows/check-maintainers-sorted.yaml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest if: github.repository_owner == 'NixOS' steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # pull_request_target checks out the base branch by default ref: refs/pull/${{ github.event.pull_request.number }}/merge diff --git a/.github/workflows/check-nix-format.yml b/.github/workflows/check-nix-format.yml index c1d87faca213..fff18d201d43 100644 --- a/.github/workflows/check-nix-format.yml +++ b/.github/workflows/check-nix-format.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest if: github.repository_owner == 'NixOS' steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # pull_request_target checks out the base branch by default ref: refs/pull/${{ github.event.pull_request.number }}/merge @@ -32,11 +32,15 @@ jobs: # Each environment variable beginning with NIX_FMT_PATHS_ is a list of # paths to check with nixfmt. env: + NIX_FMT_PATHS_MPVSCRIPTS: pkgs/applications/video/mpv/scripts # Format paths related to the Nixpkgs CUDA ecosystem. NIX_FMT_PATHS_CUDA: | pkgs/development/cuda-modules pkgs/test/cuda pkgs/top-level/cuda-packages.nix + NIX_FMT_PATHS_VSCODE_EXTS: pkgs/applications/editors/vscode/extensions + NIX_FMT_PATHS_PHP_PACKAGES: pkgs/development/php-packages + NIX_FMT_PATHS_BUILD_SUPPORT_PHP: pkgs/build-support/php # Iterate over all environment variables beginning with NIX_FMT_PATHS_. run: | for env_var in "${!NIX_FMT_PATHS_@}"; do diff --git a/.github/workflows/editorconfig.yml b/.github/workflows/editorconfig.yml index 168e5bccaea4..bb864ace316b 100644 --- a/.github/workflows/editorconfig.yml +++ b/.github/workflows/editorconfig.yml @@ -24,7 +24,7 @@ jobs: - name: print list of changed files run: | cat "$HOME/changed_files" - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # pull_request_target checks out the base branch by default ref: refs/pull/${{ github.event.pull_request.number }}/merge diff --git a/.github/workflows/manual-nixos.yml b/.github/workflows/manual-nixos.yml index 2ad091720511..ac5532a25370 100644 --- a/.github/workflows/manual-nixos.yml +++ b/.github/workflows/manual-nixos.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.repository_owner == 'NixOS' steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # pull_request_target checks out the base branch by default ref: refs/pull/${{ github.event.pull_request.number }}/merge diff --git a/.github/workflows/manual-nixpkgs.yml b/.github/workflows/manual-nixpkgs.yml index b56d89eccd61..672ebf61ac77 100644 --- a/.github/workflows/manual-nixpkgs.yml +++ b/.github/workflows/manual-nixpkgs.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest if: github.repository_owner == 'NixOS' steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # pull_request_target checks out the base branch by default ref: refs/pull/${{ github.event.pull_request.number }}/merge diff --git a/.github/workflows/nix-parse.yml b/.github/workflows/nix-parse.yml index da2e942414e2..b86594e0d53b 100644 --- a/.github/workflows/nix-parse.yml +++ b/.github/workflows/nix-parse.yml @@ -24,7 +24,7 @@ jobs: if [[ -s "$HOME/changed_files" ]]; then echo "CHANGED_FILES=$HOME/changed_files" > "$GITHUB_ENV" fi - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 with: # pull_request_target checks out the base branch by default ref: refs/pull/${{ github.event.pull_request.number }}/merge diff --git a/.github/workflows/periodic-merge-24h.yml b/.github/workflows/periodic-merge-24h.yml index 6adada59c5a5..d9ad593618ae 100644 --- a/.github/workflows/periodic-merge-24h.yml +++ b/.github/workflows/periodic-merge-24h.yml @@ -41,7 +41,7 @@ jobs: into: staging-23.11 name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }} steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }} uses: devmasx/merge-branch@854d3ac71ed1e9deb668e0074781b81fdd6e771f # 1.4.0 diff --git a/.github/workflows/periodic-merge-6h.yml b/.github/workflows/periodic-merge-6h.yml index 6f188ee28d17..a3131e802534 100644 --- a/.github/workflows/periodic-merge-6h.yml +++ b/.github/workflows/periodic-merge-6h.yml @@ -39,7 +39,7 @@ jobs: into: staging name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }} steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: ${{ matrix.pairs.from }} → ${{ matrix.pairs.into }} uses: devmasx/merge-branch@854d3ac71ed1e9deb668e0074781b81fdd6e771f # 1.4.0 diff --git a/.github/workflows/update-terraform-providers.yml b/.github/workflows/update-terraform-providers.yml index 9b7ec5cc59b0..36d84d617dc4 100644 --- a/.github/workflows/update-terraform-providers.yml +++ b/.github/workflows/update-terraform-providers.yml @@ -16,7 +16,7 @@ jobs: if: github.repository_owner == 'NixOS' && github.ref == 'refs/heads/master' # ensure workflow_dispatch only runs on master runs-on: ubuntu-latest steps: - - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - uses: cachix/install-nix-action@8887e596b4ee1134dae06b98d573bd674693f47c # v26 with: nix_path: nixpkgs=channel:nixpkgs-unstable @@ -46,7 +46,7 @@ jobs: run: | git clean -f - name: create PR - uses: peter-evans/create-pull-request@70a41aba780001da0a30141984ae2a0c95d8704e # v6.0.2 + uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83 # v6.0.4 with: body: | Automatic update by [update-terraform-providers](https://github.com/NixOS/nixpkgs/blob/master/.github/workflows/update-terraform-providers.yml) action. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b1a12362f39..8d54124acfd7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -512,6 +512,7 @@ To get a sense for what changes are considered mass rebuilds, see [previously me - Check for unnecessary whitespace with `git diff --check` before committing. - If you have commits `pkg-name: oh, forgot to insert whitespace`: squash commits in this case. Use `git rebase -i`. + See [Squashing Commits](https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History#_squashing) for additional information. - For consistency, there should not be a period at the end of the commit message's summary line (the first line of the commit message). diff --git a/doc/README.md b/doc/README.md index 1e9305d040ba..96ac107fc180 100644 --- a/doc/README.md +++ b/doc/README.md @@ -62,7 +62,7 @@ Allow linking arbitrary place in the text (e.g. individual list items, sentences They are defined using a hybrid of the link syntax with the attributes syntax known from headings, called [bracketed spans](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/bracketed_spans.md): ```markdown -- []{#ssec-gnome-hooks-glib} `glib` setup hook will populate `GSETTINGS_SCHEMAS_PATH` and then `wrapGAppsHook` will prepend it to `XDG_DATA_DIRS`. +- []{#ssec-gnome-hooks-glib} `glib` setup hook will populate `GSETTINGS_SCHEMAS_PATH` and then `wrapGApps*` hook will prepend it to `XDG_DATA_DIRS`. ``` #### Automatic links @@ -106,12 +106,12 @@ This is a warning The following are supported: -- [`caution`](https://tdg.docbook.org/tdg/5.0/caution.html) -- [`important`](https://tdg.docbook.org/tdg/5.0/important.html) -- [`note`](https://tdg.docbook.org/tdg/5.0/note.html) -- [`tip`](https://tdg.docbook.org/tdg/5.0/tip.html) -- [`warning`](https://tdg.docbook.org/tdg/5.0/warning.html) -- [`example`](https://tdg.docbook.org/tdg/5.0/example.html) +- `caution` +- `important` +- `note` +- `tip` +- `warning` +- `example` Example admonitions require a title to work. If you don't provide one, the manual won't be built. diff --git a/doc/build-helpers/special/fhs-environments.section.md b/doc/build-helpers/special/fhs-environments.section.md index 8145fbd730f7..b87bb9727857 100644 --- a/doc/build-helpers/special/fhs-environments.section.md +++ b/doc/build-helpers/special/fhs-environments.section.md @@ -6,7 +6,11 @@ It uses Linux' namespaces feature to create temporary lightweight environments w Accepted arguments are: - `name` - The name of the environment and the wrapper executable. + The name of the environment, and the wrapper executable if `pname` is unset. +- `pname` + The pname of the environment and the wrapper executable. +- `version` + The version of the environment. - `targetPkgs` Packages to be installed for the main host's architecture (i.e. x86_64 on x86_64 installations). Along with libraries binaries are also installed. - `multiPkgs` @@ -53,4 +57,4 @@ You can create a simple environment using a `shell.nix` like this: Running `nix-shell` on it would drop you into a shell inside an FHS env where those libraries and binaries are available in FHS-compliant paths. Applications that expect an FHS structure (i.e. proprietary binaries) can run inside this environment without modification. You can build a wrapper by running your binary in `runScript`, e.g. `./bin/start.sh`. Relative paths work as expected. -Additionally, the FHS builder links all relocated gsettings-schemas (the glib setup-hook moves them to `share/gsettings-schemas/${name}/glib-2.0/schemas`) to their standard FHS location. This means you don't need to wrap binaries with `wrapGAppsHook`. +Additionally, the FHS builder links all relocated gsettings-schemas (the glib setup-hook moves them to `share/gsettings-schemas/${name}/glib-2.0/schemas`) to their standard FHS location. This means you don't need to wrap binaries with `wrapGApps*` hook. diff --git a/doc/default.nix b/doc/default.nix index 76aba1a03eaf..ca4091dc222c 100644 --- a/doc/default.nix +++ b/doc/default.nix @@ -111,7 +111,7 @@ in pkgs.stdenv.mkDerivation { ${lib-docs}/index.md \ > ./functions/library.md substitute ./manual.md.in ./manual.md \ - --replace '@MANUAL_VERSION@' '${pkgs.lib.version}' + --replace-fail '@MANUAL_VERSION@' '${pkgs.lib.version}' mkdir -p out/media diff --git a/doc/hooks/zig.section.md b/doc/hooks/zig.section.md index 1a09491649d7..8bef293769e5 100644 --- a/doc/hooks/zig.section.md +++ b/doc/hooks/zig.section.md @@ -9,14 +9,14 @@ In Nixpkgs, `zig.hook` overrides the default build, check and install phases. ```nix { lib , stdenv -, zig_0_11 +, zig }: stdenv.mkDerivation { # . . . nativeBuildInputs = [ - zig_0_11.hook + zig.hook ]; zigBuildFlags = [ "-Dman-pages=true" ]; diff --git a/doc/languages-frameworks/cuda.section.md b/doc/languages-frameworks/cuda.section.md index 9791018c7f5f..1b2005bb1edd 100644 --- a/doc/languages-frameworks/cuda.section.md +++ b/doc/languages-frameworks/cuda.section.md @@ -148,4 +148,4 @@ All new projects should use the CUDA redistributables available in [`cudaPackage | Find libraries | `configurePhase` | Missing dependency on a `dev` output | Add the missing dependency | The `dev` output typically contain CMake configuration files | | Find libraries | `buildPhase` or `patchelf` | Missing dependency on a `lib` or `static` output | Add the missing dependency | The `lib` or `static` output typically contain the libraries | -In the scenario you are unable to run the resulting binary: this is arguably the most complicated as it could be any combination of the previous reasons. This type of failure typically occurs when a library attempts to load or open a library it depends on that it does not declare in its `DT_NEEDED` section. As a first step, ensure that dependencies are patched with [`cudaPackages.autoAddDriverRunpath`](https://search.nixos.org/packages?channel=unstable&type=packages&query=cudaPackages.autoAddDriverRunpath). Failing that, try running the application with [`nixGL`](https://github.com/guibou/nixGL) or a similar wrapper tool. If that works, it likely means that the application is attempting to load a library that is not in the `RPATH` or `RUNPATH` of the binary. +In the scenario you are unable to run the resulting binary: this is arguably the most complicated as it could be any combination of the previous reasons. This type of failure typically occurs when a library attempts to load or open a library it depends on that it does not declare in its `DT_NEEDED` section. As a first step, ensure that dependencies are patched with [`autoAddDriverRunpath`](https://search.nixos.org/packages?channel=unstable&type=packages&query=autoAddDriverRunpath). Failing that, try running the application with [`nixGL`](https://github.com/guibou/nixGL) or a similar wrapper tool. If that works, it likely means that the application is attempting to load a library that is not in the `RPATH` or `RUNPATH` of the binary. diff --git a/doc/languages-frameworks/gnome.section.md b/doc/languages-frameworks/gnome.section.md index e158cea0e512..743327770891 100644 --- a/doc/languages-frameworks/gnome.section.md +++ b/doc/languages-frameworks/gnome.section.md @@ -8,7 +8,7 @@ Programs in the GNOME universe are written in various languages but they all use [GSettings](https://developer.gnome.org/gio/stable/GSettings.html) API is often used for storing settings. GSettings schemas are required, to know the type and other metadata of the stored values. GLib looks for `glib-2.0/schemas/gschemas.compiled` files inside the directories of `XDG_DATA_DIRS`. -On Linux, GSettings API is implemented using [dconf](https://wiki.gnome.org/Projects/dconf) backend. You will need to add `dconf` [GIO module](#ssec-gnome-gio-modules) to `GIO_EXTRA_MODULES` variable, otherwise the `memory` backend will be used and the saved settings will not be persistent. +On Linux, GSettings API is implemented using [dconf](https://gitlab.gnome.org/GNOME/dconf) backend. You will need to add `dconf` [GIO module](#ssec-gnome-gio-modules) to `GIO_EXTRA_MODULES` variable, otherwise the `memory` backend will be used and the saved settings will not be persistent. Last you will need the dconf database D-Bus service itself. You can enable it using `programs.dconf.enable`. @@ -76,13 +76,13 @@ Previously, a GTK theme needed to be in `XDG_DATA_DIRS`. This is no longer neces ### GObject introspection typelibs {#ssec-gnome-typelibs} -[GObject introspection](https://wiki.gnome.org/Projects/GObjectIntrospection) allows applications to use C libraries in other languages easily. It does this through `typelib` files searched in `GI_TYPELIB_PATH`. +[GObject introspection](https://gitlab.gnome.org/GNOME/gobject-introspection) allows applications to use C libraries in other languages easily. It does this through `typelib` files searched in `GI_TYPELIB_PATH`. ### Various plug-ins {#ssec-gnome-plugins} -If your application uses [GStreamer](https://gstreamer.freedesktop.org/) or [Grilo](https://wiki.gnome.org/Projects/Grilo), you should set `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH`, respectively. +If your application uses [GStreamer](https://gstreamer.freedesktop.org/) or [Grilo](https://gitlab.gnome.org/GNOME/grilo), you should set `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH`, respectively. -## Onto `wrapGAppsHook` {#ssec-gnome-hooks} +## Onto `wrapGApps*` hooks {#ssec-gnome-hooks} Given the requirements above, the package expression would become messy quickly: @@ -102,27 +102,29 @@ Given the requirements above, the package expression would become messy quickly: } ``` -Fortunately, there is [`wrapGAppsHook`]{#ssec-gnome-hooks-wrapgappshook}. It works in conjunction with other setup hooks that populate environment variables, and it will then wrap all executables in `bin` and `libexec` directories using said variables. For convenience, it also adds `dconf.lib` for a GIO module implementing a GSettings backend using `dconf`, `gtk3` for GSettings schemas, and `librsvg` for GdkPixbuf loader to the closure. +Fortunately, we have a [family of hooks]{#ssec-gnome-hooks-wrapgappshook} that automate this. They work in conjunction with other setup hooks that populate environment variables, and will then wrap all executables in `bin` and `libexec` directories using said variables. -There is also [`wrapGAppsHook4`]{#ssec-gnome-hooks-wrapgappshook4}, which replaces GTK 3 with GTK 4. Instead of `wrapGAppsHook`, this should be used for all GTK4 applications. +- [`wrapGAppsHook3`]{#ssec-gnome-hooks-wrapgappshook3} for GTK 3 apps. For convenience, it also adds `dconf.lib` for a GIO module implementing a GSettings backend using `dconf`, `gtk3` for GSettings schemas, and `librsvg` for GdkPixbuf loader to the closure. +- [`wrapGAppsHook4`]{#ssec-gnome-hooks-wrapgappshook4} for GTK 4 apps. Same as `wrapGAppsHook3` but replaces `gtk3` with `gtk4`. +- [`wrapGAppsNoGuiHook`]{#ssec-gnome-hooks-wrapgappsnoguihook} for programs without a graphical interface. Same as the above but does not bring `gtk3` and `librsvg` into the closure. -In case you are packaging a program without a graphical interface, you might want to use [`wrapGAppsNoGuiHook`]{#ssec-gnome-hooks-wrapgappsnoguihook}, which runs the same script as `wrapGAppsHook` but does not bring `gtk3` and `librsvg` into the closure. +The hooks do the the following: -- `wrapGAppsHook` itself will add the package’s `share` directory to `XDG_DATA_DIRS`. +- `wrapGApps*` hook itself will add the package’s `share` directory to `XDG_DATA_DIRS`. -- []{#ssec-gnome-hooks-glib} `glib` setup hook will populate `GSETTINGS_SCHEMAS_PATH` and then `wrapGAppsHook` will prepend it to `XDG_DATA_DIRS`. +- []{#ssec-gnome-hooks-glib} `glib` setup hook will populate `GSETTINGS_SCHEMAS_PATH` and then `wrapGApps*` hook will prepend it to `XDG_DATA_DIRS`. -- []{#ssec-gnome-hooks-gdk-pixbuf} `gdk-pixbuf` setup hook will populate `GDK_PIXBUF_MODULE_FILE` with the path to biggest `loaders.cache` file from the dependencies containing [GdkPixbuf loaders](#ssec-gnome-gdk-pixbuf-loaders). This works fine when there are only two packages containing loaders (`gdk-pixbuf` and e.g. `librsvg`) – it will choose the second one, reasonably expecting that it will be bigger since it describes extra loader in addition to the default ones. But when there are more than two loader packages, this logic will break. One possible solution would be constructing a custom cache file for each package containing a program like `services/x11/gdk-pixbuf.nix` NixOS module does. `wrapGAppsHook` copies the `GDK_PIXBUF_MODULE_FILE` environment variable into the produced wrapper. +- []{#ssec-gnome-hooks-gdk-pixbuf} `gdk-pixbuf` setup hook will populate `GDK_PIXBUF_MODULE_FILE` with the path to biggest `loaders.cache` file from the dependencies containing [GdkPixbuf loaders](#ssec-gnome-gdk-pixbuf-loaders). This works fine when there are only two packages containing loaders (`gdk-pixbuf` and e.g. `librsvg`) – it will choose the second one, reasonably expecting that it will be bigger since it describes extra loader in addition to the default ones. But when there are more than two loader packages, this logic will break. One possible solution would be constructing a custom cache file for each package containing a program like `services/x11/gdk-pixbuf.nix` NixOS module does. `wrapGApps*` hook copies the `GDK_PIXBUF_MODULE_FILE` environment variable into the produced wrapper. - []{#ssec-gnome-hooks-gtk-drop-icon-theme-cache} One of `gtk3`’s setup hooks will remove `icon-theme.cache` files from package’s icon theme directories to avoid conflicts. Icon theme packages should prevent this with `dontDropIconThemeCache = true;`. -- []{#ssec-gnome-hooks-dconf} `dconf.lib` is a dependency of `wrapGAppsHook`, which then also adds it to the `GIO_EXTRA_MODULES` variable. +- []{#ssec-gnome-hooks-dconf} `dconf.lib` is a dependency of `wrapGApps*` hook, which then also adds it to the `GIO_EXTRA_MODULES` variable. - []{#ssec-gnome-hooks-hicolor-icon-theme} `hicolor-icon-theme`’s setup hook will add icon themes to `XDG_ICON_DIRS`. -- []{#ssec-gnome-hooks-gobject-introspection} `gobject-introspection` setup hook populates `GI_TYPELIB_PATH` variable with `lib/girepository-1.0` directories of dependencies, which is then added to wrapper by `wrapGAppsHook`. It also adds `share` directories of dependencies to `XDG_DATA_DIRS`, which is intended to promote GIR files but it also [pollutes the closures](https://github.com/NixOS/nixpkgs/issues/32790) of packages using `wrapGAppsHook`. +- []{#ssec-gnome-hooks-gobject-introspection} `gobject-introspection` setup hook populates `GI_TYPELIB_PATH` variable with `lib/girepository-1.0` directories of dependencies, which is then added to wrapper by `wrapGApps*` hook. It also adds `share` directories of dependencies to `XDG_DATA_DIRS`, which is intended to promote GIR files but it also [pollutes the closures](https://github.com/NixOS/nixpkgs/issues/32790) of packages using `wrapGApps*` hook. -- []{#ssec-gnome-hooks-gst-grl-plugins} Setup hooks of `gst_all_1.gstreamer` and `grilo` will populate the `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH` variables, respectively, which will then be added to the wrapper by `wrapGAppsHook`. +- []{#ssec-gnome-hooks-gst-grl-plugins} Setup hooks of `gst_all_1.gstreamer` and `grilo` will populate the `GST_PLUGIN_SYSTEM_PATH_1_0` and `GRL_PLUGIN_PATH` variables, respectively, which will then be added to the wrapper by `wrapGApps*` hook. You can also pass additional arguments to `makeWrapper` using `gappsWrapperArgs` in `preFixup` hook: @@ -147,15 +149,15 @@ Most GNOME package offer [`updateScript`](#var-passthru-updateScript), it is the ### `GLib-GIO-ERROR **: 06:04:50.903: No GSettings schemas are installed on the system` {#ssec-gnome-common-issues-no-schemas} -There are no schemas available in `XDG_DATA_DIRS`. Temporarily add a random package containing schemas like `gsettings-desktop-schemas` to `buildInputs`. [`glib`](#ssec-gnome-hooks-glib) and [`wrapGAppsHook`](#ssec-gnome-hooks-wrapgappshook) setup hooks will take care of making the schemas available to application and you will see the actual missing schemas with the [next error](#ssec-gnome-common-issues-missing-schema). Or you can try looking through the source code for the actual schemas used. +There are no schemas available in `XDG_DATA_DIRS`. Temporarily add a random package containing schemas like `gsettings-desktop-schemas` to `buildInputs`. [`glib`](#ssec-gnome-hooks-glib) and [`wrapGApps*`](#ssec-gnome-hooks-wrapgappshook) setup hooks will take care of making the schemas available to application and you will see the actual missing schemas with the [next error](#ssec-gnome-common-issues-missing-schema). Or you can try looking through the source code for the actual schemas used. ### `GLib-GIO-ERROR **: 06:04:50.903: Settings schema ‘org.gnome.foo’ is not installed` {#ssec-gnome-common-issues-missing-schema} Package is missing some GSettings schemas. You can find out the package containing the schema with `nix-locate org.gnome.foo.gschema.xml` and let the hooks handle the wrapping as [above](#ssec-gnome-common-issues-no-schemas). -### When using `wrapGAppsHook` with special derivers you can end up with double wrapped binaries. {#ssec-gnome-common-issues-double-wrapped} +### When using `wrapGApps*` hook with special derivers you can end up with double wrapped binaries. {#ssec-gnome-common-issues-double-wrapped} -This is because derivers like `python.pkgs.buildPythonApplication` or `qt5.mkDerivation` have setup-hooks automatically added that produce wrappers with makeWrapper. The simplest way to workaround that is to disable the `wrapGAppsHook` automatic wrapping with `dontWrapGApps = true;` and pass the arguments it intended to pass to makeWrapper to another. +This is because derivers like `python.pkgs.buildPythonApplication` or `qt5.mkDerivation` have setup-hooks automatically added that produce wrappers with makeWrapper. The simplest way to workaround that is to disable the `wrapGApps*` hook automatic wrapping with `dontWrapGApps = true;` and pass the arguments it intended to pass to makeWrapper to another. In the case of a Python application it could look like: @@ -165,7 +167,7 @@ python3.pkgs.buildPythonApplication { version = "3.32.2"; nativeBuildInputs = [ - wrapGAppsHook + wrapGAppsHook3 gobject-introspection # ... ]; @@ -187,7 +189,7 @@ mkDerivation { version = "3.47.0"; nativeBuildInputs = [ - wrapGAppsHook + wrapGAppsHook3 qmake # ... ]; diff --git a/doc/languages-frameworks/pkg-config.section.md b/doc/languages-frameworks/pkg-config.section.md index e5a2b85b6576..0b25396314cb 100644 --- a/doc/languages-frameworks/pkg-config.section.md +++ b/doc/languages-frameworks/pkg-config.section.md @@ -7,10 +7,11 @@ Nixpkgs provides a couple of facilities for working with this tool. ## Writing packages providing pkg-config modules {#pkg-config-writing-packages} Packages should set `meta.pkgConfigModules` with the list of package config modules they provide. -They should also use `testers.testMetaPkgConfig` to check that the final built package matches that list. +They should also use `testers.hasPkgConfigModules` to check that the final built package matches that list, +and optionally check that the pkgconf modules' version metadata matches the derivation's. Additionally, the [`validatePkgConfig` setup hook](https://nixos.org/manual/nixpkgs/stable/#validatepkgconfig), will do extra checks on to-be-installed pkg-config modules. -A good example of all these things is zlib: +A good example of all these things is miniz: ```nix { pkg-config, testers, ... }: @@ -20,11 +21,14 @@ stdenv.mkDerivation (finalAttrs: { nativeBuildInputs = [ pkg-config validatePkgConfig ]; - passthru.tests.pkg-config = testers.testMetaPkgConfig finalAttrs.finalPackage; + passthru.tests.pkg-config = testers.hasPkgConfigModules { + package = finalAttrs.finalPackage; + versionCheck = true; + }; meta = { /* ... */ - pkgConfigModules = [ "zlib" ]; + pkgConfigModules = [ "miniz" ]; }; }) ``` diff --git a/doc/languages-frameworks/python.section.md b/doc/languages-frameworks/python.section.md index f325af0641f6..6fcae4b6520d 100644 --- a/doc/languages-frameworks/python.section.md +++ b/doc/languages-frameworks/python.section.md @@ -497,40 +497,6 @@ are used in [`buildPythonPackage`](#buildpythonpackage-function). with the `pipInstallHook`. - `unittestCheckHook` will run tests with `python -m unittest discover`. See [example usage](#using-unittestcheckhook). -### Development mode {#development-mode} - -Development or editable mode is supported. To develop Python packages -[`buildPythonPackage`](#buildpythonpackage-function) has additional logic inside `shellPhase` to run `pip -install -e . --prefix $TMPDIR/`for the package. - -Warning: `shellPhase` is executed only if `setup.py` exists. - -Given a `default.nix`: - -```nix -with import {}; - -python3Packages.buildPythonPackage { - name = "myproject"; - buildInputs = with python3Packages; [ pyramid ]; - - src = ./.; -} -``` - -Running `nix-shell` with no arguments should give you the environment in which -the package would be built with `nix-build`. - -Shortcut to setup environments with C headers/libraries and Python packages: - -```shell -nix-shell -p python3Packages.pyramid zlib libjpeg git -``` - -::: {.note} -There is a boolean value `lib.inNixShell` set to `true` if nix-shell is invoked. -::: - ## User Guide {#user-guide} ### Using Python {#using-python} @@ -867,8 +833,7 @@ Above, we were mostly just focused on use cases and what to do to get started creating working Python environments in nix. Now that you know the basics to be up and running, it is time to take a step -back and take a deeper look at how Python packages are packaged on Nix. Then, -we will look at how you can use development mode with your code. +back and take a deeper look at how Python packages are packaged on Nix. #### Python library packages in Nixpkgs {#python-library-packages-in-nixpkgs} @@ -913,7 +878,6 @@ buildPythonPackage rec { homepage = "https://github.com/pytoolz/toolz"; description = "List processing tools and functional utilities"; license = lib.licenses.bsd3; - maintainers = with lib.maintainers; [ fridh ]; }; } ``` @@ -1048,7 +1012,6 @@ buildPythonPackage rec { homepage = "https://github.com/ContinuumIO/datashape"; description = "A data description language"; license = lib.licenses.bsd2; - maintainers = with lib.maintainers; [ fridh ]; }; } ``` @@ -1169,7 +1132,6 @@ buildPythonPackage rec { description = "A pythonic wrapper around FFTW, the FFT library, presenting a unified interface for all the supported transforms"; homepage = "http://hgomersall.github.com/pyFFTW"; license = with lib.licenses; [ bsd2 bsd3 ]; - maintainers = with lib.maintainers; [ fridh ]; }; } ``` @@ -1481,45 +1443,6 @@ documentation source root. The hook is also available to packages outside the python ecosystem by referencing it using `sphinxHook` from top-level. -### Develop local package {#develop-local-package} - -As a Python developer you're likely aware of [development mode](http://setuptools.readthedocs.io/en/latest/setuptools.html#development-mode) -(`python setup.py develop`); instead of installing the package this command -creates a special link to the project code. That way, you can run updated code -without having to reinstall after each and every change you make. Development -mode is also available. Let's see how you can use it. - -In the previous Nix expression the source was fetched from a url. We can also -refer to a local source instead using `src = ./path/to/source/tree;` - -If we create a `shell.nix` file which calls [`buildPythonPackage`](#buildpythonpackage-function), and if `src` -is a local source, and if the local source has a `setup.py`, then development -mode is activated. - -In the following example, we create a simple environment that has a Python 3.11 -version of our package in it, as well as its dependencies and other packages we -like to have in the environment, all specified with `dependencies`. - -```nix -with import {}; -with python311Packages; - -buildPythonPackage rec { - name = "mypackage"; - src = ./path/to/package/source; - dependencies = [ - pytest - numpy - ]; - propagatedBuildInputs = [ - pkgs.libsndfile - ]; -} -``` - -It is important to note that due to how development mode is implemented on Nix -it is not possible to have multiple packages simultaneously in development mode. - ### Organising your packages {#organising-your-packages} So far we discussed how you can use Python on Nix, and how you can develop with @@ -1568,7 +1491,6 @@ buildPythonPackage rec { homepage = "https://github.com/pytoolz/toolz/"; description = "List processing tools and functional utilities"; license = lib.licenses.bsd3; - maintainers = with lib.maintainers; [ fridh ]; }; } ``` diff --git a/doc/using/configuration.chapter.md b/doc/using/configuration.chapter.md index 252d255de829..05a8fa5517cc 100644 --- a/doc/using/configuration.chapter.md +++ b/doc/using/configuration.chapter.md @@ -1,6 +1,7 @@ # Global configuration {#chap-packageconfig} -Nix comes with certain defaults about what packages can and cannot be installed, based on a package's metadata. By default, Nix will prevent installation if any of the following criteria are true: +Nix comes with certain defaults about which packages can and cannot be installed, based on a package's metadata. +By default, Nix will prevent installation if any of the following criteria are true: - The package is thought to be broken, and has had its `meta.broken` set to `true`. @@ -10,23 +11,14 @@ Nix comes with certain defaults about what packages can and cannot be installed, - The package has known security vulnerabilities but has not or can not be updated for some reason, and a list of issues has been entered in to the package's `meta.knownVulnerabilities`. -Note that all this is checked during evaluation already, and the check includes any package that is evaluated. In particular, all build-time dependencies are checked. `nix-env -qa` will (attempt to) hide any packages that would be refused. +Each of these criteria can be altered in the Nixpkgs configuration. -Each of these criteria can be altered in the nixpkgs configuration. +:::{.note} +All this is checked during evaluation already, and the check includes any package that is evaluated. +In particular, all build-time dependencies are checked. +::: -The nixpkgs configuration for a NixOS system is set in the `configuration.nix`, as in the following example: - -```nix -{ - nixpkgs.config = { - allowUnfree = true; - }; -} -``` - -However, this does not allow unfree software for individual users. Their configurations are managed separately. - -A user's nixpkgs configuration is stored in a user-specific configuration file located at `~/.config/nixpkgs/config.nix`. For example: +A user's Nixpkgs configuration is stored in a user-specific configuration file located at `~/.config/nixpkgs/config.nix`. For example: ```nix { @@ -34,7 +26,10 @@ A user's nixpkgs configuration is stored in a user-specific configuration file l } ``` -Note that we are not able to test or build unfree software on Hydra due to policy. Most unfree licenses prohibit us from either executing or distributing the software. +:::{.caution} +Unfree software is not tested or built in Nixpkgs continuous integration, and therefore not cached. +Most unfree licenses prohibit either executing or distributing the software. +::: ## Installing broken packages {#sec-allow-broken} diff --git a/lib/attrsets.nix b/lib/attrsets.nix index 49d311ed37b3..83f8d0f34186 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -5,7 +5,7 @@ let inherit (builtins) head length; - inherit (lib.trivial) mergeAttrs warn; + inherit (lib.trivial) isInOldestRelease mergeAttrs warn warnIf; inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName; inherit (lib.lists) foldr foldl' concatMap elemAt all partition groupBy take foldl; in @@ -885,15 +885,15 @@ rec { # Type ``` - cartesianProductOfSets :: AttrSet -> [AttrSet] + cartesianProduct :: AttrSet -> [AttrSet] ``` # Examples :::{.example} - ## `lib.attrsets.cartesianProductOfSets` usage example + ## `lib.attrsets.cartesianProduct` usage example ```nix - cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; } + cartesianProduct { a = [ 1 2 ]; b = [ 10 20 ]; } => [ { a = 1; b = 10; } { a = 1; b = 20; } @@ -904,7 +904,7 @@ rec { ::: */ - cartesianProductOfSets = + cartesianProduct = attrsOfLists: foldl' (listOfAttrs: attrName: concatMap (attrs: @@ -913,6 +913,40 @@ rec { ) [{}] (attrNames attrsOfLists); + /** + Return the result of function f applied to the cartesian product of attribute set value combinations. + Equivalent to using cartesianProduct followed by map. + + # Inputs + + `f` + + : A function, given an attribute set, it returns a new value. + + `attrsOfLists` + + : Attribute set with attributes that are lists of values + + # Type + + ``` + mapCartesianProduct :: (AttrSet -> a) -> AttrSet -> [a] + ``` + + # Examples + :::{.example} + ## `lib.attrsets.mapCartesianProduct` usage example + + ```nix + mapCartesianProduct ({a, b}: "${a}-${b}") { a = [ "1" "2" ]; b = [ "3" "4" ]; } + => [ "1-3" "1-4" "2-3" "2-4" ] + ``` + + ::: + + */ + mapCartesianProduct = f: attrsOfLists: map f (cartesianProduct attrsOfLists); + /** Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`. @@ -1999,4 +2033,8 @@ rec { # DEPRECATED zip = warn "lib.zip is a deprecated alias of lib.zipAttrsWith." zipAttrsWith; + + # DEPRECATED + cartesianProductOfSets = warnIf (isInOldestRelease 2405) + "lib.cartesianProductOfSets is a deprecated alias of lib.cartesianProduct." cartesianProduct; } diff --git a/lib/default.nix b/lib/default.nix index 21e4bab2b942..d5d47defb8e6 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -47,7 +47,7 @@ let # misc asserts = callLibs ./asserts.nix; debug = callLibs ./debug.nix; - misc = callLibs ./deprecated.nix; + misc = callLibs ./deprecated/misc.nix; # domain-specific fetchers = callLibs ./fetchers.nix; @@ -86,10 +86,10 @@ let zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil recursiveUpdate matchAttrs mergeAttrsList overrideExisting showAttrPath getOutput getBin getLib getDev getMan chooseDevOutputs zipWithNames zip - recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets - updateManyAttrsByPath; + recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets + mapCartesianProduct updateManyAttrsByPath; inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 - concatMap flatten remove findSingle findFirst any all count + ifilter0 concatMap flatten remove findSingle findFirst any all count optional optionals toList range replicate partition zipListsWith zipLists reverseList listDfs toposort sort sortOn naturalSort compareLists take drop sublist last init crossLists unique allUnique intersectLists diff --git a/lib/deprecated/README.md b/lib/deprecated/README.md new file mode 100644 index 000000000000..afeb34d449f5 --- /dev/null +++ b/lib/deprecated/README.md @@ -0,0 +1,11 @@ + +# lib/deprecated + +Do not add any new functions to this directory. + +This directory contains the `lib.misc` sublibrary, which - as a location - is deprecated. +Furthermore, some of the functions inside are of *dubious* utility, and should perhaps be avoided, +while some functions *may still be needed*. + +This directory does not play a role in the deprecation process for library functions. +They should be deprecated in place, by putting a `lib.warn` or `lib.warnIf` call around the function. diff --git a/lib/deprecated.nix b/lib/deprecated/misc.nix similarity index 100% rename from lib/deprecated.nix rename to lib/deprecated/misc.nix diff --git a/lib/fileset/default.nix b/lib/fileset/default.nix index ce9afc796a3f..e29f30251c69 100644 --- a/lib/fileset/default.nix +++ b/lib/fileset/default.nix @@ -1,5 +1,5 @@ /* - + []{#sec-fileset} The [`lib.fileset`](#sec-functions-library-fileset) library allows you to work with _file sets_. diff --git a/lib/gvariant.nix b/lib/gvariant.nix index 708213224d3e..54aa4ea80571 100644 --- a/lib/gvariant.nix +++ b/lib/gvariant.nix @@ -53,6 +53,53 @@ rec { inherit type isGVariant; + intConstructors = [ + { + name = "mkInt32"; + type = type.int32; + min = -2147483648; + max = 2147483647; + } + { + name = "mkUint32"; + type = type.uint32; + min = 0; + max = 4294967295; + } + { + name = "mkInt64"; + type = type.int64; + # Nix does not support such large numbers. + min = null; + max = null; + } + { + name = "mkUint64"; + type = type.uint64; + min = 0; + # Nix does not support such large numbers. + max = null; + } + { + name = "mkInt16"; + type = type.int16; + min = -32768; + max = 32767; + } + { + name = "mkUint16"; + type = type.uint16; + min = 0; + max = 65535; + } + { + name = "mkUchar"; + type = type.uchar; + min = 0; + max = 255; + } + ]; + /* Returns the GVariant value that most closely matches the given Nix value. If no GVariant value can be found unambiguously then error is thrown. @@ -70,8 +117,20 @@ rec { mkArray v else if isGVariant v then v + else if builtins.isInt v then + let + validConstructors = builtins.filter ({ min, max, ... }: (min == null || min <= v) && (max == null || v <= max)) intConstructors; + in + throw '' + The GVariant type for number “${builtins.toString v}” is unclear. + Please wrap the value with one of the following, depending on the value type in GSettings schema: + + ${lib.concatMapStringsSep "\n" ({ name, type, ...}: "- `lib.gvariant.${name}` for `${type}`") validConstructors} + '' + else if builtins.isAttrs v then + throw "Cannot construct GVariant value from an attribute set. If you want to construct a dictionary, you will need to create an array containing items constructed with `lib.gvariant.mkDictionaryEntry`." else - throw "The GVariant type of ${v} can't be inferred."; + throw "The GVariant type of “${builtins.typeOf v}” can't be inferred."; /* Returns the GVariant array from the given type of the elements and a Nix list. diff --git a/lib/licenses.nix b/lib/licenses.nix index 035907ed921e..7d2a22bc25a4 100644 --- a/lib/licenses.nix +++ b/lib/licenses.nix @@ -632,6 +632,11 @@ in mkLicense lset) ({ url = "https://old.calculate-linux.org/packages/licenses/iASL"; }; + icu = { + spdxId = "ICU"; + fullName = "ICU"; + }; + ijg = { spdxId = "IJG"; fullName = "Independent JPEG Group License"; @@ -1168,6 +1173,11 @@ in mkLicense lset) ({ # channel and NixOS images. }; + unicode-30 = { + spdxId = "Unicode-3.0"; + fullName = "Unicode License v3"; + }; + unicode-dfs-2015 = { spdxId = "Unicode-DFS-2015"; fullName = "Unicode License Agreement - Data Files and Software (2015)"; diff --git a/lib/lists.nix b/lib/lists.nix index c162f921280d..ca436d7a9c94 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -4,7 +4,7 @@ { lib }: let inherit (lib.strings) toInt; - inherit (lib.trivial) compare min id warn; + inherit (lib.trivial) compare min id warn pipe; inherit (lib.attrsets) mapAttrs; in rec { @@ -333,6 +333,54 @@ rec { */ imap1 = f: list: genList (n: f (n + 1) (elemAt list n)) (length list); + /** + Filter a list for elements that satisfy a predicate function. + The predicate function is called with both the index and value for each element. + It must return `true`/`false` to include/exclude a given element in the result. + This function is strict in the result of the predicate function for each element. + This function has O(n) complexity. + + Also see [`builtins.filter`](https://nixos.org/manual/nix/stable/language/builtins.html#builtins-filter) (available as `lib.lists.filter`), + which can be used instead when the index isn't needed. + + # Inputs + + `ipred` + + : The predicate function, it takes two arguments: + - 1. (int): the index of the element. + - 2. (a): the value of the element. + + It must return `true`/`false` to include/exclude a given element from the result. + + `list` + + : The list to filter using the predicate. + + # Type + ``` + ifilter0 :: (int -> a -> bool) -> [a] -> [a] + ``` + + # Examples + :::{.example} + ## `lib.lists.ifilter0` usage example + + ```nix + ifilter0 (i: v: i == 0 || v > 2) [ 1 2 3 ] + => [ 1 3 ] + ``` + ::: + */ + ifilter0 = + ipred: + input: + map (idx: elemAt input idx) ( + filter (idx: ipred idx (elemAt input idx)) ( + genList (x: x) (length input) + ) + ); + /** Map and concatenate the result. @@ -1688,16 +1736,32 @@ rec { ## `lib.lists.crossLists` usage example ```nix - crossLists (x:y: "${toString x}${toString y}") [[1 2] [3 4]] + crossLists (x: y: "${toString x}${toString y}") [[1 2] [3 4]] => [ "13" "14" "23" "24" ] ``` + The following function call is equivalent to the one deprecated above: + + ```nix + mapCartesianProduct (x: "${toString x.a}${toString x.b}") { a = [1 2]; b = [3 4]; } + => [ "13" "14" "23" "24" ] + ``` ::: */ crossLists = warn - "lib.crossLists is deprecated, use lib.cartesianProductOfSets instead." - (f: foldl (fs: args: concatMap (f: map f args) fs) [f]); + ''lib.crossLists is deprecated, use lib.mapCartesianProduct instead. + For example, the following function call: + + nix-repl> lib.crossLists (x: y: x+y) [[1 2] [3 4]] + [ 4 5 5 6 ] + + Can now be replaced by the following one: + + nix-repl> lib.mapCartesianProduct ({x,y}: x+y) { x = [1 2]; y = [3 4]; } + [ 4 5 5 6 ] + '' + (f: foldl (fs: args: concatMap (f: map f args) fs) [f]); /** Remove duplicate elements from the `list`. O(n^2) complexity. diff --git a/lib/systems/doubles.nix b/lib/systems/doubles.nix index 13f029ee1f40..b4cd5acfcc5b 100644 --- a/lib/systems/doubles.nix +++ b/lib/systems/doubles.nix @@ -13,7 +13,7 @@ let "x86_64-darwin" "i686-darwin" "aarch64-darwin" "armv7a-darwin" # FreeBSD - "i686-freebsd13" "x86_64-freebsd13" + "i686-freebsd" "x86_64-freebsd" # Genode "aarch64-genode" "i686-genode" "x86_64-genode" diff --git a/lib/systems/examples.nix b/lib/systems/examples.nix index 75578b974945..8a3726f36968 100644 --- a/lib/systems/examples.nix +++ b/lib/systems/examples.nix @@ -235,6 +235,11 @@ rec { libc = "newlib"; }; + microblaze-embedded = { + config = "microblazeel-none-elf"; + libc = "newlib"; + }; + # # Redox # @@ -323,7 +328,7 @@ rec { # BSDs x86_64-freebsd = { - config = "x86_64-unknown-freebsd13"; + config = "x86_64-unknown-freebsd"; useLLVM = true; }; diff --git a/lib/systems/parse.nix b/lib/systems/parse.nix index 191e9734b879..4890912d7fed 100644 --- a/lib/systems/parse.nix +++ b/lib/systems/parse.nix @@ -326,11 +326,7 @@ rec { # the normalized name for macOS. macos = { execFormat = macho; families = { inherit darwin; }; name = "darwin"; }; ios = { execFormat = macho; families = { inherit darwin; }; }; - # A tricky thing about FreeBSD is that there is no stable ABI across - # versions. That means that putting in the version as part of the - # config string is paramount. - freebsd12 = { execFormat = elf; families = { inherit bsd; }; name = "freebsd"; version = 12; }; - freebsd13 = { execFormat = elf; families = { inherit bsd; }; name = "freebsd"; version = 13; }; + freebsd = { execFormat = elf; families = { inherit bsd; }; name = "freebsd"; }; linux = { execFormat = elf; families = { }; }; netbsd = { execFormat = elf; families = { inherit bsd; }; }; none = { execFormat = unknown; families = { }; }; diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index accceb4ddf9c..6774939023d2 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -33,7 +33,7 @@ let boolToString callPackagesWith callPackageWith - cartesianProductOfSets + cartesianProduct cli composeExtensions composeManyExtensions @@ -63,18 +63,20 @@ let hasAttrByPath hasInfix id + ifilter0 isStorePath lazyDerivation + length lists listToAttrs makeExtensible makeIncludePath makeOverridable mapAttrs + mapCartesianProduct matchAttrs mergeAttrs meta - mkOption mod nameValuePair optionalDrvAttr @@ -117,7 +119,6 @@ let expr = (builtins.tryEval expr).success; expected = true; }; - testingDeepThrow = expr: testingThrow (builtins.deepSeq expr expr); testSanitizeDerivationName = { name, expected }: let @@ -652,6 +653,31 @@ runTests { expected = ["b" "c"]; }; + testIfilter0Example = { + expr = ifilter0 (i: v: i == 0 || v > 2) [ 1 2 3 ]; + expected = [ 1 3 ]; + }; + testIfilter0Empty = { + expr = ifilter0 (i: v: abort "shouldn't be evaluated!") [ ]; + expected = [ ]; + }; + testIfilter0IndexOnly = { + expr = length (ifilter0 (i: v: mod i 2 == 0) [ (throw "0") (throw "1") (throw "2") (throw "3")]); + expected = 2; + }; + testIfilter0All = { + expr = ifilter0 (i: v: true) [ 10 11 12 13 14 15 ]; + expected = [ 10 11 12 13 14 15 ]; + }; + testIfilter0First = { + expr = ifilter0 (i: v: i == 0) [ 10 11 12 13 14 15 ]; + expected = [ 10 ]; + }; + testIfilter0Last = { + expr = ifilter0 (i: v: i == 5) [ 10 11 12 13 14 15 ]; + expected = [ 15 ]; + }; + testFold = let f = op: fold: fold op 0 (range 0 100); @@ -1415,7 +1441,7 @@ runTests { }; testToPrettyMultiline = { - expr = mapAttrs (const (generators.toPretty { })) rec { + expr = mapAttrs (const (generators.toPretty { })) { list = [ 3 4 [ false ] ]; attrs = { foo = null; bar.foo = "baz"; }; newlinestring = "\n"; @@ -1429,7 +1455,7 @@ runTests { there test''; }; - expected = rec { + expected = { list = '' [ 3 @@ -1467,13 +1493,10 @@ runTests { expected = "«foo»"; }; - testToPlist = - let - deriv = derivation { name = "test"; builder = "/bin/sh"; system = "aarch64-linux"; }; - in { + testToPlist = { expr = mapAttrs (const (generators.toPlist { })) { value = { - nested.values = rec { + nested.values = { int = 42; float = 0.1337; bool = true; @@ -1686,17 +1709,17 @@ runTests { }; testCartesianProductOfEmptySet = { - expr = cartesianProductOfSets {}; + expr = cartesianProduct {}; expected = [ {} ]; }; testCartesianProductOfOneSet = { - expr = cartesianProductOfSets { a = [ 1 2 3 ]; }; + expr = cartesianProduct { a = [ 1 2 3 ]; }; expected = [ { a = 1; } { a = 2; } { a = 3; } ]; }; testCartesianProductOfTwoSets = { - expr = cartesianProductOfSets { a = [ 1 ]; b = [ 10 20 ]; }; + expr = cartesianProduct { a = [ 1 ]; b = [ 10 20 ]; }; expected = [ { a = 1; b = 10; } { a = 1; b = 20; } @@ -1704,12 +1727,12 @@ runTests { }; testCartesianProductOfTwoSetsWithOneEmpty = { - expr = cartesianProductOfSets { a = [ ]; b = [ 10 20 ]; }; + expr = cartesianProduct { a = [ ]; b = [ 10 20 ]; }; expected = [ ]; }; testCartesianProductOfThreeSets = { - expr = cartesianProductOfSets { + expr = cartesianProduct { a = [ 1 2 3 ]; b = [ 10 20 30 ]; c = [ 100 200 300 ]; @@ -1753,6 +1776,30 @@ runTests { ]; }; + testMapCartesianProductOfOneSet = { + expr = mapCartesianProduct ({a}: a * 2) { a = [ 1 2 3 ]; }; + expected = [ 2 4 6 ]; + }; + + testMapCartesianProductOfTwoSets = { + expr = mapCartesianProduct ({a,b}: a + b) { a = [ 1 ]; b = [ 10 20 ]; }; + expected = [ 11 21 ]; + }; + + testMapCartesianProcutOfTwoSetsWithOneEmpty = { + expr = mapCartesianProduct (x: x.a + x.b) { a = [ ]; b = [ 10 20 ]; }; + expected = [ ]; + }; + + testMapCartesianProductOfThreeSets = { + expr = mapCartesianProduct ({a,b,c}: a + b + c) { + a = [ 1 2 3 ]; + b = [ 10 20 30 ]; + c = [ 100 200 300 ]; + }; + expected = [ 111 211 311 121 221 321 131 231 331 112 212 312 122 222 322 132 232 332 113 213 313 123 223 323 133 233 333 ]; + }; + # The example from the showAttrPath documentation testShowAttrPathExample = { expr = showAttrPath [ "foo" "10" "bar" ]; diff --git a/lib/tests/release.nix b/lib/tests/release.nix index 5b2a9df1635c..1447e8817091 100644 --- a/lib/tests/release.nix +++ b/lib/tests/release.nix @@ -2,7 +2,7 @@ # Don't test properties of pkgs.lib, but rather the lib in the parent directory pkgs ? import ../.. {} // { lib = throw "pkgs.lib accessed, but the lib tests should use nixpkgs' lib path directly!"; }, nix ? pkgs-nixVersions.stable, - nixVersions ? [ pkgs-nixVersions.minimum nix pkgs-nixVersions.unstable ], + nixVersions ? [ pkgs-nixVersions.minimum nix pkgs-nixVersions.latest ], pkgs-nixVersions ? import ./nix-for-tests.nix { inherit pkgs; }, }: diff --git a/lib/tests/systems.nix b/lib/tests/systems.nix index e142ff307fbd..03c5d6868962 100644 --- a/lib/tests/systems.nix +++ b/lib/tests/systems.nix @@ -40,7 +40,7 @@ lib.runTests ( testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ]; testarmv7 = mseteq armv7 [ "armv7a-darwin" "armv7a-linux" "armv7l-linux" "armv7a-netbsd" "armv7l-netbsd" ]; - testi686 = mseteq i686 [ "i686-linux" "i686-freebsd13" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ]; + testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ]; testmips = mseteq mips [ "mips-none" "mips64-none" "mips-linux" "mips64-linux" "mips64el-linux" "mipsel-linux" "mipsel-netbsd" ]; testmmix = mseteq mmix [ "mmix-mmixware" ]; testpower = mseteq power [ "powerpc-netbsd" "powerpc-none" "powerpc64-linux" "powerpc64le-linux" "powerpcle-none" ]; @@ -48,11 +48,11 @@ lib.runTests ( testriscv32 = mseteq riscv32 [ "riscv32-linux" "riscv32-netbsd" "riscv32-none" ]; testriscv64 = mseteq riscv64 [ "riscv64-linux" "riscv64-netbsd" "riscv64-none" ]; tests390x = mseteq s390x [ "s390x-linux" "s390x-none" ]; - testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd13" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ]; + testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ]; testcygwin = mseteq cygwin [ "i686-cygwin" "x86_64-cygwin" ]; testdarwin = mseteq darwin [ "x86_64-darwin" "i686-darwin" "aarch64-darwin" "armv7a-darwin" ]; - testfreebsd = mseteq freebsd [ "i686-freebsd13" "x86_64-freebsd13" ]; + testfreebsd = mseteq freebsd [ "i686-freebsd" "x86_64-freebsd" ]; testgenode = mseteq genode [ "aarch64-genode" "i686-genode" "x86_64-genode" ]; testredox = mseteq redox [ "x86_64-redox" ]; testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */); diff --git a/maintainers/maintainer-list.nix b/maintainers/maintainer-list.nix index 36ddea9f5e0d..cd2b6eaacac0 100644 --- a/maintainers/maintainer-list.nix +++ b/maintainers/maintainer-list.nix @@ -429,6 +429,18 @@ githubId = 1517066; name = "Aiken Cairncross"; }; + a-camarillo = { + name = "Anthony Camarillo"; + email = "anthony.camarillo.96@gmail.com"; + github = "a-camarillo"; + githubId = 58638902; + }; + acesyde = { + name = "Pierre-Emmanuel Mercier"; + email = "acesyde@gmail.com"; + github = "acesyde"; + githubId = 958435; + }; aciceri = { name = "Andrea Ciceri"; email = "andrea.ciceri@autistici.org"; @@ -768,6 +780,12 @@ github = "akgrant43"; githubId = 2062166; }; + akhilmhdh = { + email = "akhilmhdh@infisical.com"; + github = "akhilmhdh"; + githubId = 31166322; + name = "Akhil Mohan"; + }; akho = { name = "Alexander Khodyrev"; email = "a@akho.name"; @@ -800,6 +818,12 @@ githubId = 20405311; name = "Aksh Gupta"; }; + aktaboot = { + email = "akhtaboo@protonmail.com"; + github = "aktaboot"; + githubId = 120214979; + name = "aktaboot"; + }; al3xtjames = { email = "nix@alextjam.es"; github = "al3xtjames"; @@ -1080,12 +1104,6 @@ githubId = 153175; name = "Andrew Marshall"; }; - amaxine = { - email = "max@ine.dev"; - github = "amaxine"; - githubId = 35892750; - name = "Maxine Aubrey"; - }; ambroisie = { email = "bruno.nixpkgs@belanyi.fr"; github = "ambroisie"; @@ -1241,12 +1259,6 @@ githubId = 962885; name = "Andrew Chambers"; }; - andrew-d = { - email = "andrew@du.nham.ca"; - github = "andrew-d"; - githubId = 1079173; - name = "Andrew Dunham"; - }; andrewrk = { email = "superjoe30@gmail.com"; github = "andrewrk"; @@ -1442,12 +1454,24 @@ githubId = 4194320; name = "Anton Schirg"; }; + anytimetraveler = { + email = "simon@simonscode.org"; + github = "AnyTimeTraveler"; + githubId = 19378309; + name = "Simon Struck"; + }; aorith = { email = "aomanu+nixpkgs@gmail.com"; github = "aorith"; githubId = 5411704; name = "Manuel Sanchez Pinar"; }; + aos = { + email = "n@aos.sh"; + github = "aos"; + githubId = 25783780; + name = "aos"; + }; apeschar = { email = "albert@peschar.net"; github = "apeschar"; @@ -1791,11 +1815,6 @@ fingerprint = "409D 201E 9450 8732 A49E D0FC 6BDA F874 0068 08DF"; }]; }; - ashvith-shetty = { - github = "Ashvith10"; - githubId = 113123021; - name = "Ashvith Shetty"; - }; asininemonkey = { email = "nixpkgs@asininemonkey.com"; github = "asininemonkey"; @@ -1836,6 +1855,12 @@ githubId = 7745457; name = "Astavie"; }; + astindev = { + email = "astindev@pm.me"; + github = "astindev"; + githubId = 52360869; + name = "Astin"; + }; astro = { email = "astro@spaceboyz.net"; github = "astro"; @@ -2016,6 +2041,12 @@ githubId = 687218; name = "averelld"; }; + avery = { + email = "nixpkgs@avery.cafe"; + github = "coolavery"; + githubId = 76545554; + name = "Avery"; + }; avh4 = { email = "gruen0aermel@gmail.com"; github = "avh4"; @@ -2064,12 +2095,6 @@ githubId = 135230; name = "Aycan iRiCAN"; }; - ayes-web = { - email = "ayes2022@protonmail.com"; - github = "ayes-web"; - githubId = 52951851; - name = "ayes-web"; - }; aynish = { github = "Chickensoupwithrice"; githubId = 22575913; @@ -2257,6 +2282,12 @@ githubId = 576355; name = "Bas van Dijk"; }; + BatteredBunny = { + email = "ayes2022@protonmail.com"; + github = "BatteredBunny"; + githubId = 52951851; + name = "BatteredBunny"; + }; BattleCh1cken = { email = "BattleCh1cken@larkov.de"; github = "BattleCh1cken"; @@ -2930,6 +2961,12 @@ fingerprint = "BF4FCB85C69989B4ED95BF938AE74787A4B7C07E"; }]; }; + b-rodrigues = { + email = "bruno@brodrigues.co"; + github = "b-rodrigues"; + githubId = 2998834; + name = "Bruno Rodrigues"; + }; broke = { email = "broke@in-fucking.space"; github = "broke"; @@ -3005,6 +3042,12 @@ githubId = 37375448; name = "Buildit"; }; + buurro = { + email = "marcoburro98@gmail.com"; + github = "buurro"; + githubId = 9320677; + name = "Marco Burro"; + }; bwc9876 = { email = "bwc9876@gmail.com"; github = "Bwc9876"; @@ -3539,12 +3582,6 @@ githubId = 1118859; name = "Scott Worley"; }; - ChlorideCull = { - email = "nixrelated@chcl.se"; - github = "ChlorideCull"; - githubId = 4977063; - name = "Sebastian Johansson"; - }; choochootrain = { email = "hurshal@imap.cc"; github = "choochootrain"; @@ -4340,12 +4377,6 @@ githubId = 990767; name = "Daniel Olsen"; }; - danderson = { - email = "dave@natulte.net"; - github = "danderson"; - githubId = 1918; - name = "David Anderson"; - }; daneads = { email = "me@daneads.com"; github = "daneads"; @@ -4436,6 +4467,12 @@ github = "DarkOnion0"; githubId = 68606322; }; + daru-san = { + name = "Daru"; + email = "zadarumaka@proton.me"; + github = "Daru-san"; + githubId = 135046711; + }; das-g = { email = "nixpkgs@raphael.dasgupta.ch"; github = "das-g"; @@ -4756,12 +4793,6 @@ githubId = 150736012; email = "me+git@delliott.xyz"; }; - delroth = { - email = "delroth@gmail.com"; - github = "delroth"; - githubId = 202798; - name = "Pierre Bourdon"; - }; delta = { email = "d4delta@outlook.fr"; github = "D4Delta"; @@ -5797,6 +5828,15 @@ githubId = 4576666; name = "Eliza Velasquez"; }; + eljamm = { + name = "Fedi Jamoussi"; + email = "fedi.jamoussi@protonmail.ch"; + github = "eljamm"; + githubId = 83901271; + keys = [{ + fingerprint = "FF59 E027 4EE2 E792 512B BDC8 7630 FDF7 C8FB 1F3F"; + }]; + }; elkowar = { email = "thereal.elkowar@gmail.com"; github = "elkowar"; @@ -5939,12 +5979,6 @@ name = "Zhenbo Li"; matrix = "@zhenbo:matrix.org"; }; - endocrimes = { - email = "dani@builds.terrible.systems"; - github = "endocrimes"; - githubId = 1330683; - name = "Danielle Lancashire"; - }; enorris = { name = "Eric Norris"; email = "erictnorris@gmail.com"; @@ -6456,6 +6490,12 @@ githubId = 4246921; name = "Florian Beeres"; }; + fccapria = { + email = "francesco@capria.eu"; + github = "fccapria"; + githubId = 62179193; + name = "Francesco Carmelo Capria"; + }; fd = { email = "simon.menke@gmail.com"; github = "fd"; @@ -6468,16 +6508,6 @@ githubId = 541748; name = "Felipe Espinoza"; }; - federicoschonborn = { - name = "Federico Damián Schonborn"; - email = "federicoschonborn@disroot.org"; - github = "FedericoSchonborn"; - githubId = 62166915; - matrix = "@FedericoDSchonborn:matrix.org"; - keys = [ - { fingerprint = "C43F 4052 D289 3B73 33F8 0259 E4F6 F544 DE9E 29E8"; } - ]; - }; fedx-sudo = { email = "fedx-sudo@pm.me"; github = "FedX-sudo"; @@ -6716,12 +6746,6 @@ githubId = 5918766; name = "Franz Thoma"; }; - fogti = { - name = "Alain Fogtia Zscheile"; - email = "fogti+devel@ytrizja.de"; - github = "fogti"; - githubId = 1618343; - }; foo-dogsquared = { email = "foodogsquared@foodogsquared.one"; github = "foo-dogsquared"; @@ -7183,6 +7207,12 @@ githubId = 40209356; name = "Gabriel Doriath Döhler"; }; + gdifolco = { + email = "gautier.difolco@gmail.com"; + github = "blackheaven"; + githubId = 1362807; + name = "Gautier Di Folco"; + }; gdinh = { email = "nix@contact.dinh.ai"; github = "gdinh"; @@ -7363,12 +7393,6 @@ githubId = 104317939; name = "gilice"; }; - gilligan = { - email = "tobias.pflug@gmail.com"; - github = "gilligan"; - githubId = 27668; - name = "Tobias Pflug"; - }; gin66 = { email = "jochen@kiemes.de"; github = "gin66"; @@ -7588,6 +7612,12 @@ githubId = 76716; name = "Graham Christensen"; }; + grahamnorris = { + email = "oss@grahamjnorris.com"; + github = "grahamnorris"; + githubId = 66037909; + name = "Graham J. Norris"; + }; gravndal = { email = "gaute.ravndal+nixos@gmail.com"; github = "gravndal"; @@ -7723,6 +7753,12 @@ githubId = 10654650; name = "Guillaume Koenig"; }; + guitargeek = { + email = "jonas.rembser@cern.ch"; + github = "guitargeek"; + githubId = 6578603; + name = "Jonas Rembser"; + }; guserav = { github = "guserav"; githubId = 28863828; @@ -7806,6 +7842,12 @@ github = "HannahMR"; githubId = 9088467; }; + hannesgith = { + email = "nix@h-h.win"; + github = "hannesgith"; + githubId = 33062605; + name = "Hannes Hattenbach"; + }; hansjoergschurr = { email = "commits@schurr.at"; github = "hansjoergschurr"; @@ -9040,6 +9082,12 @@ githubId = 6789916; name = "Jason Odoom"; }; + javaes = { + email = "jan+dev@vanesdonk.de"; + github = "javaes"; + githubId = 1131529; + name = "Jan van Esdonk"; + }; javaguirre = { email = "contacto@javaguirre.net"; github = "javaguirre"; @@ -9115,6 +9163,12 @@ github = "joshua-cooper"; githubId = 35612334; }; + jcaesar = { + name = "Julius Michaelis"; + matrix = "@julius:mtx.liftm.de"; + github = "jcaesar"; + githubId = 1753388; + }; jceb = { name = "Jan Christoph Ebersbach"; email = "jceb@e-jc.de"; @@ -9373,12 +9427,6 @@ githubId = 6445082; name = "Joseph Lukasik"; }; - jgoux = { - email = "hi@jgoux.dev"; - github = "jgoux"; - githubId = 1443499; - name = "Julien Goux"; - }; jhh = { email = "jeff@j3ff.io"; github = "jhh"; @@ -9467,6 +9515,12 @@ fingerprint = "B768 6CD7 451A 650D 9C54 4204 6710 CF0C 1CBD 7762"; }]; }; + jlbribeiro = { + email = "nix@jlbribeiro.com"; + github = "jlbribeiro"; + githubId = 1015816; + name = "José Ribeiro"; + }; jleightcap = { email = "jack@leightcap.com"; github = "jleightcap"; @@ -9873,6 +9927,11 @@ github = "jpagex"; githubId = 635768; }; + jpaju = { + name = "Jaakko Paju"; + github = "jpaju"; + githubId = 36770267; + }; jpas = { name = "Jarrod Pas"; email = "jarrod@jarrodpas.com"; @@ -10357,15 +10416,6 @@ github = "keenanweaver"; githubId = 37268985; }; - keksbg = { - email = "keksbg@riseup.net"; - name = "Stella"; - github = "keksbg"; - githubId = 10682187; - keys = [{ - fingerprint = "AB42 1F18 5A19 A160 AD77 9885 3D6D CA5B 6F2C 2A7A"; - }]; - }; keldu = { email = "mail@keldu.de"; github = "keldu"; @@ -10523,6 +10573,12 @@ githubId = 845652; name = "Kier Davis"; }; + kiike = { + email = "me@enric.me"; + github = "kiike"; + githubId = 464625; + name = "Enric Morales"; + }; kilianar = { email = "mail@kilianar.de"; github = "kilianar"; @@ -10806,6 +10862,12 @@ githubId = 2037002; name = "Konstantinos"; }; + kotatsuyaki = { + email = "kotatsuyaki@mail.kotatsu.dev"; + github = "kotatsuyaki"; + githubId = 17219127; + name = "kotatsuyaki"; + }; kouyk = { email = "skykinetic@stevenkou.xyz"; github = "kouyk"; @@ -10983,6 +11045,12 @@ githubId = 2422454; name = "Kai Wohlfahrt"; }; + kylecarbs = { + name = "Kyle Carberry"; + email = "kyle@carberry.com"; + github = "kylecarbs"; + githubId = 7122116; + }; kylehendricks = { name = "Kyle Hendricks"; email = "kyle-github@mail.hendricks.nu"; @@ -11603,12 +11671,6 @@ githubId = 918448; name = "Anthony Lodi"; }; - loewenheim = { - email = "loewenheim@mailbox.org"; - github = "loewenheim"; - githubId = 7622248; - name = "Sebastian Zivota"; - }; logo = { email = "logo4poop@protonmail.com"; matrix = "@logo4poop:matrix.org"; @@ -11638,6 +11700,12 @@ github = "LongerHV"; githubId = 46924944; }; + lonyelon = { + email = "sergio@lony.xyz"; + name = "Sergio Miguéns Iglesias"; + github = "lonyelon"; + githubId = 18664655; + }; lopsided98 = { email = "benwolsieffer@gmail.com"; github = "lopsided98"; @@ -12347,11 +12415,6 @@ githubId = 1709273; name = "Robin Hack"; }; - marsam = { - github = "marsam"; - githubId = 65531; - name = "Mario Rodas"; - }; marsupialgutz = { email = "mars@possums.xyz"; github = "pupbrained"; @@ -13394,6 +13457,12 @@ fingerprint = "64BE BF11 96C3 DD7A 443E 8314 1DC0 82FA DE5B A863"; }]; }; + mlaradji = { + name = "Mohamed Laradji"; + email = "mlaradji@pm.me"; + github = "mlaradji"; + githubId = 33703663; + }; mlatus = { email = "wqseleven@gmail.com"; github = "Ninlives"; @@ -13588,12 +13657,6 @@ githubId = 20026143; name = "Katona László"; }; - MP2E = { - email = "MP2E@archlinux.us"; - github = "MP2E"; - githubId = 167708; - name = "Cray Elliott"; - }; mpcsh = { email = "m@mpc.sh"; github = "mpcsh"; @@ -13709,15 +13772,6 @@ githubId = 3856390; email = "mschwaig+nixpkgs@eml.cc"; }; - msfjarvis = { - github = "msfjarvis"; - githubId = 13348378; - name = "Harsh Shandilya"; - email = "nixos@msfjarvis.dev"; - keys = [{ - fingerprint = "8F87 050B 0F9C B841 1515 7399 B784 3F82 3355 E9B9"; - }]; - }; msiedlarek = { email = "mikolaj@siedlarek.pl"; github = "msiedlarek"; @@ -14637,12 +14691,6 @@ githubId = 126072875; name = "nova madeline"; }; - novenary = { - email = "streetwalkermc@gmail.com"; - github = "9ary"; - githubId = 1155030; - name = "novenary"; - }; novoxd = { email = "radnovox@gmail.com"; github = "novoxd"; @@ -14798,6 +14846,12 @@ githubId = 127548; name = "Judson Lester"; }; + nyawox = { + name = "nyawox"; + email = "nyawox.git@gmail.com"; + github = "nyawox"; + githubId = 93813719; + }; nzbr = { email = "nixos@nzbr.de"; github = "nzbr"; @@ -15106,6 +15160,13 @@ githubId = 104593071; name = "Oliver Schmidt"; }; + osslate = { + email = "fionn@kelleher.email"; + github = "osslate"; + githubId = 773673; + matrix = "@osslate:fsfe.org"; + name = "Fionn Kelleher"; + }; ostrolucky = { email = "gabriel.ostrolucky@gmail.com"; github = "ostrolucky"; @@ -15273,6 +15334,12 @@ githubId = 1788628; name = "pandaman"; }; + pandapip1 = { + email = "gavinnjohn@gmail.com"; + github = "Pandapip1"; + githubId = 45835846; + name = "Gavin John"; + }; panicgh = { email = "nbenes.gh@xandea.de"; github = "panicgh"; @@ -15327,12 +15394,6 @@ githubId = 72527881; name = "PassiveLemon"; }; - patka = { - email = "patka@patka.dev"; - github = "patka-123"; - githubId = 69802930; - name = "patka"; - }; patricksjackson = { email = "patrick@jackson.dev"; github = "patricksjackson"; @@ -15842,6 +15903,13 @@ githubId = 4056630; name = "Patrick Steinhardt"; }; + pkulak = { + name = "Phil Kulak"; + email = "phil@kulak.us"; + matrix = "@phil:kulak.us"; + github = "pkulak"; + githubId = 502905; + }; plabadens = { name = "Pierre Labadens"; email = "labadens.pierre+nixpkgs@gmail.com"; @@ -16334,6 +16402,12 @@ githubId = 5636; name = "Steve Purcell"; }; + purrpurrn = { + email = "scrcpynovideoaudiocodecraw+nixpkgs@gmail.com"; + github = "purrpurrn"; + githubId = 142632643; + name = "purrpurrn"; + }; putchar = { email = "slim.cadoux@gmail.com"; matrix = "@putch4r:matrix.org"; @@ -16359,6 +16433,16 @@ githubId = 4579165; name = "Danny Bautista"; }; + pyrox0 = { + name = "Pyrox"; + email = "pyrox@pyrox.dev"; + matrix = "@pyrox:pyrox.dev"; + github = "pyrox0"; + githubId = 35778371; + keys = [{ + fingerprint = "4CA9 72FB ADC8 1416 0F10 3138 FE1D 8A7D 620C 611F"; + }]; + }; pyxels = { email = "pyxels.dev@gmail.com"; github = "Pyxels"; @@ -16479,12 +16563,24 @@ fingerprint = "7573 56D7 79BB B888 773E 415E 736C CDF9 EF51 BD97"; }]; }; + qyriad = { + email = "qyriad@qyriad.me"; + github = "Qyriad"; + githubId = 1542224; + matrix = "@qyriad:katesiria.org"; + name = "Qyriad"; + }; r3dl3g = { email = "redleg@rothfuss-web.de"; github = "r3dl3g"; githubId = 35229674; name = "Armin Rothfuss"; }; + r3n3gad3p3arl = { + github = "r3n3gad3p3arl"; + githubId = 20760527; + name = "Madelyn"; + }; raboof = { email = "arnout@bzzt.net"; matrix = "@raboof:matrix.org"; @@ -16683,6 +16779,12 @@ githubId = 145816; name = "David McKay"; }; + raylas = { + email = "r@raymond.sh"; + github = "raylas"; + githubId = 8099415; + name = "Raymond Douglas"; + }; rayslash = { email = "stevemathewjoy@tutanota.com"; github = "rayslash"; @@ -16782,6 +16884,12 @@ githubId = 18155001; name = "Gabe Dunn"; }; + redyf = { + email = "mateusalvespereira7@gmail.com"; + github = "redyf"; + githubId = 98139059; + name = "Mateus Alves"; + }; reedrw = { email = "reedrw5601@gmail.com"; github = "reedrw"; @@ -16925,6 +17033,13 @@ githubId = 12279531; name = "Ricardo Guevara"; }; + rhelmot = { + name = "Audrey Dutcher"; + github = "rhelmot"; + githubId = 2498805; + email = "audrey@rhelmot.io"; + matrix = "@rhelmot:matrix.org"; + }; rhendric = { name = "Ryan Hendrickson"; github = "rhendric"; @@ -17015,6 +17130,12 @@ githubId = 37246692; name = "Riley Inman"; }; + rinx = { + email = "rintaro.okamura@gmail.com"; + github = "rinx"; + githubId = 1588935; + name = "Rintaro Okamura"; + }; riotbib = { email = "lennart@cope.cool"; github = "riotbib"; @@ -17204,6 +17325,12 @@ githubId = 69053978; name = "rogarb"; }; + rohanssrao = { + email = "rohanssrao@gmail.com"; + github = "rohanssrao"; + githubId = 17805516; + name = "Rohan Rao"; + }; rollf = { email = "rolf.schroeder@limbus-medtec.com"; github = "rollf"; @@ -18120,6 +18247,11 @@ githubId = 863807; name = "Serge Guelton"; }; + sergioribera = { + github = "SergioRibera"; + githubId = 56278796; + name = "Sergio Ribera"; + }; sersorrel = { email = "ash@sorrel.sh"; github = "sersorrel"; @@ -18977,12 +19109,6 @@ githubId = 16364318; name = "Jeffrey Harmon"; }; - srapenne = { - email = "solene@perso.pw"; - github = "rapenne-s"; - githubId = 248016; - name = "Solène Rapenne"; - }; srghma = { email = "srghma@gmail.com"; github = "srghma"; @@ -19945,16 +20071,6 @@ github = "thefossguy"; githubId = 44400303; }; - thehedgeh0g = { - name = "The Hedgehog"; - email = "hedgehog@mrhedgehog.xyz"; - matrix = "@mrhedgehog:jupiterbroadcasting.com"; - github = "pyrox0"; - githubId = 35778371; - keys = [{ - fingerprint = "38A0 29B0 4A7E 4C13 A4BB 86C8 7D51 0786 6B1C 6752"; - }]; - }; thekostins = { name = "Konstantin"; email = "anisimovkosta19@gmail.com"; @@ -20229,12 +20345,6 @@ github = "tirimia"; githubId = 11174371; }; - titanous = { - email = "jonathan@titanous.com"; - github = "titanous"; - githubId = 13026; - name = "Jonathan Rudenberg"; - }; tjni = { email = "43ngvg@masqt.com"; matrix = "@tni:matrix.org"; @@ -20330,12 +20440,6 @@ githubId = 74688871; name = "Tochukwu Ahanonu"; }; - tokudan = { - email = "git@danielfrank.net"; - github = "tokudan"; - githubId = 692610; - name = "Daniel Frank"; - }; tomahna = { email = "kevin.rauscher@tomahna.fr"; github = "Tomahna"; @@ -20655,12 +20759,6 @@ githubId = 131159000; name = "Nitin Passa"; }; - twitchyliquid64 = { - name = "Tom"; - email = "twitchyliquid64@ciphersink.net"; - github = "twitchyliquid64"; - githubId = 6328589; - }; twz123 = { name = "Tom Wieczorek"; email = "tom@bibbu.net"; @@ -21538,6 +21636,16 @@ fingerprint = "DA03 D6C6 3F58 E796 AD26 E99B 366A 2940 479A 06FC"; }]; }; + willbush = { + email = "git@willbush.dev"; + matrix = "@willbush:matrix.org"; + github = "willbush"; + githubId = 2023546; + name = "Will Bush"; + keys = [{ + fingerprint = "4441 422E 61E4 C8F3 EBFE 5E33 3823 864B 54B1 3BDA"; + }]; + }; willcohen = { github = "willcohen"; githubId = 5185341; @@ -21840,12 +21948,6 @@ githubId = 36407913; name = "Uli Baum"; }; - xfix = { - email = "kamila@borowska.pw"; - github = "KamilaBorowska"; - githubId = 1297598; - name = "Kamila Borowska"; - }; xfnw = { email = "xfnw+nixos@riseup.net"; github = "xfnw"; @@ -21860,7 +21962,8 @@ }; xgwq = { name = "XGWQ"; - email = "nixos@xnee.de"; + email = "nixos.xgwq@xnee.net"; + keys = [{ fingerprint = "6489 9EF2 A256 5C04 7426 686C 8337 A748 74EB E129"; }]; matrix = "@xgwq:nerdberg.de"; github = "peterablehmann"; githubId = 36541313; @@ -22246,6 +22349,12 @@ githubId = 179548; name = "Yves Fischer"; }; + YvesStraten = { + email = "yves.straten@gmail.com"; + github = "YvesStraten"; + githubId = 65394961; + name = "Yves Straten"; + }; yvt = { email = "i@yvt.jp"; github = "yvt"; @@ -22428,6 +22537,12 @@ githubId = 1108325; name = "Théo Zimmermann"; }; + zlepper = { + name = "Rasmus Hansen"; + github = "zlepper"; + githubId = 1499810; + email = "hansen13579@gmail.com"; + }; zmitchell = { name = "Zach Mitchell"; email = "zmitchell@fastmail.com"; @@ -22468,12 +22583,6 @@ githubId = 51886259; name = "Zokre Zyl"; }; - zombiezen = { - name = "Ross Light"; - email = "ross@zombiezen.com"; - github = "zombiezen"; - githubId = 181535; - }; zookatron = { email = "tim@zookatron.com"; github = "zookatron"; @@ -22515,12 +22624,6 @@ githubId = 393108; name = "Damien Diederen"; }; - zumorica = { - name = "Vera Aguilera Puerto"; - email = "gradientvera+nix@outlook.com"; - github = "Zumorica"; - githubId = 6766154; - }; zupo = { name = "Nejc Zupan"; email = "nejczupan+nix@gmail.com"; diff --git a/maintainers/scripts/eval-release.nix b/maintainers/scripts/eval-release.nix index 10acfe328447..fb830981683f 100644 --- a/maintainers/scripts/eval-release.nix +++ b/maintainers/scripts/eval-release.nix @@ -5,7 +5,7 @@ let trace = if builtins.getEnv "VERBOSE" == "1" then builtins.trace else (x: y: y); - rel = removeAttrs (import ../../pkgs/top-level/release.nix { }) [ "tarball" "unstable" "xbursttools" ]; + rel = removeAttrs (import ../../pkgs/top-level/release.nix { }) [ "tarball" "unstable" ]; # Add the ‘recurseForDerivations’ attribute to ensure that # nix-instantiate recurses into nested attribute sets. diff --git a/maintainers/scripts/luarocks-packages.csv b/maintainers/scripts/luarocks-packages.csv index a4e46e6991bc..4b41b7887512 100644 --- a/maintainers/scripts/luarocks-packages.csv +++ b/maintainers/scripts/luarocks-packages.csv @@ -5,11 +5,11 @@ argparse,,,,,, basexx,,,,,, binaryheap,,,,,,vcunat busted,,,,,, -cassowary,,,,,,marsam alerque +cassowary,,,,,,alerque cldr,,,,,,alerque compat53,,,,,,vcunat commons.nvim,,,,,,mrcjkb -cosmo,,,,,,marsam +cosmo,,,,,, coxpcall,,,,1.17.0-1,, cqueues,,,,,,vcunat cyan,,,,,, diff --git a/maintainers/team-list.nix b/maintainers/team-list.nix index 9389514fcba5..2a50f6f98d09 100644 --- a/maintainers/team-list.nix +++ b/maintainers/team-list.nix @@ -32,7 +32,6 @@ with lib.maintainers; { acme = { members = [ aanderse - andrew-d arianvp emily flokli @@ -46,7 +45,6 @@ with lib.maintainers; { bazel = { members = [ mboes - marsam uri-canva cbley olebedev @@ -99,7 +97,6 @@ with lib.maintainers; { budgie = { members = [ bobby285271 - federicoschonborn ]; scope = "Maintain Budgie desktop environment"; shortName = "Budgie"; @@ -265,9 +262,7 @@ with lib.maintainers; { }; docs = { - members = [ - ryantm - ]; + members = [ ]; scope = "Maintain nixpkgs/NixOS documentation and tools for building it."; shortName = "Docs"; enableFeatureFreezePing = true; @@ -380,7 +375,6 @@ with lib.maintainers; { krav talyz yayayayaka - yuka ]; scope = "Maintain gitlab packages."; shortName = "gitlab"; @@ -408,7 +402,6 @@ with lib.maintainers; { hedning jtojnar dasj19 - amaxine ]; githubTeams = [ "gnome" @@ -467,6 +460,14 @@ with lib.maintainers; { shortName = "Home Assistant"; }; + infisical = { + members = [ + akhilmhdh + ]; + scope = "Maintain Infisical"; + shortName = "Infisical"; + }; + iog = { members = [ cleverca22 @@ -531,7 +532,6 @@ with lib.maintainers; { members = [ aanderse edwtjo - MP2E thiagokokada ]; scope = "Maintain Libretro, RetroArch and related packages."; @@ -575,6 +575,9 @@ with lib.maintainers; { rrbutani sternenseemann ]; + githubTeams = [ + "llvm" + ]; scope = "Maintain LLVM package sets and related packages"; shortName = "LLVM"; enableFeatureFreezePing = true; @@ -733,7 +736,6 @@ with lib.maintainers; { node = { members = [ lilyinstarlight - marsam winter ]; scope = "Maintain Node.js runtimes and build tooling."; @@ -831,7 +833,6 @@ with lib.maintainers; { python = { members = [ - fridh hexa jonringer tjni @@ -861,8 +862,10 @@ with lib.maintainers; { r = { members = [ + b-rodrigues bcdarwin jbedo + kupac ]; scope = "Maintain the R programming language and related packages."; shortName = "R"; @@ -903,7 +906,6 @@ with lib.maintainers; { ruby = { members = [ - marsam ]; scope = "Maintain the Ruby interpreter and related packages."; shortName = "Ruby"; diff --git a/nixos/doc/manual/configuration/abstractions.section.md b/nixos/doc/manual/configuration/abstractions.section.md index 5bc44aa72245..3ff8ac885b65 100644 --- a/nixos/doc/manual/configuration/abstractions.section.md +++ b/nixos/doc/manual/configuration/abstractions.section.md @@ -10,14 +10,12 @@ If you find yourself repeating yourself over and over, it’s time to abstract. adminAddr = "alice@example.org"; forceSSL = true; enableACME = true; - enablePHP = true; }; "wiki.example.org" = { documentRoot = "/webroot/wiki.example.org"; adminAddr = "alice@example.org"; forceSSL = true; enableACME = true; - enablePHP = true; }; }; } @@ -35,7 +33,7 @@ in { services.httpd.virtualHosts = { "blog.example.org" = (commonConfig // { documentRoot = "/webroot/blog.example.org"; }); - "wiki.example.org" = (commonConfig // { documentRoot = "/webroot/wiki.example.com"; }); + "wiki.example.org" = (commonConfig // { documentRoot = "/webroot/wiki.example.org"; }); }; } ``` diff --git a/nixos/doc/manual/configuration/customizing-packages.section.md b/nixos/doc/manual/configuration/customizing-packages.section.md index a524ef266eaf..074932b3f110 100644 --- a/nixos/doc/manual/configuration/customizing-packages.section.md +++ b/nixos/doc/manual/configuration/customizing-packages.section.md @@ -1,11 +1,33 @@ # Customising Packages {#sec-customising-packages} -Some packages in Nixpkgs have options to enable or disable optional -functionality or change other aspects of the package. +The Nixpkgs configuration for a NixOS system is set by the {option}`nixpkgs.config` option. + +::::{.example} +# Globally allow unfree packages + +```nix +{ + nixpkgs.config = { + allowUnfree = true; + }; +} +``` + +:::{.note} +This only allows unfree software in the given NixOS configuration. +For users invoking Nix commands such as [`nix-build`](https://nixos.org/manual/nix/stable/command-ref/nix-build), Nixpkgs is configured independently. +See the [Nixpkgs manual section on global configuration](https://nixos.org/manual/nixpkgs/unstable/#chap-packageconfig) for details. +::: +:::: + + + +Some packages in Nixpkgs have options to enable or disable optional functionality, or change other aspects of the package. ::: {.warning} -Unfortunately, Nixpkgs currently lacks a way to query available -configuration options. +Unfortunately, Nixpkgs currently lacks a way to query available package configuration options. ::: ::: {.note} diff --git a/nixos/doc/manual/configuration/profiles/graphical.section.md b/nixos/doc/manual/configuration/profiles/graphical.section.md index 3bd80b52e845..84fad5c0a612 100644 --- a/nixos/doc/manual/configuration/profiles/graphical.section.md +++ b/nixos/doc/manual/configuration/profiles/graphical.section.md @@ -6,5 +6,5 @@ graphical installation CD. It sets [](#opt-services.xserver.enable), [](#opt-services.displayManager.sddm.enable), [](#opt-services.xserver.desktopManager.plasma5.enable), -and [](#opt-services.xserver.libinput.enable) to true. It also +and [](#opt-services.libinput.enable) to true. It also includes glxinfo and firefox in the system packages list. diff --git a/nixos/doc/manual/configuration/x-windows.chapter.md b/nixos/doc/manual/configuration/x-windows.chapter.md index c09e0877e866..31752330dd9a 100644 --- a/nixos/doc/manual/configuration/x-windows.chapter.md +++ b/nixos/doc/manual/configuration/x-windows.chapter.md @@ -207,7 +207,7 @@ Latitude series) can be enabled as follows: ```nix { - services.xserver.libinput.enable = true; + services.libinput.enable = true; } ``` @@ -216,7 +216,7 @@ For instance, the following disables tap-to-click behavior: ```nix { - services.xserver.libinput.touchpad.tapping = false; + services.libinput.touchpad.tapping = false; } ``` diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix index 558fec4cab92..80916e9733c5 100644 --- a/nixos/doc/manual/default.nix +++ b/nixos/doc/manual/default.nix @@ -80,17 +80,17 @@ let cp -r --no-preserve=all $inputs/* . substituteInPlace ./manual.md \ - --replace '@NIXOS_VERSION@' "${version}" + --replace-fail '@NIXOS_VERSION@' "${version}" substituteInPlace ./configuration/configuration.md \ - --replace \ + --replace-fail \ '@MODULE_CHAPTERS@' \ ${escapeShellArg (concatMapStringsSep "\n" (p: "${p.value}") config.meta.doc)} substituteInPlace ./nixos-options.md \ - --replace \ + --replace-fail \ '@NIXOS_OPTIONS_JSON@' \ ${optionsDoc.optionsJSON}/${common.outputPath}/options.json substituteInPlace ./development/writing-nixos-tests.section.md \ - --replace \ + --replace-fail \ '@NIXOS_TEST_OPTIONS_JSON@' \ ${testOptionsDoc.optionsJSON}/${common.outputPath}/options.json sed -e '/@PYTHON_MACHINE_METHODS@/ {' -e 'r ${testDriverMachineDocstrings}/machine-methods.md' -e 'd' -e '}' \ diff --git a/nixos/doc/manual/release-notes/rl-2405.section.md b/nixos/doc/manual/release-notes/rl-2405.section.md index 32d9508e89b1..6a76b194a144 100644 --- a/nixos/doc/manual/release-notes/rl-2405.section.md +++ b/nixos/doc/manual/release-notes/rl-2405.section.md @@ -10,13 +10,13 @@ In addition to numerous new and upgraded packages, this release has the followin - `cryptsetup` has been upgraded from 2.6.1 to 2.7.0. Cryptsetup is a critical component enabling LUKS-based (but not only) full disk encryption. Take the time to review [the release notes](https://gitlab.com/cryptsetup/cryptsetup/-/raw/v2.7.0/docs/v2.7.0-ReleaseNotes). - One of the highlight is that it is now possible to use hardware OPAL-based encryption of your disk with `cryptsetup`, it has a lot of caveats, see the above notes for the full details. + One of the highlights is that it is now possible to use hardware OPAL-based encryption of your disk with `cryptsetup`. It has a lot of caveats, see the above notes for the full details. - `screen`'s module has been cleaned, and will now require you to set `programs.screen.enable` in order to populate `screenrc` and add the program to the environment. - `linuxPackages_testing_bcachefs` is now fully deprecated by `linuxPackages_latest`, and is therefore no longer available. -- The default kernel package has been updated from 6.1 to 6.6. All supported kernels remain available. +- (TODO not sure what path to use here) The default kernel package has been updated from 6.1 to 6.6. All supported kernels remain available. - NixOS now installs a stub ELF loader that prints an informative error message when users attempt to run binaries not made for NixOS. - This can be disabled through the `environment.stub-ld.enable` option. @@ -30,9 +30,13 @@ In addition to numerous new and upgraded packages, this release has the followin To disable this, set [nixpkgs.flake.setNixPath](#opt-nixpkgs.flake.setNixPath) and [nixpkgs.flake.setFlakeRegistry](#opt-nixpkgs.flake.setFlakeRegistry) to false. -- Julia environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`. +- `nixVersions.unstable` was removed. Instead the following attributes are provided: + - `nixVersions.git` which tracks the latest Nix master and is roughly updated once a week. This is intended to enable people to easily test unreleased changes of Nix to catch regressions earlier. + - `nixVersions.latest` which points to the latest Nix version packaged in nixpkgs. -- The PipeWire and WirePlumber modules have removed support for using +- `julia` environments can now be built with arbitrary packages from the ecosystem using the `.withPackages` function. For example: `julia.withPackages ["Plots"]`. + +- `pipewire` and `wireplumber` modules have removed support for using `environment.etc."pipewire/..."` and `environment.etc."wireplumber/..."`. Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for PipeWire and `services.pipewire.wireplumber.configPackages` for WirePlumber instead." @@ -41,16 +45,12 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi Refer to upstream [upgrade instructions](https://goteleport.com/docs/management/operations/upgrading/) and release notes for [v15](https://goteleport.com/docs/changelog/#1500-013124). -- A new option `systemd.sysusers.enable` was added. If enabled, users and +- `systemd.sysusers.enable` option was added. If enabled, users and groups are created with systemd-sysusers instead of with a custom perl script. -- The default dbus implementation has transitioned to dbus-broker from the classic dbus daemon for better performance and reliability. Users can revert to the classic dbus daemon by setting `services.dbus.implementation = "dbus";`. For detailed deviations, refer to [dbus-broker's deviations page](https://github.com/bus1/dbus-broker/wiki/Deviations). +- `virtualisation.docker.enableNvidia` and `virtualisation.podman.enableNvidia` options are deprecated. `hardware.nvidia-container-toolkit.enable` should be used instead. This option will expose GPUs on containers with the `--device` CLI option. This is supported by Docker 25, Podman 3.2.0 and Singularity 4. Any container runtime that supports the CDI specification will take advantage of this feature. -- A new option `virtualisation.containers.cdi` was added. It contains `static` and `dynamic` attributes (corresponding to `/etc/cdi` and `/run/cdi` respectively) to configure the Container Device Interface (CDI). - -- `virtualisation.docker.enableNvidia` and `virtualisation.podman.enableNvidia` options are deprecated. `virtualisation.containers.cdi.dynamic.nvidia.enable` should be used instead. This option will expose GPUs on containers with the `--device` CLI option. This is supported by Docker 25, Podman 3.2.0 and Singularity 4. Any container runtime that supports the CDI specification will take advantage of this feature. - -- A new option `system.etc.overlay.enable` was added. If enabled, `/etc` is +- `system.etc.overlay.enable` option was added. If enabled, `/etc` is mounted via an overlayfs instead of being created by a custom perl script. - NixOS AMIs are now uploaded regularly to a new AWS Account. @@ -69,16 +69,16 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi } ``` -- The initial Incus LTS release (v6.0.x) is now available through `virtualisation.incus` as the default. Users who wish to continue using the non-LTS release will need to set `virtualisation.incus.package = pkgs.incus`. Stable release users are encouraged to stay on the LTS release as non-LTS releases will by default not be backported. +- `virtialisation.incus` now defaults to the newly-added `incus-lts` release (v6.0.x). Users who wish to continue using the non-LTS release will need to set `virtualisation.incus.package = pkgs.incus`. Stable release users are encouraged to stay on the LTS release as non-LTS releases will by default not be backported. -- Canonical LXD has been upgraded to v5.21.x, an LTS release. The LTS release is now the only supported LXD release. Users are encouraged to [migrate to Incus](https://linuxcontainers.org/incus/docs/main/howto/server_migrate_lxd/) for better support on NixOS. +- Canonical `lxd` has been upgraded to v5.21.x, an LTS release. The LTS release is now the only supported LXD release. Users are encouraged to [migrate to Incus](https://linuxcontainers.org/incus/docs/main/howto/server_migrate_lxd/) for better support on NixOS. -- lua interpreters default LUA_PATH and LUA_CPATH are not overriden by nixpkgs +- `lua` interpreters default LUA_PATH and LUA_CPATH are not overriden by nixpkgs anymore, we patch LUA_ROOT instead which is more respectful to upstream. -- Plasma 6 is now available and can be installed with `services.xserver.desktopManager.plasma6.enable = true;`. Plasma 5 will likely be deprecated in the next release (24.11). Note that Plasma 6 runs as Wayland by default, and the X11 session needs to be explicitly selected if necessary. +- `plasma6` is now available and can be installed with `services.xserver.desktopManager.plasma6.enable = true;`. Plasma 5 will likely be deprecated in the next release (24.11). Note that Plasma 6 runs as Wayland by default, and the X11 session needs to be explicitly selected if necessary. -- The desktop mode of Lomiri (formerly known as Unity8), using Mir 2.x to function as a Wayland compositor, is now available and can be installed with `services.desktopManager.lomiri.enable = true`. Note that some core applications, services and indicators have yet to be packaged, and some functions may remain incomplete, but the base experience should be there. +- `lomiri` (formerly known as Unity8) desktop mode, using Mir 2.x to function as a Wayland compositor, is now available and can be installed with `services.desktopManager.lomiri.enable = true`. Note that some core applications, services and indicators have yet to be packaged, and some functions may remain incomplete, but the base experience should be there. ## New Services {#sec-release-24.05-new-services} @@ -92,6 +92,8 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi - [PhotonVision](https://photonvision.org/), a free, fast, and easy-to-use computer vision solution for the FIRST® Robotics Competition. +- [clatd](https://github.com/toreanderson/clatd), a CLAT / SIIT-DC Edge Relay implementation for Linux. + - [pyLoad](https://pyload.net/), a FOSS download manager written in Python. Available as [services.pyload](#opt-services.pyload.enable) - [maubot](https://github.com/maubot/maubot), a plugin-based Matrix bot framework. Available as [services.maubot](#opt-services.maubot.enable). @@ -100,7 +102,7 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi - [ryzen-smu](https://gitlab.com/leogx9r/ryzen_smu), Linux kernel driver to expose the SMU (System Management Unit) for certain AMD Ryzen Processors. Includes the userspace program `monitor_cpu`. Available at [hardward.cpu.amd.ryzen-smu](#opt-hardware.cpu.amd.ryzen-smu.enable) -- systemd's gateway, upload, and remote services, which provides ways of sending journals across the network. Enable using [services.journald.gateway](#opt-services.journald.gateway.enable), [services.journald.upload](#opt-services.journald.upload.enable), and [services.journald.remote](#opt-services.journald.remote.enable). +- `systemd`'s `gateway`, `upload`, and `remote` services, which provide ways of sending journals across the network. Enable using [services.journald.gateway](#opt-services.journald.gateway.enable), [services.journald.upload](#opt-services.journald.upload.enable), and [services.journald.remote](#opt-services.journald.remote.enable). - [GNS3](https://www.gns3.com/), a network software emulator. Available as [services.gns3-server](#opt-services.gns3-server.enable). @@ -108,6 +110,8 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi - [dnsproxy](https://github.com/AdguardTeam/dnsproxy), a simple DNS proxy with DoH, DoT, DoQ and DNSCrypt support. Available as [services.dnsproxy](#opt-services.dnsproxy.enable). +- [manticoresearch](https://manticoresearch.com), easy to use open source fast database for search. Available as [services.manticore](#opt-services.manticore.enable). + - [rspamd-trainer](https://gitlab.com/onlime/rspamd-trainer), script triggered by a helper which reads mails from a specific mail inbox and feeds them into rspamd for spam/ham training. - [ollama](https://ollama.ai), server for running large language models locally. @@ -125,10 +129,12 @@ Use `services.pipewire.extraConfig` or `services.pipewire.configPackages` for Pi - [db-rest](https://github.com/derhuerst/db-rest), a wrapper around Deutsche Bahn's internal API for public transport data. Available as [services.db-rest](#opt-services.db-rest.enable). - [Anki Sync Server](https://docs.ankiweb.net/sync-server.html), the official sync server built into recent versions of Anki. Available as [services.anki-sync-server](#opt-services.anki-sync-server.enable). -The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server softwares. +The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been marked deprecated and will be dropped after 24.05 due to lack of maintenance of the anki-sync-server software. - [mautrix-meta](https://github.com/mautrix/meta), a Matrix <-> Facebook and Matrix <-> Instagram hybrid puppeting/relaybot bridge. Available as services.mautrix-meta +- [Jottacloud Command-line Tool](https://docs.jottacloud.com/en/articles/1436834-jottacloud-command-line-tool), a CLI for the [Jottacloud](https://jottacloud.com/) cloud storage provider. Available as [services.jotta-cli](#opt-services.jotta-cli.enable). + - [transfer-sh](https://github.com/dutchcoders/transfer.sh), a tool that supports easy and fast file sharing from the command-line. Available as [services.transfer-sh](#opt-services.transfer-sh.enable). - [FCast Receiver](https://fcast.org), an open-source alternative to Chromecast and AirPlay. Available as [programs.fcast-receiver](#opt-programs.fcast-receiver.enable). @@ -137,6 +143,8 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [Suwayomi Server](https://github.com/Suwayomi/Suwayomi-Server), a free and open source manga reader server that runs extensions built for [Tachiyomi](https://tachiyomi.org). Available as [services.suwayomi-server](#opt-services.suwayomi-server.enable). +- [Netbird](https://netbird.io), an open-source VPN management platform, now has a self-hosted management server. Available as [services.netbird.server](#opt-services.netbird.server.enable). + - [ping_exporter](https://github.com/czerwonk/ping_exporter), a Prometheus exporter for ICMP echo requests. Available as [services.prometheus.exporters.ping](#opt-services.prometheus.exporters.ping.enable). - [Prometheus DNSSEC Exporter](https://github.com/chrj/prometheus-dnssec-exporter), check for validity and expiration in DNSSEC signatures and expose metrics for Prometheus. Available as [services.prometheus.exporters.dnssec](#opt-services.prometheus.exporters.dnssec.enable). @@ -147,9 +155,11 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [Monado](https://monado.freedesktop.org/), an open source XR runtime. Available as [services.monado](#opt-services.monado.enable). -- [Pretix](https://pretix.eu/about/en/), an open source ticketing software for events. Available as [services.pretix]($opt-services-pretix.enable). +- [Pretix](https://pretix.eu/about/en/), an open source ticketing software for events. Available as [services.pretix](#opt-services.pretix.enable). -- [microsocks](https://github.com/rofl0r/microsocks), a tiny, portable SOCKS5 server with very moderate resource usage. Available as [services.microsocks]($opt-services-microsocks.enable). +- [microsocks](https://github.com/rofl0r/microsocks), a tiny, portable SOCKS5 server with very moderate resource usage. Available as [services.microsocks](#opt-services.microsocks.enable). + +- [inadyn](https://github.com/troglobit/inadyn), a Dynamic DNS client with built-in support for multiple providers. Available as [services.inadyn](#opt-services.inadyn.enable). - [Clevis](https://github.com/latchset/clevis), a pluggable framework for automated decryption, used to unlock encrypted devices in initrd. Available as [boot.initrd.clevis.enable](#opt-boot.initrd.clevis.enable). @@ -157,21 +167,25 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [armagetronad](https://wiki.armagetronad.org), a mid-2000s 3D lightcycle game widely played at iD Tech Camps. You can define multiple servers using `services.armagetronad..enable`. -- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite]($opt-services.wyoming.satellite.enable). +- [wyoming-satellite](https://github.com/rhasspy/wyoming-satellite), a voice assistant satellite for Home Assistant using the Wyoming protocol. Available as [services.wyoming.satellite](#opt-services.wyoming.satellite.enable). - [TuxClocker](https://github.com/Lurkki14/tuxclocker), a hardware control and monitoring program. Available as [programs.tuxclocker](#opt-programs.tuxclocker.enable). -- binfmt option for AppImage-run to support running [AppImage](https://appimage.org/)'s seamlessly on NixOS.. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt). +- [AppImage](https://appimage.org/), a tool to package desktop applications, now has a `binfmt` option to support running AppImages seamlessly on NixOS. Available as [programs.appimage.binfmt](#opt-programs.appimage.binfmt). - [nh](https://github.com/viperML/nh), yet another Nix CLI helper. Available as [programs.nh](#opt-programs.nh.enable). - [ALVR](https://github.com/alvr-org/alvr), a VR desktop streamer. Available as [programs.alvr](#opt-programs.alvr.enable) -- [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. +- [xdg-terminal-exec](https://github.com/Vladimir-csp/xdg-terminal-exec), the proposed Default Terminal Execution Specification. -- [Scrutiny](https://github.com/AnalogJ/scrutiny), a S.M.A.R.T monitoring tool for hard disks with a web frontend. +- [RustDesk](https://rustdesk.com), a full-featured open source remote control alternative for self-hosting and security with minimal configuration. Alternative to TeamViewer. Available as [services.rustdesk-server](#opt-services.rustdesk-server.enable). -- [davis](https://github.com/tchapi/davis), a simple CardDav and CalDav server inspired by Baïkal. Available as [services.davis]($opt-services-davis.enable). +- [Scrutiny](https://github.com/AnalogJ/scrutiny), a S.M.A.R.T monitoring tool for hard disks with a web frontend. Available as [services.scrutiny](#opt-services.scrutiny.enable). + +- [davis](https://github.com/tchapi/davis), a simple CardDav and CalDav server inspired by Baïkal. Available as [services.davis](#opt-services.davis.enable). + +- [Firefly-iii](https://www.firefly-iii.org), a free and open source personal finance manager. Available as [services.firefly-iii](#opt-services.firefly-iii.enable) - [systemd-lock-handler](https://git.sr.ht/~whynothugo/systemd-lock-handler/), a bridge between logind D-Bus events and systemd targets. Available as [services.systemd-lock-handler.enable](#opt-services.systemd-lock-handler.enable). @@ -179,17 +193,35 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [Mealie](https://nightly.mealie.io/), a self-hosted recipe manager and meal planner with a RestAPI backend and a reactive frontend application built in NuxtJS for a pleasant user experience for the whole family. Available as [services.mealie](#opt-services.mealie.enable) +- [Sunshine](https://app.lizardbyte.dev/Sunshine), a self-hosted game stream host for Moonlight. Available as [services.sunshine](#opt-services.sunshine.enable). + - [Uni-Sync](https://github.com/EightB1ts/uni-sync), a synchronization tool for Lian Li Uni Controllers. Available as [hardware.uni-sync](#opt-hardware.uni-sync.enable) - [prometheus-nats-exporter](https://github.com/nats-io/prometheus-nats-exporter), a Prometheus exporter for NATS. Available as [services.prometheus.exporters.nats](#opt-services.prometheus.exporters.nats.enable). +- [isolate](https://github.com/ioi/isolate), a sandbox for securely executing untrusted programs. Available as [security.isolate](#opt-security.isolate.enable). + ## Backward Incompatibilities {#sec-release-24.05-incompatibilities} - `k3s`: was updated to version [v1.29](https://github.com/k3s-io/k3s/releases/tag/v1.29.1%2Bk3s2), all previous versions (k3s_1_26, k3s_1_27, k3s_1_28) will be removed. See [changelog and upgrade notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.29.md#urgent-upgrade-notes) for more information. -- `himalaya` was updated to `v1.0.0-beta.4`, which introduces breaking changes. Check out the [release note](https://github.com/soywod/himalaya/releases/tag/v1.0.0-beta.4) for details. +- `himalaya` was updated to v1.0.0-beta.4, which introduces breaking changes. Check out the [release note](https://github.com/soywod/himalaya/releases/tag/v1.0.0-beta.4) for details. + +- `security.pam.enableSSHAgentAuth` was replaced by the `sshAgentAuth` attrset, and **only** + `authorized_keys` files listed in [`sshAgentAuth.authorizedKeysFiles`] are trusted, + defaulting to `/etc/ssh/authorized_keys.d/%u`. + ::: {.warning} + Users of {manpage}`pam_ssh_agent_auth(8)` must take care that the pubkeys they use (for instance with `sudo`) + are listed in [`sshAgentAuth.authorizedKeysFiles`]. + ::: + ::: {.note} + Previously, all `services.openssh.authorizedKeysFiles` were trusted, including `~/.ssh/authorized_keys`, + which results in an **insecure** configuration; see [#31611](https://github.com/NixOS/nixpkgs/issues/31611). + ::: + +[`sshAgentAuth.authorizedKeysFiles`]: #opt-security.pam.sshAgentAuth.authorizedKeysFiles - The `power.ups` module now generates `upsd.conf`, `upsd.users` and `upsmon.conf` automatically from a set of new configuration options. This breaks compatibility with existing `power.ups` setups where these files were created manually. Back up these files before upgrading NixOS. @@ -200,11 +232,13 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `cudaPackages.autoFixElfFiles` has been deprecated for `pkgs.autoFixElfFiles`. Functionality has not changed, but the setuphook has been renamed and moved to the top-level package scope. +- `appimageTools.wrapAppImage` now creates the binary at `$out/bin/${pname}` rather than `$out/bin/${pname}-${version}`, which will break downstream workarounds. + - `pdns` was updated to version [v4.9.x](https://doc.powerdns.com/authoritative/changelog/4.9.html), which introduces breaking changes. Check out the [Upgrade Notes](https://doc.powerdns.com/authoritative/upgrading.html#to-4-9-0) for details. - `unrar` was updated to v7. See [changelog](https://www.rarlab.com/unrar7notes.htm) for more information. -- `git-town` was updated from version `11` to `13`. See the [changelog](https://github.com/git-town/git-town/blob/main/CHANGELOG.md#1300-2024-03-22) for breaking changes. +- `git-town` was updated from version 11 to 13. See the [changelog](https://github.com/git-town/git-town/blob/main/CHANGELOG.md#1300-2024-03-22) for breaking changes. - `k9s` was updated to v0.31. There have been various breaking changes in the config file format, check out the changelog of [v0.29](https://github.com/derailed/k9s/releases/tag/v0.29.0), @@ -218,16 +252,16 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m The list in `nixos/modules/virtualisation/amazon-ec2-amis.nix` will stop being updated and will be removed in the future. -- The option `services.postgresql.ensureUsers._.ensurePermissions` has been removed as it's +- The option `services.postgresql.ensureUsers._.ensurePermissions` has been removed as it is not declarative and is broken with newer postgresql versions. Consider using [](#opt-services.postgresql.ensureUsers._.ensureDBOwnership) - instead or a tool that's more suited for managing the data inside a postgresql database. + instead or a tool that is more suited for managing the data inside a postgresql database. - `idris2` was updated to v0.7.0. This version introduces breaking changes. Check out the [changelog](https://github.com/idris-lang/Idris2/blob/v0.7.0/CHANGELOG.md#v070) for details. - `nvtop` family of packages was reorganized into nested attrset. `nvtop` has been renamed to `nvtopPackages.full`, and all `nvtop-{amd,nvidia,intel,msm}` packages are now named as `nvtopPackages.{amd,nvidia,intel,msm}` -- `neo4j` has been updated to 5, you may want to read the [release notes for Neo4j 5](https://neo4j.com/release-notes/database/neo4j-5/) +- `neo4j` has been updated to version 5. You may want to read the [release notes for Neo4j 5](https://neo4j.com/release-notes/database/neo4j-5/). - `services.neo4j.allowUpgrade` was removed and no longer has any effect. Neo4j 5 supports automatic rolling upgrades. @@ -235,43 +269,47 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `mongodb-4_4` has been removed as it has reached end of life. Consequently, `unifi7` and `unifi8` now use MongoDB 5.0 by default. +- `mongodb-5_0` and newer requires a cpu with the avx instruction set to run. + - `nitter` requires a `guest_accounts.jsonl` to be provided as a path or loaded into the default location at `/var/lib/nitter/guest_accounts.jsonl`. See [Guest Account Branch Deployment](https://github.com/zedeus/nitter/wiki/Guest-Account-Branch-Deployment) for details. - `boot.supportedFilesystems` and `boot.initrd.supportedFilesystems` are now attribute sets instead of lists. Assignment from lists as done previously is still supported, but checking whether a filesystem is enabled must now by done using `supportedFilesystems.fs or false` instead of using `lib.elem "fs" supportedFilesystems` as was done previously. - `services.aria2.rpcSecret` has been replaced with `services.aria2.rpcSecretFile`. This was done so that secrets aren't stored in the world-readable nix store. - To migrate, you will have create a file with the same exact string, and change + To migrate, you will have to create a file with the same exact string, and change your module options to point to that file. For example, `services.aria2.rpcSecret = "mysecret"` becomes `services.aria2.rpcSecretFile = "/path/to/secret_file"` where the file `secret_file` contains the string `mysecret`. - `openssh`, `openssh_hpn` and `openssh_gssapi` are now compiled without support for the DSA signature algorithm as it is being deprecated upstream. Users still relying on DSA keys should consider upgrading - to another signature algorithm. It is however possible, for the time being, to restore the DSA keys support using `override` to set `dsaKeysSupport = true`. + to another signature algorithm. However, for the time being it is possible to restore DSA key support using `override` to set `dsaKeysSupport = true`. -- `buildGoModule` now throws error when `vendorHash` is not specified. `vendorSha256`, deprecated in Nixpkgs 23.11, is now ignored and is no longer a `vendorHash` alias. +- `buildGoModule` now throws an error when `vendorHash` is not specified. `vendorSha256`, deprecated in Nixpkgs 23.11, is now ignored and is no longer a `vendorHash` alias. -- Invidious has changed its default database username from `kemal` to `invidious`. Setups involving an externally provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857) +- `services.invidious.settings.db.user`, the default database username has changed from `kemal` to `invidious`. Setups involving an externally-provisioned database (i.e. `services.invidious.database.createLocally == false`) should adjust their configuration accordingly. The old `kemal` user will not be removed automatically even when the database is provisioned automatically.(https://github.com/NixOS/nixpkgs/pull/265857) - `writeReferencesToFile` is deprecated in favour of the new trivial build helper `writeClosure`. The latter accepts a list of paths and has an unambiguous name and cleaner implementation. - `inetutils` now has a lower priority to avoid shadowing the commonly used `util-linux`. If one wishes to restore the default priority, simply use `lib.setPrio 5 inetutils` or override with `meta.priority = 5`. -- `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the freeform type and option named `services.paperless.settings`. +- `paperless`' `services.paperless.extraConfig` setting has been removed and converted to the free-form type and option named `services.paperless.settings`. -- `davfs2`' `services.davfs2.extraConfig` setting has been deprecated and converted to the freeform type option named `services.davfs2.settings` according to RFC42. +- `davfs2`' `services.davfs2.extraConfig` setting has been deprecated and converted to the free-form type option named `services.davfs2.settings` according to RFC42. -- `services.homepage-dashboard` now takes it's configuration using native Nix expressions, rather than dumping templated configurations into `/var/lib/homepage-dashboard` where they were previously managed manually. There are now new options which allow the configuration of bookmarks, services, widgets and custom CSS/JS natively in Nix. +- `services.homepage-dashboard` now takes its configuration using native Nix expressions, rather than dumping templated configurations into `/var/lib/homepage-dashboard` where they were previously managed manually. There are now new options which allow the configuration of bookmarks, services, widgets and custom CSS/JS natively in Nix. - `hare` may now be cross-compiled. For that to work, however, `haredoc` needed to stop being built together with it. Thus, the latter is now its own package with the name of `haredoc`. -- The legacy and long deprecated systemd target `network-interfaces.target` has been removed. Use `network.target` instead. +- `network-interfaces.target` system target was removed as it has been deprecated for a long time. Use `network.target` instead. + +- `services.redis.vmOverCommit` now defaults to `true` and no longer enforces Transparent Hugepages (THP) to be disabled. Redis only works with THP configured to `madvise` which is the kernel's default. - `azure-cli` now has extension support. For example, to install the `aks-preview` extension, use ```nix environment.systemPackages = [ - (azure-cli.withExtensions [ azure-cli.extensions.aks-preview ]); + (azure-cli.withExtensions [ azure-cli.extensions.aks-preview ]) ]; ``` To make the `azure-cli` immutable and prevent clashes in case `azure-cli` is also installed via other package managers, some configuration files were moved into the derivation. @@ -283,17 +321,23 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - Proxies are now defined with a new option `settings.proxies` which takes a list of proxies. - Consult the [upstream documentation](https://github.com/fatedier/frp#example-usage) for more details on the changes. -- `mkosi` was updated to v20. Parts of the user interface have changed. Consult the - release notes of [v19](https://github.com/systemd/mkosi/releases/tag/v19) and - [v20](https://github.com/systemd/mkosi/releases/tag/v20) for a list of changes. +- `mkosi` was updated to v22. Parts of the user interface have changed. Consult the + release notes of [v19](https://github.com/systemd/mkosi/releases/tag/v19), + [v20](https://github.com/systemd/mkosi/releases/tag/v20), + [v21](https://github.com/systemd/mkosi/releases/tag/v21) and + [v22](https://github.com/systemd/mkosi/releases/tag/v22) for a list of changes. - `gonic` has been updated to v0.16.4. Config now requires `playlists-path` to be set. See the rest of the [v0.16.0 release notes](https://github.com/sentriz/gonic/releases/tag/v0.16.0) for more details. -- The `services.vikunja` systemd service now uses `vikunja` as dynamic user instead of `vikunja-api`. Database users might need to be changed. +- `services.vikunja` systemd service now uses `vikunja` as dynamic user instead of `vikunja-api`. Database users might need to be changed. -- The `services.vikunja.setupNginx` setting has been removed. Users now need to setup the webserver configuration on their own with a proxy pass to the vikunja service. +- `services.vikunja.setupNginx` setting has been removed. Users now need to setup the webserver configuration on their own with a proxy pass to the vikunja service. -- The `woodpecker-*` packages have been updated to v2 which includes [breaking changes](https://woodpecker-ci.org/docs/next/migrations#200). +- `services.vmagent` module deprecates `dataDir`, `group` and `user` setting in favor of systemd provided CacheDirectory and DynamicUser. + +- `services.vmagent.remoteWriteUrl` setting has been renamed to `services.vmagent.remoteWrite.url` and now defaults to `null`. + +- `woodpecker-*` packages have been updated to v2 which includes [breaking changes](https://woodpecker-ci.org/docs/next/migrations#200). - `services.nginx` will no longer advertise HTTP/3 availability automatically. This must now be manually added, preferably to each location block. Example: @@ -309,27 +353,30 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m } ``` -- The package `optparse-bash` is now dropped due to upstream inactivity. Alternatives available in Nixpkgs include [`argc`](https://github.com/sigoden/argc), [`argbash`](https://github.com/matejak/argbash), [`bashly`](https://github.com/DannyBen/bashly) and [`gum`](https://github.com/charmbracelet/gum), to name a few. +- `optparse-bash` is now dropped due to upstream inactivity. Alternatives available in Nixpkgs include [`argc`](https://github.com/sigoden/argc), [`argbash`](https://github.com/matejak/argbash), [`bashly`](https://github.com/DannyBen/bashly) and [`gum`](https://github.com/charmbracelet/gum), to name a few. -- The `kanata` package has been updated to v1.5.0, which includes [breaking changes](https://github.com/jtroo/kanata/releases/tag/v1.5.0). +- `kanata` package has been updated to v1.6.1, which includes breaking changes. Check out the changelog of [v1.5.0](https://github.com/jtroo/kanata/releases/tag/v1.5.0) and [v1.6.0](https://github.com/jtroo/kanata/releases/tag/v1.6.0) for details. -- The `craftos-pc` package has been updated to v2.8, which includes [breaking changes](https://github.com/MCJack123/craftos2/releases/tag/v2.8). +- `craftos-pc` package has been updated to v2.8, which includes [breaking changes](https://github.com/MCJack123/craftos2/releases/tag/v2.8). - Files are now handled in binary mode; this could break programs with embedded UTF-8 characters. - The ROM was updated to match ComputerCraft version v1.109.2. - The bundled Lua was updated to Lua v5.2, which includes breaking changes. See the [Lua manual](https://www.lua.org/manual/5.2/manual.html#8) for more information. - The WebSocket API [was rewritten](https://github.com/MCJack123/craftos2/issues/337), which introduced breaking changes. -- The `gtest` package has been updated past v1.13.0, which requires C++14 or higher. +- `gtest` package has been updated past v1.13.0, which requires C++14 or higher. -- The latest available version of Nextcloud is v28 (available as `pkgs.nextcloud28`). The installation logic is as follows: +- Nextcloud 26 has been removed since it's not maintained anymore by upstream. + +- The latest available version of Nextcloud is v29 (available as `pkgs.nextcloud29`). The installation logic is as follows: - If [`services.nextcloud.package`](#opt-services.nextcloud.package) is specified explicitly, this package will be installed (**recommended**) - - If [`system.stateVersion`](#opt-system.stateVersion) is >=24.05, `pkgs.nextcloud28` will be installed by default. + - If [`system.stateVersion`](#opt-system.stateVersion) is >=24.05, `pkgs.nextcloud29` will be installed by default. - If [`system.stateVersion`](#opt-system.stateVersion) is >=23.11, `pkgs.nextcloud27` will be installed by default. - - Please note that an upgrade from v26 (or older) to v28 directly is not possible. Please upgrade to `nextcloud27` (or earlier) first. Nextcloud prohibits skipping major versions while upgrading. You can upgrade by declaring [`services.nextcloud.package = pkgs.nextcloud27;`](options.html#opt-services.nextcloud.package). + - Please note that an upgrade from v27 (or older) to v29 directly is not possible. Please upgrade to `nextcloud28` (or earlier) first. Nextcloud prohibits skipping major versions while upgrading. You can upgrade by declaring [`services.nextcloud.package = pkgs.nextcloud28;`](options.html#opt-services.nextcloud.package). + - Known warnings after the upgrade are documented in [](#module-services-nextcloud-known-warnings). - The vendored third party libraries have been mostly removed from `cudaPackages.nsight_systems`, which we now only ship for `cudaPackages_11_8` and later due to outdated dependencies. Users comfortable with the vendored dependencies may use `overrideAttrs` to amend the `postPatch` phase and the `meta.broken` correspondingly. Alternatively, one could package the deprecated `boost170` locally, as required for `cudaPackages_11_4.nsight_systems`. -- The `cudaPackages` package scope has been updated to `cudaPackages_12`. +- `cudaPackages` package scope has been updated to `cudaPackages_12`. - The deprecated `cudaPackages.cudatoolkit` has been replaced with a symlink-based wrapper for the splayed redistributable CUDA packages. The @@ -337,10 +384,15 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m like e.g. tensorflow. The original runfile-based `cudatoolkit` is still available as `cudatoolkit-legacy-runfile`. -- The `halloy` package was updated past 2024.5 which introduced a breaking change by switching the config format from YAML to TOML. See https://github.com/squidowl/halloy/releases/tag/2024.5 for details. +- `halloy` package was updated past 2024.5 which introduced a breaking change by switching the config format from YAML to TOML. See https://github.com/squidowl/halloy/releases/tag/2024.5 for details. + +- The `wpaperd` package has a breaking change moving to 1.0.1, previous version 0.3.0 had 2 different configuration files, one for wpaperd and one for the wallpapers. Remove the former and move the latter (`wallpaper.toml`) to `config.toml`. - Ada packages (libraries and tools) have been moved into the `gnatPackages` scope. `gnatPackages` uses the default GNAT compiler, `gnat12Packages` and `gnat13Packages` use the respective matching compiler version. +- Paths provided as `restartTriggers` and `reloadTriggers` for systemd units will now be copied into the nix store to make the behavior consistent. + Previously, `restartTriggers = [ ./config.txt ]`, if defined in a flake, would trigger a restart when any part of the flake changed; and if not defined in a flake, would never trigger a restart even if the contents of `config.txt` changed. + - `spark2014` has been renamed to `gnatprove`. A version of `gnatprove` matching different GNAT versions is available from the different `gnatPackages` sets. - `services.resolved.fallbackDns` can now be used to disable the upstream fallback servers entirely by setting it to an empty list. To get the previous behaviour of the upstream defaults set it to null, the new default, instead. @@ -354,10 +406,12 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `xxd` has been moved from `vim` default output to its own output to reduce closure size. The canonical way to reference it across all platforms is `unixtools.xxd`. -- The `stalwart-mail` package has been updated to v0.5.3, which includes [breaking changes](https://github.com/stalwartlabs/mail-server/blob/v0.5.3/UPGRADING.md). +- `stalwart-mail` package has been updated to v0.5.3, which includes [breaking changes](https://github.com/stalwartlabs/mail-server/blob/v0.5.3/UPGRADING.md). - `services.zope2` has been removed as `zope2` is unmaintained and was relying on Python2. +- `services.oauth2_proxy` was renamed to `services.oauth2-proxy`. Also the corresponding service, user and group were renamed. + - `services.avahi.nssmdns` got split into `services.avahi.nssmdns4` and `services.avahi.nssmdns6` which enable the mDNS NSS switch for IPv4 and IPv6 respectively. Since most mDNS responders only register IPv4 addresses, most users want to keep the IPv6 support disabled to avoid long timeouts. @@ -388,14 +442,18 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m upgrade NetBox by changing `services.netbox.package`. Database migrations will be run automatically. -- The executable file names for `firefox-devedition`, `firefox-beta`, `firefox-esr` now matches their package names, which is consistent with the `firefox-*-bin` packages. The desktop entries are also updated so that you can have multiple editions of firefox in your app launcher. +- `gauge` now supports installing plugins using nix. For the old imperative approach, switch to `gauge-unwrapped`. + You can load plugins from an existing gauge manifest file using `gauge.fromManifest ./path/to/manifest.json` or + specify plugins in nix using `gauge.withPlugins (p: with p; [ js html-report xml-report ])`. + +- `firefox-devedition`, `firefox-beta`, `firefox-esr` executable file names for now match their package names, which is consistent with the `firefox-*-bin` packages. The desktop entries are also updated so that you can have multiple editions of firefox in your app launcher. - switch-to-configuration does not directly call systemd-tmpfiles anymore. Instead, the new artificial sysinit-reactivation.target is introduced which allows to restart multiple services that are ordered before sysinit.target and respect the ordering between the services. -- The `systemd.oomd` module behavior is changed as: +- `systemd.oomd` module behavior is changed as: - Raise ManagedOOMMemoryPressureLimit from 50% to 80%. This should make systemd-oomd kill things less often, and fix issues like [this](https://pagure.io/fedora-workstation/issue/358). Reference: [commit](https://src.fedoraproject.org/rpms/systemd/c/806c95e1c70af18f81d499b24cd7acfa4c36ffd6?branch=806c95e1c70af18f81d499b24cd7acfa4c36ffd6) @@ -415,7 +473,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - [watchdogd](https://troglobit.com/projects/watchdogd/), a system and process supervisor using watchdog timers. Available as [services.watchdogd](#opt-services.watchdogd.enable). -- The `jdt-language-server` package now uses upstream's provided python wrapper instead of our own custom wrapper. This results in the following breaking and notable changes: +- `jdt-language-server` package now uses upstream's provided python wrapper instead of our own custom wrapper. This results in the following breaking and notable changes: - The main binary for the package is now named `jdtls` instead of `jdt-language-server`, equivalent to what most editors expect the binary to be named. @@ -437,21 +495,23 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - Ruby plugin support has been disabled in DFHack. Many of the Ruby plugins have been converted to Lua, and support was removed upstream due to frequent crashes. -- The `livebook` package is now built as a `mix release` instead of an `escript`. +- `livebook` package is now built as a `mix release` instead of an `escript`. This means that configuration now has to be done using [environment variables](https://hexdocs.pm/livebook/readme.html#environment-variables) instead of command line arguments. This has the further implication that the `livebook` service configuration has changed: -- The `erlang_node_short_name`, `erlang_node_name`, `port` and `options` configuration parameters are gone, and have been replaced with an `environment` parameter. +- `erlang_node_short_name`, `erlang_node_name`, `port` and `options` configuration parameters are gone, and have been replaced with an `environment` parameter. Use the appropriate [environment variables](https://hexdocs.pm/livebook/readme.html#environment-variables) inside `environment` to configure the service instead. - `akkoma` now requires explicitly setting the base URL for uploaded media (`settings."Pleroma.Upload".base_url`), as well as for the media proxy if enabled (`settings."Media"`). This is recommended to be a separate (sub)domain to the one Akkoma is hosted at. See [here](https://meta.akkoma.dev/t/akkoma-stable-2024-03-securer-i-barely-know-her/681#explicit-upload-and-media-proxy-domains-5) for more details. -- The `crystal` package has been updated to 1.11.x, which has some breaking changes. +- `crystal` package has been updated to 1.11.x, which has some breaking changes. Refer to crystal's changelog for more information. ([v1.10](https://github.com/crystal-lang/crystal/blob/master/CHANGELOG.md#1100-2023-10-09), [v1.11](https://github.com/crystal-lang/crystal/blob/master/CHANGELOG.md#1110-2024-01-08)) -- The `erlang-ls` package no longer ships the `els_dap` binary as of v0.51.0. +- `erlang-ls` package no longer ships the `els_dap` binary as of v0.51.0. + +- `icu` no longer includes `install-sh` and `mkinstalldirs` in the shared folder. ## Other Notable Changes {#sec-release-24.05-notable-changes} @@ -459,14 +519,14 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `addDriverRunpath` has been added to facilitate the deprecation of the old `addOpenGLRunpath` setuphook. This change is motivated by the evolution of the setuphook to include all hardware acceleration. -- Cinnamon has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release and could potentially [affect Xorg sessions](https://blog.linuxmint.com/?p=4639). We suggest a reboot when switching between sessions. +- `cinnamon` has been updated to 6.0. Please beware that the [Wayland session](https://blog.linuxmint.com/?p=4591) is still experimental in this release and could potentially [affect Xorg sessions](https://blog.linuxmint.com/?p=4639). We suggest a reboot when switching between sessions. -- MATE has been updated to 1.28. +- (TODO awaiting feedback on code-casing package names) MATE has been updated to 1.28. - To properly support panel plugins built with Wayland (in-process) support, we are introducing `services.xserver.desktopManager.mate.extraPanelApplets` option, please use that for installing panel applets. - Similarly, please use `services.xserver.desktopManager.mate.extraCajaExtensions` option for installing Caja extensions. - To use the Wayland session, enable `services.xserver.desktopManager.mate.enableWaylandSession`. This is opt-in for now as it is in early stage and introduces a new set of Wayfire closure. Due to [known issues with LightDM](https://github.com/canonical/lightdm/issues/63), we suggest using SDDM for display manager. -- The Budgie module installs gnome-terminal by default (instead of mate-terminal). +- `services.xserver.desktopManager.budgie` installs `gnome.gnome-terminal` by default (instead of `mate.mate-terminal`). - New `boot.loader.systemd-boot.xbootldrMountPoint` allows setting up a separate [XBOOTLDR partition](https://uapi-group.org/specifications/specs/boot_loader_specification/) to store boot files. Useful on systems with a small EFI System partition that cannot be easily repartitioned. @@ -475,19 +535,32 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `services.postgresql.extraPlugins` changed its type from just a list of packages to also a function that returns such a list. For example a config line like ``services.postgresql.extraPlugins = with pkgs.postgresql_11.pkgs; [ postgis ];`` is recommended to be changed to ``services.postgresql.extraPlugins = ps: with ps; [ postgis ];``; -- The Matrix homeserver [Synapse](https://element-hq.github.io/synapse/) module now supports configuring UNIX domain socket [listeners](#opt-services.matrix-synapse.settings.listeners) through the `path` option. +- `services.openssh` now has an option `authorizedKeysInHomedir`, controlling whether `~/.ssh/authorizedKeys` is + added to `authorizedKeysFiles`. + ::: {.note} + This option currently defaults to `true` for NixOS 24.05, preserving the previous behaviour. + This is expected to change in NixOS 24.11. + ::: + ::: {.warning} + Users should check that their SSH keys are in `users.users.*.openssh`, or that they have another way to access + and administer the system, before setting this option to `false`. + ::: + +- [`matrix-synapse`](https://element-hq.github.io/synapse/) homeserver module now supports configuring UNIX domain socket [`listeners`](#opt-services.matrix-synapse.settings.listeners) through the `path` option. The default replication worker on the main instance has been migrated away from TCP sockets to UNIX domain sockets. -- The initrd ssh daemon module got a new option to add authorized keys via a list of files using `boot.initrd.network.ssh.authorizedKeyFiles`. +- `boot.initrd.network.ssh.authorizedKeyFiles` is a new option in the initrd ssh daemon module, for adding authorized keys via list of files. + +- `appimage`, `appimageTools.wrapAppImage` and `buildFHSEnvBubblewrap` now properly accepts `pname` and `version`. - Programs written in [Nim](https://nim-lang.org/) are built with libraries selected by lockfiles. The `nimPackages` and `nim2Packages` sets have been removed. See https://nixos.org/manual/nixpkgs/unstable#nim for more information. -- Programs written in [D](https://dlang.org/) using the `dub` build system and package manager can now be built using `buildDubPackage` utilizing lockfiles provided by the new `dub-to-nix` helper program. +- [TODO: reword to place an attribute at the front] Programs written in [D](https://dlang.org/) using the `dub` build system and package manager can now be built using `buildDubPackage` utilizing lockfiles provided by the new `dub-to-nix` helper program. See the [D section](https://nixos.org/manual/nixpkgs/unstable#dlang) in the manual for more information. -- [Portunus](https://github.com/majewsky/portunus) has been updated to major version 2. +- [`portunus`](https://github.com/majewsky/portunus) has been updated to major version 2. This version of Portunus supports strong password hashes, but the legacy hash SHA-256 is also still supported to ensure a smooth migration of existing user accounts. After upgrading, follow the instructions on the [upstream release notes](https://github.com/majewsky/portunus/releases/tag/v2.0.0) to upgrade all user accounts to strong password hashes. Support for weak password hashes will be removed in NixOS 24.11. @@ -496,11 +569,11 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `libass` now uses the native CoreText backend on Darwin, which may fix subtitle rendering issues with `mpv`, `ffmpeg`, etc. -- [Lilypond](https://lilypond.org/index.html) and [Denemo](https://www.denemo.org) are now compiled with Guile 3.0. +- [`lilypond`](https://lilypond.org/index.html) and [`denemo`](https://www.denemo.org) are now compiled with Guile 3.0. -- Garage has been updated to v1.x.x. Users should read the [upstream release notes](https://git.deuxfleurs.fr/Deuxfleurs/garage/releases/tag/v1.0.0) and follow the documentation when changing over their `services.garage.package` and performing this manual upgrade. +- `garage` has been updated to v1.x.x. Users should read the [upstream release notes](https://git.deuxfleurs.fr/Deuxfleurs/garage/releases/tag/v1.0.0) and follow the documentation when changing over their `services.garage.package` and performing this manual upgrade. -- The EC2 image module now enables the [Amazon SSM Agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html) by default. +- [TODO: reword to place an attribute at the front] The EC2 image module now enables the [Amazon SSM Agent](https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent.html) by default. - The following options of the Nextcloud module were moved into [`services.nextcloud.settings`](#opt-services.nextcloud.settings) and renamed to match the name from Nextcloud's `config.php`: - `logLevel` -> [`loglevel`](#opt-services.nextcloud.settings.loglevel), @@ -512,7 +585,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `extraTrustedDomains` -> [`trusted_domains`](#opt-services.nextcloud.settings.trusted_domains) and - `trustedProxies` -> [`trusted_proxies`](#opt-services.nextcloud.settings.trusted_proxies). -- The option [`services.nextcloud.config.dbport`] of the Nextcloud module was removed to match upstream. +- `services.nextcloud.config.dbport` option of the Nextcloud module was removed to match upstream. The port can be specified in [`services.nextcloud.config.dbhost`](#opt-services.nextcloud.config.dbhost). - A new abstraction to create both read-only as well as writable overlay file @@ -520,7 +593,7 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m [fileSystems.overlay](#opt-fileSystems._name_.overlay.lowerdir). See also the [NixOS docs](#sec-overlayfs). -- systemd units can now specify the `Upholds=` and `UpheldBy=` unit dependencies via the aptly +- `systemd` units can now specify the `Upholds=` and `UpheldBy=` unit dependencies via the aptly named `upholds` and `upheldBy` options. These options get systemd to enforce that the dependencies remain continuosly running for as long as the dependent unit is in a running state. @@ -533,33 +606,27 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - New options were added to the dnsdist module to enable and configure a DNSCrypt endpoint (see `services.dnsdist.dnscrypt.enable`, etc.). The module can generate the DNSCrypt provider key pair, certificates and also performs their rotation automatically with no downtime. -- With a bump to `sonarr` v4, existing config database files will be upgraded automatically, but note that some old apparently-working configs [might actually be corrupt and fail to upgrade cleanly](https://forums.sonarr.tv/t/sonarr-v4-released/33089). +- `sonarr` version bumped to from 3.0.10 to 4.0.3. Consequently existing config database files will be upgraded automatically, but note that some old apparently-working configs [might actually be corrupt and fail to upgrade cleanly](https://forums.sonarr.tv/t/sonarr-v4-released/33089). -- The Yama LSM is now enabled by default in the kernel, which prevents ptracing +- [TODO: reword to place an attribute at the front] The Yama LSM is now enabled by default in the kernel, which prevents ptracing non-child processes. This means you will not be able to attach gdb to an existing process, but will need to start that process from gdb (so it is a child). Or you can set `boot.kernel.sysctl."kernel.yama.ptrace_scope"` to 0. -- The netbird module now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.tunnels). +- `netbird` module now allows running multiple tunnels in parallel through [`services.netbird.tunnels`](#opt-services.netbird.tunnels). - [Nginx virtual hosts](#opt-services.nginx.virtualHosts) using `forceSSL` or - `globalRedirect` can now have redirect codes other than 301 through + `globalRedirect` can now have redirect codes other than 301 through `redirectCode`. - `bacula` now allows to configure `TLS` for encrypted communication. - `redirectCode`. +- `libjxl` version bumped from 0.8.2 to 0.9.1 [dropped support for the butteraugli API](https://github.com/libjxl/libjxl/pull/2576). You will no longer be able to set `enableButteraugli` on `libaom`. -- `libjxl` 0.9.0 [dropped support for the butteraugli API](https://github.com/libjxl/libjxl/pull/2576). You will no longer be able to set `enableButteraugli` on `libaom`. - -- The source of the `mockgen` package has changed to the [go.uber.org/mock](https://github.com/uber-go/mock) fork because [the original repository is no longer maintained](https://github.com/golang/mock#gomock). - -- `security.pam.enableSSHAgentAuth` was renamed to `security.pam.sshAgentAuth.enable` and an `authorizedKeysFiles` - option was added, to control which `authorized_keys` files are trusted. It defaults to the previous behaviour, - **which is insecure**: see [#31611](https://github.com/NixOS/nixpkgs/issues/31611). +- `mockgen` package source has changed to the [go.uber.org/mock](https://github.com/uber-go/mock) fork because [the original repository is no longer maintained](https://github.com/golang/mock#gomock). - [](#opt-boot.kernel.sysctl._net.core.wmem_max_) changed from a string to an integer because of the addition of a custom merge option (taking the highest value defined to avoid conflicts between 2 services trying to set that value), just as [](#opt-boot.kernel.sysctl._net.core.rmem_max_) since 22.11. -- A new top-level package set, `pkgsExtraHardening` is added. This is a set of packages built with stricter hardening flags - those that have not yet received enough testing to be applied universally, those that are more likely to cause build failures or those that have drawbacks to their use (e.g. performance or required hardware features). +- [TODO: reword to place an attribute at the front] A new top-level package set, `pkgsExtraHardening` is added. This is a set of packages built with stricter hardening flags - those that have not yet received enough testing to be applied universally, those that are more likely to cause build failures or those that have drawbacks to their use (e.g. performance or required hardware features). - `services.zfs.zed.enableMail` now uses the global `sendmail` wrapper defined by an email module (such as msmtp or Postfix). It no longer requires using a special ZFS build with email support. @@ -568,57 +635,59 @@ The pre-existing [services.ankisyncd](#opt-services.ankisyncd.enable) has been m - `nextcloud-setup.service` no longer changes the group of each file & directory inside `/var/lib/nextcloud/{config,data,store-apps}` if one of these directories has the wrong owner group. This was part of transitioning the group used for `/var/lib/nextcloud`, but isn't necessary anymore. -- `services.kavita` now uses the freeform option `services.kavita.settings` for the application settings file. +- `services.kavita` now uses the free-form option `services.kavita.settings` for the application settings file. The options `services.kavita.ipAdresses` and `services.kavita.port` now exist at `services.kavita.settings.IpAddresses` and `services.kavita.settings.IpAddresses`. The file at `services.kavita.tokenKeyFile` now needs to contain a secret with 512+ bits instead of 128+ bits. -- The `krb5` module has been rewritten and moved to `security.krb5`, moving all options but `security.krb5.enable` and `security.krb5.package` into `security.krb5.settings`. +- `kavita` has been updated to 0.8.0, requiring a manual forced library scan on all libraries for migration. Refer to upstream's [release notes](https://github.com/Kareadita/Kavita/releases/tag/v0.8.0) for details. + +- `krb5` module has been rewritten and moved to `security.krb5`, moving all options but `security.krb5.enable` and `security.krb5.package` into `security.krb5.settings`. - `services.soju` now has a wrapper for the `sojuctl` command, pointed at the service config file. It also has the new option `adminSocket.enable`, which creates a unix admin socket at `/run/soju/admin`. -- Gitea 1.21 upgrade has several breaking changes, including: +- `gitea` upgrade to 1.21 has several breaking changes, including: - Custom themes and other assets that were previously stored in `custom/public/*` now belong in `custom/public/assets/*` - New instances of Gitea using MySQL now ignore the `[database].CHARSET` config option and always use the `utf8mb4` charset, existing instances should migrate via the `gitea doctor convert` CLI command. -- The `services.paperless` module no longer uses the previously downloaded NLTK data stored in `/var/cache/paperless/nltk`. This directory can be removed. +- `services.paperless` module no longer uses the previously downloaded NLTK data stored in `/var/cache/paperless/nltk`. This directory can be removed. -- The `services.teeworlds` module now has a wealth of configuration options, including a new `package` option. +- `services.teeworlds` module now has a wealth of configuration options, including a new `package` option. -- The `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399). +- `hardware.pulseaudio` module now sets permission of pulse user home directory to 755 when running in "systemWide" mode. It fixes [issue 114399](https://github.com/NixOS/nixpkgs/issues/114399). -- The `services.networkmanager.extraConfig` was renamed to `services.networkmanager.settings` and was changed to use the ini type instead of using a multiline string. +- `services.networkmanager.extraConfig` was renamed to `services.networkmanager.settings` and was changed to use the ini type instead of using a multiline string. -- The module `services.github-runner` has been removed. To configure a single GitHub Actions Runner refer to `services.github-runners.*`. Note that this will trigger a new runner registration. +- `services.github-runner` module has been removed. To configure a single GitHub Actions Runner refer to `services.github-runners.*`. Note that this will trigger a new runner registration. -- The `services.slskd` has been refactored to include more configuation options in - the freeform `services.slskd.settings` option, and some defaults (including listen ports) +- `services.slskd` has been refactored to include more configuation options in + the free-form `services.slskd.settings` option, and some defaults (including listen ports) have been changed to match the upstream defaults. Additionally, disk logging is now disabled by default, and the log rotation timer has been removed. The nginx virtualhost option is now of the `vhost-options` type. -- The `btrbk` module now automatically selects and provides required compression +- `services.btrbk` now automatically selects and provides required compression program depending on the configured `stream_compress` option. Since this replaces the need for the `extraPackages` option, this option will be deprecated in future releases. -- The `mpich` package expression now requires `withPm` to be a list, e.g. `"hydra:gforker"` becomes `[ "hydra" "gforker" ]`. +- `mpich` package expression now requires `withPm` to be a list, e.g. `"hydra:gforker"` becomes `[ "hydra" "gforker" ]`. -- When merging systemd unit options (of type `unitOption`), +- `systemd`: when merging unit options (of type `unitOption`), if at least one definition is a list, all those which aren't are now lifted into a list, making it possible to accumulate definitions without resorting to `mkForce`, hence to retain the definitions not anticipating that need. -- YouTrack is bumped to 2023.3. The update is not performed automatically, it requires manual interaction. See the YouTrack section in the manual for details. +- `youtrack` is bumped to 2023.3. The update is not performed automatically, it requires manual interaction. See the YouTrack section in the manual for details. - QtMultimedia has changed its default backend to `QT_MEDIA_BACKEND=ffmpeg` (previously `gstreamer` on Linux or `darwin` on MacOS). The previous native backends remain available but are now minimally maintained. Refer to [upstream documentation](https://doc.qt.io/qt-6/qtmultimedia-index.html#ffmpeg-as-the-default-backend) for further details about each platform. -- The `drbd` out-of-tree Linux kernel driver has been added in version `9.2.7`. With it the DRBD 9.x features can be used instead of the 8.x features provided by the `8.4.11` in-tree driver. +- `drbd` out-of-tree Linux kernel driver has been added in version 9.2.7. With it the DRBD 9.x features can be used instead of the 8.x features provided by the 8.4.11 in-tree driver. -- The oil shell's c++ version is now available as `oils-for-unix`. The python version is still available as `oil` +- [TODO: reword to place an attribute at the front] The oil shell's c++ version is now available as `oils-for-unix`. The python version is still available as `oil` - `documentation.man.mandoc` now by default uses `MANPATH` to set the directories where mandoc will search for manual pages. This enables mandoc to find manual pages in Nix profiles. To set the manual search paths via the `mandoc.conf` configuration file like before, use `documentation.man.mandoc.settings.manpath` instead. -- The `grafana-loki` package was updated to 3.0.0 which includes [breaking changes](https://github.com/grafana/loki/releases/tag/v3.0.0) +- `grafana-loki` package was updated to 3.0.0 which includes [breaking changes](https://github.com/grafana/loki/releases/tag/v3.0.0) diff --git a/nixos/lib/qemu-common.nix b/nixos/lib/qemu-common.nix index b946f62d93dc..f1e19c5b3b72 100644 --- a/nixos/lib/qemu-common.nix +++ b/nixos/lib/qemu-common.nix @@ -35,6 +35,8 @@ rec { aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -machine virt,gic-version=max,accel=kvm:tcg -cpu max"; powerpc64le-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv"; powerpc64-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv"; + riscv32-linux = "${qemuPkg}/bin/qemu-system-riscv32 -machine virt"; + riscv64-linux = "${qemuPkg}/bin/qemu-system-riscv64 -machine virt"; x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max"; }; otherHostGuestMatrix = { diff --git a/nixos/lib/systemd-lib.nix b/nixos/lib/systemd-lib.nix index 198a710f052d..eef49f8c4ef3 100644 --- a/nixos/lib/systemd-lib.nix +++ b/nixos/lib/systemd-lib.nix @@ -1,4 +1,4 @@ -{ config, lib, pkgs }: +{ config, lib, pkgs, utils }: let inherit (lib) @@ -14,10 +14,12 @@ let elem filter filterAttrs + flatten flip head isInt isList + isPath length makeBinPath makeSearchPathOutput @@ -28,6 +30,7 @@ let optional optionalAttrs optionalString + pipe range replaceStrings reverseList @@ -366,9 +369,17 @@ in rec { // optionalAttrs (config.requisite != []) { Requisite = toString config.requisite; } // optionalAttrs (config ? restartTriggers && config.restartTriggers != []) - { X-Restart-Triggers = "${pkgs.writeText "X-Restart-Triggers-${name}" (toString config.restartTriggers)}"; } + { X-Restart-Triggers = "${pkgs.writeText "X-Restart-Triggers-${name}" (pipe config.restartTriggers [ + flatten + (map (x: if isPath x then "${x}" else x)) + toString + ])}"; } // optionalAttrs (config ? reloadTriggers && config.reloadTriggers != []) - { X-Reload-Triggers = "${pkgs.writeText "X-Reload-Triggers-${name}" (toString config.reloadTriggers)}"; } + { X-Reload-Triggers = "${pkgs.writeText "X-Reload-Triggers-${name}" (pipe config.reloadTriggers [ + flatten + (map (x: if isPath x then "${x}" else x)) + toString + ])}"; } // optionalAttrs (config.description != "") { Description = config.description; } // optionalAttrs (config.documentation != []) { @@ -385,8 +396,41 @@ in rec { }; }; - serviceConfig = { config, ... }: { - config.environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}"; + serviceConfig = { name, config, ... }: { + config = { + name = "${name}.service"; + environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}"; + }; + }; + + pathConfig = { name, config, ... }: { + config = { + name = "${name}.path"; + }; + }; + + socketConfig = { name, config, ... }: { + config = { + name = "${name}.socket"; + }; + }; + + sliceConfig = { name, config, ... }: { + config = { + name = "${name}.slice"; + }; + }; + + targetConfig = { name, config, ... }: { + config = { + name = "${name}.target"; + }; + }; + + timerConfig = { name, config, ... }: { + config = { + name = "${name}.timer"; + }; }; stage2ServiceConfig = { @@ -405,6 +449,7 @@ in rec { mountConfig = { config, ... }: { config = { + name = "${utils.escapeSystemdPath config.where}.mount"; mountConfig = { What = config.what; Where = config.where; @@ -418,6 +463,7 @@ in rec { automountConfig = { config, ... }: { config = { + name = "${utils.escapeSystemdPath config.where}.automount"; automountConfig = { Where = config.where; }; @@ -433,8 +479,8 @@ in rec { WantedBy=${concatStringsSep " " def.wantedBy} ''; - targetToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + targetToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = '' [Unit] @@ -442,8 +488,8 @@ in rec { ''; }; - serviceToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + serviceToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def ('' [Service] '' + (let env = cfg.globalEnvironment // def.environment; @@ -452,7 +498,7 @@ in rec { "Environment=${toJSON "${n}=${env.${n}}"}\n"; # systemd max line length is now 1MiB # https://github.com/systemd/systemd/commit/e6dde451a51dc5aaa7f4d98d39b8fe735f73d2af - in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${name}.service’ is too long." else s) (attrNames env)) + in if stringLength s >= 1048576 then throw "The value of the environment variable ‘${n}’ in systemd service ‘${def.name}.service’ is too long." else s) (attrNames env)) + (if def ? reloadIfChanged && def.reloadIfChanged then '' X-ReloadIfChanged=true '' else if (def ? restartIfChanged && !def.restartIfChanged) then '' @@ -463,8 +509,8 @@ in rec { '' + attrsToSection def.serviceConfig); }; - socketToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + socketToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Socket] ${attrsToSection def.socketConfig} @@ -473,40 +519,40 @@ in rec { ''; }; - timerToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + timerToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Timer] ${attrsToSection def.timerConfig} ''; }; - pathToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + pathToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Path] ${attrsToSection def.pathConfig} ''; }; - mountToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + mountToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Mount] ${attrsToSection def.mountConfig} ''; }; - automountToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + automountToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Automount] ${attrsToSection def.automountConfig} ''; }; - sliceToUnit = name: def: - { inherit (def) aliases wantedBy requiredBy upheldBy enable overrideStrategy; + sliceToUnit = def: + { inherit (def) name aliases wantedBy requiredBy upheldBy enable overrideStrategy; text = commonUnitText def '' [Slice] ${attrsToSection def.sliceConfig} diff --git a/nixos/lib/systemd-types.nix b/nixos/lib/systemd-types.nix index c4c5771cff82..f3bc8e06d9cb 100644 --- a/nixos/lib/systemd-types.nix +++ b/nixos/lib/systemd-types.nix @@ -5,8 +5,13 @@ let automountConfig makeUnit mountConfig + pathConfig + sliceConfig + socketConfig stage1ServiceConfig stage2ServiceConfig + targetConfig + timerConfig unitConfig ; @@ -48,29 +53,32 @@ let ; in -rec { +{ units = attrsOf (submodule ({ name, config, ... }: { options = concreteUnitOptions; - config = { unit = mkDefault (makeUnit name config); }; + config = { + name = mkDefault name; + unit = mkDefault (makeUnit name config); + }; })); services = attrsOf (submodule [ stage2ServiceOptions unitConfig stage2ServiceConfig ]); initrdServices = attrsOf (submodule [ stage1ServiceOptions unitConfig stage1ServiceConfig ]); - targets = attrsOf (submodule [ stage2CommonUnitOptions unitConfig ]); - initrdTargets = attrsOf (submodule [ stage1CommonUnitOptions unitConfig ]); + targets = attrsOf (submodule [ stage2CommonUnitOptions unitConfig targetConfig ]); + initrdTargets = attrsOf (submodule [ stage1CommonUnitOptions unitConfig targetConfig ]); - sockets = attrsOf (submodule [ stage2SocketOptions unitConfig ]); - initrdSockets = attrsOf (submodule [ stage1SocketOptions unitConfig ]); + sockets = attrsOf (submodule [ stage2SocketOptions unitConfig socketConfig]); + initrdSockets = attrsOf (submodule [ stage1SocketOptions unitConfig socketConfig ]); - timers = attrsOf (submodule [ stage2TimerOptions unitConfig ]); - initrdTimers = attrsOf (submodule [ stage1TimerOptions unitConfig ]); + timers = attrsOf (submodule [ stage2TimerOptions unitConfig timerConfig ]); + initrdTimers = attrsOf (submodule [ stage1TimerOptions unitConfig timerConfig ]); - paths = attrsOf (submodule [ stage2PathOptions unitConfig ]); - initrdPaths = attrsOf (submodule [ stage1PathOptions unitConfig ]); + paths = attrsOf (submodule [ stage2PathOptions unitConfig pathConfig ]); + initrdPaths = attrsOf (submodule [ stage1PathOptions unitConfig pathConfig ]); - slices = attrsOf (submodule [ stage2SliceOptions unitConfig ]); - initrdSlices = attrsOf (submodule [ stage1SliceOptions unitConfig ]); + slices = attrsOf (submodule [ stage2SliceOptions unitConfig sliceConfig ]); + initrdSlices = attrsOf (submodule [ stage1SliceOptions unitConfig sliceConfig ]); mounts = listOf (submodule [ stage2MountOptions unitConfig mountConfig ]); initrdMounts = listOf (submodule [ stage1MountOptions unitConfig mountConfig ]); diff --git a/nixos/lib/systemd-unit-options.nix b/nixos/lib/systemd-unit-options.nix index fc990a87f0c2..160f2bf9483a 100644 --- a/nixos/lib/systemd-unit-options.nix +++ b/nixos/lib/systemd-unit-options.nix @@ -65,6 +65,14 @@ in rec { ''; }; + name = lib.mkOption { + type = lib.types.str; + description = '' + The name of this systemd unit, including its extension. + This can be used to refer to this unit from other systemd units. + ''; + }; + overrideStrategy = mkOption { default = "asDropinIfExists"; type = types.enum [ "asDropinIfExists" "asDropin" ]; diff --git a/nixos/lib/utils.nix b/nixos/lib/utils.nix index 4992113bdbd2..c1c1828a2c12 100644 --- a/nixos/lib/utils.nix +++ b/nixos/lib/utils.nix @@ -35,7 +35,8 @@ let inherit (lib.strings) toJSON normalizePath escapeC; in -rec { +let +utils = rec { # Copy configuration files to avoid having the entire sources in the system closure copyFile = filePath: pkgs.runCommand (builtins.unsafeDiscardStringContext (baseNameOf filePath)) {} '' @@ -262,11 +263,12 @@ rec { filter (x: !(elem (getName x) namesToRemove)) packages; systemdUtils = { - lib = import ./systemd-lib.nix { inherit lib config pkgs; }; + lib = import ./systemd-lib.nix { inherit lib config pkgs utils; }; unitOptions = import ./systemd-unit-options.nix { inherit lib systemdUtils; }; types = import ./systemd-types.nix { inherit lib systemdUtils pkgs; }; network = { units = import ./systemd-network-units.nix { inherit lib systemdUtils; }; }; }; -} +}; +in utils diff --git a/nixos/modules/config/malloc.nix b/nixos/modules/config/malloc.nix index 4214ae598315..e414970b0be5 100644 --- a/nixos/modules/config/malloc.nix +++ b/nixos/modules/config/malloc.nix @@ -9,8 +9,23 @@ let graphene-hardened = { libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc.so"; description = '' - An allocator designed to mitigate memory corruption attacks, such as - those caused by use-after-free bugs. + Hardened memory allocator coming from GrapheneOS project. + The default configuration template has all normal optional security + features enabled and is quite aggressive in terms of sacrificing + performance and memory usage for security. + ''; + }; + + graphene-hardened-light = { + libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc-light.so"; + description = '' + Hardened memory allocator coming from GrapheneOS project. + The light configuration template disables the slab quarantines, + write after free check, slot randomization and raises the guard + slab interval from 1 to 8 but leaves zero-on-free and slab canaries enabled. + The light configuration has solid performance and memory usage while still + being far more secure than mainstream allocators with much better security + properties. ''; }; diff --git a/nixos/modules/config/no-x-libs.nix b/nixos/modules/config/no-x-libs.nix index c9a133d0558a..1d7976cef36a 100644 --- a/nixos/modules/config/no-x-libs.nix +++ b/nixos/modules/config/no-x-libs.nix @@ -31,8 +31,11 @@ with lib; cairo = super.cairo.override { x11Support = false; }; dbus = super.dbus.override { x11Support = false; }; fastfetch = super.fastfetch.override { vulkanSupport = false; waylandSupport = false; x11Support = false; }; + ffmpeg = super.ffmpeg.override { ffmpegVariant = "headless"; }; ffmpeg_4 = super.ffmpeg_4.override { ffmpegVariant = "headless"; }; ffmpeg_5 = super.ffmpeg_5.override { ffmpegVariant = "headless"; }; + ffmpeg_6 = super.ffmpeg_6.override { ffmpegVariant = "headless"; }; + ffmpeg_7 = super.ffmpeg_7.override { ffmpegVariant = "headless"; }; # dep of graphviz, libXpm is optional for Xpm support gd = super.gd.override { withXorg = false; }; ghostscript = super.ghostscript.override { cupsSupport = false; x11Support = false; }; @@ -44,7 +47,7 @@ with lib; gst_all_1 = super.gst_all_1 // { gst-plugins-bad = super.gst_all_1.gst-plugins-bad.override { guiSupport = false; }; gst-plugins-base = super.gst_all_1.gst-plugins-base.override { enableWayland = false; enableX11 = false; }; - gst-plugins-good = super.gst_all_1.gst-plugins-good.override { enableX11 = false; }; + gst-plugins-good = super.gst_all_1.gst-plugins-good.override { enableWayland = false; enableX11 = false; gtkSupport = false; qt5Support = false; qt6Support = false; }; }; imagemagick = super.imagemagick.override { libX11Support = false; libXtSupport = false; }; imagemagickBig = super.imagemagickBig.override { libX11Support = false; libXtSupport = false; }; diff --git a/nixos/modules/config/terminfo.nix b/nixos/modules/config/terminfo.nix index 4b58605aa7f1..b538d749ffcb 100644 --- a/nixos/modules/config/terminfo.nix +++ b/nixos/modules/config/terminfo.nix @@ -31,7 +31,7 @@ with lib; # attrNames (filterAttrs # (_: drv: (builtins.tryEval (isDerivation drv && drv ? terminfo)).value) # pkgs) - environment.systemPackages = mkIf config.environment.enableAllTerminfo (map (x: x.terminfo) (with pkgs; [ + environment.systemPackages = mkIf config.environment.enableAllTerminfo (map (x: x.terminfo) (with pkgs.pkgsBuildBuild; [ alacritty contour foot diff --git a/nixos/modules/config/xdg/terminal-exec.nix b/nixos/modules/config/xdg/terminal-exec.nix new file mode 100644 index 000000000000..daf2055d2e90 --- /dev/null +++ b/nixos/modules/config/xdg/terminal-exec.nix @@ -0,0 +1,54 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + cfg = config.xdg.terminal-exec; + inherit (lib) mkIf mkEnableOption mkOption mkPackageOption types; +in +{ + meta.maintainers = with lib.maintainers; [ Cryolitia ]; + + ###### interface + + options = { + xdg.terminal-exec = { + enable = mkEnableOption "xdg-terminal-exec, the [proposed](https://gitlab.freedesktop.org/xdg/xdg-specs/-/merge_requests/46) Default Terminal Execution Specification"; + package = mkPackageOption pkgs "xdg-terminal-exec" { }; + settings = mkOption { + type = with types; attrsOf (listOf str); + default = { }; + description = '' + Configuration options for the Default Terminal Execution Specification. + + The keys are the desktop environments that are matched (case-insensitively) against `$XDG_CURRENT_DESKTOP`, + or `default` which is used when the current desktop environment is not found in the configuration. + The values are a list of terminals' [desktop file IDs](https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s02.html#desktop-file-id) to try in order of decreasing priority. + ''; + example = { + default = [ "kitty.desktop" ]; + GNOME = [ "com.raggesilver.BlackBox.desktop" "org.gnome.Terminal.desktop" ]; + }; + }; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + environment = { + systemPackages = [ cfg.package ]; + + etc = lib.mapAttrs' ( + desktop: terminals: + # map desktop name such as GNOME to `xdg/gnome-xdg-terminals.list`, default to `xdg/xdg-terminals.list` + lib.nameValuePair ( + "xdg/${if desktop == "default" then "" else "${lib.toLower desktop}-"}xdg-terminals.list" + ) { text = lib.concatLines terminals; } + ) cfg.settings; + }; + }; +} diff --git a/nixos/modules/hardware/openrazer.nix b/nixos/modules/hardware/openrazer.nix index 99b551054323..5ba6abfdb3d7 100644 --- a/nixos/modules/hardware/openrazer.nix +++ b/nixos/modules/hardware/openrazer.nix @@ -19,7 +19,9 @@ let [Startup] sync_effects_enabled = ${toPyBoolStr cfg.syncEffectsEnabled} devices_off_on_screensaver = ${toPyBoolStr cfg.devicesOffOnScreensaver} - mouse_battery_notifier = ${toPyBoolStr cfg.mouseBatteryNotifier} + battery_notifier = ${toPyBoolStr (cfg.mouseBatteryNotifier || cfg.batteryNotifier.enable)} + battery_notifier_freq = ${builtins.toString cfg.batteryNotifier.frequency} + battery_notifier_percent = ${builtins.toString cfg.batteryNotifier.percentage} [Statistics] key_statistics = ${toPyBoolStr cfg.keyStatistics} @@ -86,6 +88,41 @@ in ''; }; + batteryNotifier = mkOption { + description = '' + Settings for device battery notifications. + ''; + default = {}; + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = true; + description = '' + Mouse battery notifier. + ''; + }; + frequency = mkOption { + type = types.int; + default = 600; + description = '' + How often battery notifications should be shown (in seconds). + A value of 0 disables notifications. + ''; + }; + + percentage = mkOption { + type = types.int; + default = 33; + description = '' + At what battery percentage the device should reach before + sending notifications. + ''; + }; + }; + }; + }; + keyStatistics = mkOption { type = types.bool; default = false; @@ -107,6 +144,13 @@ in }; config = mkIf cfg.enable { + warnings = flatten [ + (optional cfg.mouseBatteryNotifier '' + The option openrazer.mouseBatteryNotifier is deprecated. + Please use openrazer.batteryNotifier instead to enable and configure battery notifications. + '') + ]; + boot.extraModulePackages = [ kernelPackages.openrazer ]; boot.kernelModules = drivers; @@ -127,15 +171,15 @@ in systemd.user.services.openrazer-daemon = { description = "Daemon to manage razer devices in userspace"; unitConfig.Documentation = "man:openrazer-daemon(8)"; - # Requires a graphical session so the daemon knows when the screensaver - # starts. See the 'devicesOffOnScreensaver' option. - wantedBy = [ "graphical-session.target" ]; - partOf = [ "graphical-session.target" ]; - serviceConfig = { - Type = "dbus"; - BusName = "org.razer"; - ExecStart = "${daemonExe} --foreground"; - Restart = "always"; + # Requires a graphical session so the daemon knows when the screensaver + # starts. See the 'devicesOffOnScreensaver' option. + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + serviceConfig = { + Type = "dbus"; + BusName = "org.razer"; + ExecStart = "${daemonExe} --foreground"; + Restart = "always"; }; }; }; diff --git a/nixos/modules/installer/tools/tools.nix b/nixos/modules/installer/tools/tools.nix index e7f9990e9632..7f16b97440c1 100644 --- a/nixos/modules/installer/tools/tools.nix +++ b/nixos/modules/installer/tools/tools.nix @@ -185,7 +185,7 @@ in # }; # Enable touchpad support (enabled default in most desktopManager). - # services.xserver.libinput.enable = true; + # services.libinput.enable = true; # Define a user account. Don't forget to set a password with ‘passwd’. # users.users.alice = { diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix index 2a25f8e56468..26323e14b901 100644 --- a/nixos/modules/misc/documentation.nix +++ b/nixos/modules/misc/documentation.nix @@ -101,6 +101,7 @@ let libPath = filter (pkgs.path + "/lib"); pkgsLibPath = filter (pkgs.path + "/pkgs/pkgs-lib"); nixosPath = filter (pkgs.path + "/nixos"); + NIX_ABORT_ON_WARN = warningsAreErrors; modules = "[ " + concatMapStringsSep " " (p: ''"${removePrefix "${modulesPath}/" (toString p)}"'') docModules.lazy diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 2a2556104731..36ab59020cc6 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -45,6 +45,7 @@ ./config/xdg/portals/lxqt.nix ./config/xdg/portals/wlr.nix ./config/xdg/sounds.nix + ./config/xdg/terminal-exec.nix ./config/zram.nix ./hardware/acpilight.nix ./hardware/all-firmware.nix @@ -325,6 +326,7 @@ ./security/duosec.nix ./security/google_oslogin.nix ./security/ipa.nix + ./security/isolate.nix ./security/krb5 ./security/lock-kernel-modules.nix ./security/misc.nix @@ -558,8 +560,9 @@ ./services/hardware/joycond.nix ./services/hardware/kanata.nix ./services/hardware/lcd.nix + ./services/hardware/libinput.nix ./services/hardware/lirc.nix - ./services/hardware/nvidia-container-toolkit-cdi-generator + ./services/hardware/nvidia-container-toolkit ./services/hardware/monado.nix ./services/hardware/nvidia-optimus.nix ./services/hardware/openrgb.nix @@ -944,6 +947,7 @@ ./services/networking/charybdis.nix ./services/networking/chisel-server.nix ./services/networking/cjdns.nix + ./services/networking/clatd.nix ./services/networking/cloudflare-dyndns.nix ./services/networking/cloudflared.nix ./services/networking/cntlm.nix @@ -1012,6 +1016,7 @@ ./services/networking/icecream/daemon.nix ./services/networking/icecream/scheduler.nix ./services/networking/imaginary.nix + ./services/networking/inadyn.nix ./services/networking/inspircd.nix ./services/networking/iodine.nix ./services/networking/iperf3.nix @@ -1026,6 +1031,7 @@ ./services/networking/jigasi.nix ./services/networking/jitsi-videobridge.nix ./services/networking/jool.nix + ./services/networking/jotta-cli.nix ./services/networking/kea.nix ./services/networking/keepalived/default.nix ./services/networking/keybase.nix @@ -1070,6 +1076,7 @@ ./services/networking/ndppd.nix ./services/networking/nebula.nix ./services/networking/netbird.nix + ./services/networking/netbird/server.nix ./services/networking/netclient.nix ./services/networking/networkd-dispatcher.nix ./services/networking/networkmanager.nix @@ -1160,6 +1167,7 @@ ./services/networking/strongswan.nix ./services/networking/stubby.nix ./services/networking/stunnel.nix + ./services/networking/sunshine.nix ./services/networking/supplicant.nix ./services/networking/supybot.nix ./services/networking/syncplay.nix @@ -1223,6 +1231,7 @@ ./services/search/elasticsearch-curator.nix ./services/search/elasticsearch.nix ./services/search/hound.nix + ./services/search/manticore.nix ./services/search/meilisearch.nix ./services/search/opensearch.nix ./services/search/qdrant.nix @@ -1250,8 +1259,8 @@ ./services/security/kanidm.nix ./services/security/munge.nix ./services/security/nginx-sso.nix - ./services/security/oauth2_proxy.nix - ./services/security/oauth2_proxy_nginx.nix + ./services/security/oauth2-proxy.nix + ./services/security/oauth2-proxy-nginx.nix ./services/security/opensnitch.nix ./services/security/pass-secret-service.nix ./services/security/physlock.nix @@ -1334,6 +1343,7 @@ ./services/web-apps/dolibarr.nix ./services/web-apps/engelsystem.nix ./services/web-apps/ethercalc.nix + ./services/web-apps/firefly-iii.nix ./services/web-apps/fluidd.nix ./services/web-apps/freshrss.nix ./services/web-apps/galene.nix @@ -1467,7 +1477,6 @@ ./services/x11/gdk-pixbuf.nix ./services/x11/hardware/cmt.nix ./services/x11/hardware/digimend.nix - ./services/x11/hardware/libinput.nix ./services/x11/hardware/synaptics.nix ./services/x11/hardware/wacom.nix ./services/x11/imwheel.nix diff --git a/nixos/modules/profiles/graphical.nix b/nixos/modules/profiles/graphical.nix index 8cc31652f807..72b865c584f0 100644 --- a/nixos/modules/profiles/graphical.nix +++ b/nixos/modules/profiles/graphical.nix @@ -7,10 +7,12 @@ services.xserver = { enable = true; desktopManager.plasma5.enable = true; - libinput.enable = true; # for touchpad support on many laptops }; - services.displayManager.sddm.enable = true; + services = { + displayManager.sddm.enable = true; + libinput.enable = true; # for touchpad support on many laptops + }; # Enable sound in virtualbox appliances. hardware.pulseaudio.enable = true; diff --git a/nixos/modules/programs/evince.nix b/nixos/modules/programs/evince.nix index cffc5127f10a..a27e75e6626d 100644 --- a/nixos/modules/programs/evince.nix +++ b/nixos/modules/programs/evince.nix @@ -2,28 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.programs.evince; in { - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "evince" "enable" ] - [ "programs" "evince" "enable" ]) - ]; - ###### interface options = { programs.evince = { - enable = mkEnableOption "Evince, the GNOME document viewer"; + enable = lib.mkEnableOption "Evince, the GNOME document viewer"; - package = mkPackageOption pkgs "evince" { }; + package = lib.mkPackageOption pkgs "evince" { }; }; @@ -32,7 +23,7 @@ in { ###### implementation - config = mkIf config.programs.evince.enable { + config = lib.mkIf config.programs.evince.enable { environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/programs/fcast-receiver.nix b/nixos/modules/programs/fcast-receiver.nix index 8da07a66e222..2e4e6bf8b242 100644 --- a/nixos/modules/programs/fcast-receiver.nix +++ b/nixos/modules/programs/fcast-receiver.nix @@ -11,11 +11,11 @@ in }; options.programs.fcast-receiver = { - enable = mkEnableOption (lib.mdDoc "FCast Receiver"); + enable = mkEnableOption "FCast Receiver"; openFirewall = mkOption { type = types.bool; default = false; - description = lib.mdDoc '' + description = '' Open ports needed for the functionality of the program. ''; }; diff --git a/nixos/modules/programs/file-roller.nix b/nixos/modules/programs/file-roller.nix index 4799f42d630b..f64bd732855b 100644 --- a/nixos/modules/programs/file-roller.nix +++ b/nixos/modules/programs/file-roller.nix @@ -2,28 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.programs.file-roller; in { - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "file-roller" "enable" ] - [ "programs" "file-roller" "enable" ]) - ]; - ###### interface options = { programs.file-roller = { - enable = mkEnableOption "File Roller, an archive manager for GNOME"; + enable = lib.mkEnableOption "File Roller, an archive manager for GNOME"; - package = mkPackageOption pkgs [ "gnome" "file-roller" ] { }; + package = lib.mkPackageOption pkgs [ "gnome" "file-roller" ] { }; }; @@ -32,7 +23,7 @@ in { ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/programs/fzf.nix b/nixos/modules/programs/fzf.nix index 0e7e519f0436..66ad7d418de6 100644 --- a/nixos/modules/programs/fzf.nix +++ b/nixos/modules/programs/fzf.nix @@ -15,11 +15,12 @@ in environment.systemPackages = lib.mkIf (cfg.keybindings || cfg.fuzzyCompletion) [ pkgs.fzf ]; programs = { - bash.interactiveShellInit = lib.optionalString cfg.fuzzyCompletion '' + # load after programs.bash.enableCompletion + bash.promptPluginInit = lib.mkAfter (lib.optionalString cfg.fuzzyCompletion '' source ${pkgs.fzf}/share/fzf/completion.bash '' + lib.optionalString cfg.keybindings '' source ${pkgs.fzf}/share/fzf/key-bindings.bash - ''; + ''); zsh = { interactiveShellInit = lib.optionalString (!config.programs.zsh.ohMyZsh.enable) diff --git a/nixos/modules/programs/gnome-disks.nix b/nixos/modules/programs/gnome-disks.nix index 4b128b471265..954f1fd9bc07 100644 --- a/nixos/modules/programs/gnome-disks.nix +++ b/nixos/modules/programs/gnome-disks.nix @@ -2,29 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-disks" "enable" ] - [ "programs" "gnome-disks" "enable" ]) - ]; - ###### interface options = { programs.gnome-disks = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Disks daemon, a program designed to @@ -39,7 +30,7 @@ with lib; ###### implementation - config = mkIf config.programs.gnome-disks.enable { + config = lib.mkIf config.programs.gnome-disks.enable { environment.systemPackages = [ pkgs.gnome.gnome-disk-utility ]; diff --git a/nixos/modules/programs/gnome-terminal.nix b/nixos/modules/programs/gnome-terminal.nix index 71a6b217880c..a5dda83edd11 100644 --- a/nixos/modules/programs/gnome-terminal.nix +++ b/nixos/modules/programs/gnome-terminal.nix @@ -2,8 +2,6 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.programs.gnome-terminal; @@ -13,21 +11,14 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2019-08-19 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-terminal-server" "enable" ] - [ "programs" "gnome-terminal" "enable" ]) - ]; - options = { - programs.gnome-terminal.enable = mkEnableOption "GNOME Terminal"; + programs.gnome-terminal.enable = lib.mkEnableOption "GNOME Terminal"; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ pkgs.gnome.gnome-terminal ]; services.dbus.packages = [ pkgs.gnome.gnome-terminal ]; systemd.packages = [ pkgs.gnome.gnome-terminal ]; diff --git a/nixos/modules/programs/gpaste.nix b/nixos/modules/programs/gpaste.nix index 1c34c86eb853..32b81434bdd9 100644 --- a/nixos/modules/programs/gpaste.nix +++ b/nixos/modules/programs/gpaste.nix @@ -1,22 +1,13 @@ # GPaste. { config, lib, pkgs, ... }: -with lib; - { - # Added 2019-08-09 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gpaste" "enable" ] - [ "programs" "gpaste" "enable" ]) - ]; - ###### interface options = { programs.gpaste = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GPaste, a clipboard manager. @@ -26,7 +17,7 @@ with lib; }; ###### implementation - config = mkIf config.programs.gpaste.enable { + config = lib.mkIf config.programs.gpaste.enable { environment.systemPackages = [ pkgs.gnome.gpaste ]; services.dbus.packages = [ pkgs.gnome.gpaste ]; systemd.packages = [ pkgs.gnome.gpaste ]; diff --git a/nixos/modules/programs/seahorse.nix b/nixos/modules/programs/seahorse.nix index c0a356bff57c..53fff50e0a8b 100644 --- a/nixos/modules/programs/seahorse.nix +++ b/nixos/modules/programs/seahorse.nix @@ -2,25 +2,15 @@ { config, pkgs, lib, ... }: -with lib; - { - # Added 2019-08-27 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "seahorse" "enable" ] - [ "programs" "seahorse" "enable" ]) - ]; - - ###### interface options = { programs.seahorse = { - enable = mkEnableOption "Seahorse, a GNOME application for managing encryption keys and passwords in the GNOME Keyring"; + enable = lib.mkEnableOption "Seahorse, a GNOME application for managing encryption keys and passwords in the GNOME Keyring"; }; @@ -29,9 +19,9 @@ with lib; ###### implementation - config = mkIf config.programs.seahorse.enable { + config = lib.mkIf config.programs.seahorse.enable { - programs.ssh.askPassword = mkDefault "${pkgs.gnome.seahorse}/libexec/seahorse/ssh-askpass"; + programs.ssh.askPassword = lib.mkDefault "${pkgs.gnome.seahorse}/libexec/seahorse/ssh-askpass"; environment.systemPackages = [ pkgs.gnome.seahorse diff --git a/nixos/modules/programs/singularity.nix b/nixos/modules/programs/singularity.nix index 981417389eb2..f4c0a6fe487e 100644 --- a/nixos/modules/programs/singularity.nix +++ b/nixos/modules/programs/singularity.nix @@ -1,4 +1,9 @@ -{ config, pkgs, lib, ... }: +{ + config, + pkgs, + lib, + ... +}: with lib; let @@ -12,9 +17,7 @@ in Whether to install Singularity/Apptainer with system-level overriding such as SUID support. ''; }; - package = mkPackageOption pkgs "singularity" { - example = "apptainer"; - }; + package = mkPackageOption pkgs "singularity" { example = "apptainer"; }; packageOverriden = mkOption { type = types.nullOr types.package; default = null; @@ -75,17 +78,19 @@ in }; config = mkIf cfg.enable { - programs.singularity.packageOverriden = (cfg.package.override ( - optionalAttrs cfg.enableExternalLocalStateDir { - externalLocalStateDir = "/var/lib"; - } // optionalAttrs cfg.enableFakeroot { - newuidmapPath = "/run/wrappers/bin/newuidmap"; - newgidmapPath = "/run/wrappers/bin/newgidmap"; - } // optionalAttrs cfg.enableSuid { - enableSuid = true; - starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid"; - } - )); + programs.singularity.packageOverriden = ( + cfg.package.override ( + optionalAttrs cfg.enableExternalLocalStateDir { externalLocalStateDir = "/var/lib"; } + // optionalAttrs cfg.enableFakeroot { + newuidmapPath = "/run/wrappers/bin/newuidmap"; + newgidmapPath = "/run/wrappers/bin/newgidmap"; + } + // optionalAttrs cfg.enableSuid { + enableSuid = true; + starterSuidPath = "/run/wrappers/bin/${cfg.package.projectName}-suid"; + } + ) + ); environment.systemPackages = [ cfg.packageOverriden ]; security.wrappers."${cfg.packageOverriden.projectName}-suid" = mkIf cfg.enableSuid { setuid = true; @@ -97,5 +102,4 @@ in "d /var/lib/${cfg.packageOverriden.projectName}/mnt/session 0770 root root -" ]; }; - } diff --git a/nixos/modules/programs/wshowkeys.nix b/nixos/modules/programs/wshowkeys.nix index f7b71d2bb0c8..1fef33e04717 100644 --- a/nixos/modules/programs/wshowkeys.nix +++ b/nixos/modules/programs/wshowkeys.nix @@ -1,27 +1,31 @@ -{ config, lib, pkgs, ... }: - -with lib; - +{ + config, + lib, + pkgs, + ... +}: let cfg = config.programs.wshowkeys; -in { - meta.maintainers = with maintainers; [ primeos ]; - +in +{ options = { programs.wshowkeys = { - enable = mkEnableOption '' + enable = lib.mkEnableOption '' wshowkeys (displays keypresses on screen on supported Wayland compositors). It requires root permissions to read input events, but these permissions are dropped after startup''; + package = lib.mkPackageOption pkgs "wshowkeys" { }; }; }; - config = mkIf cfg.enable { - security.wrappers.wshowkeys = - { setuid = true; - owner = "root"; - group = "root"; - source = "${pkgs.wshowkeys}/bin/wshowkeys"; - }; + config = lib.mkIf cfg.enable { + security.wrappers.wshowkeys = { + setuid = true; + owner = "root"; + group = "root"; + source = lib.getExe cfg.package; + }; }; + + meta.maintainers = with lib.maintainers; [ primeos ]; } diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix index 7fb75f42db1f..e755b5f0ee53 100644 --- a/nixos/modules/security/duosec.nix +++ b/nixos/modules/security/duosec.nix @@ -200,7 +200,8 @@ in unitConfig.DefaultDependencies = false; script = '' if test -f "${cfg.secretKeyFile}"; then - mkdir -m 0755 -p /etc/duo + mkdir -p /etc/duo + chmod 0755 /etc/duo umask 0077 conf="$(mktemp)" @@ -222,7 +223,8 @@ in unitConfig.DefaultDependencies = false; script = '' if test -f "${cfg.secretKeyFile}"; then - mkdir -m 0755 -p /etc/duo + mkdir -p /etc/duo + chmod 0755 /etc/duo umask 0077 conf="$(mktemp)" diff --git a/nixos/modules/security/isolate.nix b/nixos/modules/security/isolate.nix new file mode 100644 index 000000000000..3cc0176f3db3 --- /dev/null +++ b/nixos/modules/security/isolate.nix @@ -0,0 +1,133 @@ +{ config, lib, pkgs, ... }: + +let + inherit (lib) mkEnableOption mkPackageOption mkOption types mkIf maintainers; + + cfg = config.security.isolate; + configFile = pkgs.writeText "isolate-config.cf" '' + box_root=${cfg.boxRoot} + lock_root=${cfg.lockRoot} + cg_root=${cfg.cgRoot} + first_uid=${toString cfg.firstUid} + first_gid=${toString cfg.firstGid} + num_boxes=${toString cfg.numBoxes} + restricted_init=${if cfg.restrictedInit then "1" else "0"} + ${cfg.extraConfig} + ''; + isolate = pkgs.symlinkJoin { + name = "isolate-wrapped-${pkgs.isolate.version}"; + + paths = [ pkgs.isolate ]; + + nativeBuildInputs = [ pkgs.makeWrapper ]; + + postBuild = '' + wrapProgram $out/bin/isolate \ + --set ISOLATE_CONFIG_FILE ${configFile} + + wrapProgram $out/bin/isolate-cg-keeper \ + --set ISOLATE_CONFIG_FILE ${configFile} + ''; + }; +in +{ + options.security.isolate = { + enable = mkEnableOption '' + Sandbox for securely executing untrusted programs + ''; + + package = mkPackageOption pkgs "isolate-unwrapped" { }; + + boxRoot = mkOption { + type = types.path; + default = "/var/lib/isolate/boxes"; + description = '' + All sandboxes are created under this directory. + To avoid symlink attacks, this directory and all its ancestors + must be writeable only by root. + ''; + }; + + lockRoot = mkOption { + type = types.path; + default = "/run/isolate/locks"; + description = '' + Directory where lock files are created. + ''; + }; + + cgRoot = mkOption { + type = types.str; + default = "auto:/run/isolate/cgroup"; + description = '' + Control group which subgroups are placed under. + Either an explicit path to a subdirectory in cgroupfs, or "auto:file" to read + the path from "file", where it is put by `isolate-cg-helper`. + ''; + }; + + firstUid = mkOption { + type = types.numbers.between 1000 65533; + default = 60000; + description = '' + Start of block of UIDs reserved for sandboxes. + ''; + }; + + firstGid = mkOption { + type = types.numbers.between 1000 65533; + default = 60000; + description = '' + Start of block of GIDs reserved for sandboxes. + ''; + }; + + numBoxes = mkOption { + type = types.numbers.between 1000 65533; + default = 1000; + description = '' + Number of UIDs and GIDs to reserve, starting from + {option}`firstUid` and {option}`firstGid`. + ''; + }; + + restrictedInit = mkOption { + type = types.bool; + default = false; + description = '' + If true, only root can create sandboxes. + ''; + }; + + extraConfig = mkOption { + type = types.str; + default = ""; + description = '' + Extra configuration to append to the configuration file. + ''; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ + isolate + ]; + + systemd.services.isolate = { + description = "Isolate control group hierarchy daemon"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "notify"; + ExecStart = "${isolate}/bin/isolate-cg-keeper"; + Slice = "isolate.slice"; + Delegate = true; + }; + }; + + systemd.slices.isolate = { + description = "Isolate sandbox slice"; + }; + + meta.maintainers = with maintainers; [ virchau13 ]; + }; +} diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix index a9bd28b15479..5d3bed2fb02c 100644 --- a/nixos/modules/security/pam.nix +++ b/nixos/modules/security/pam.nix @@ -1044,9 +1044,7 @@ in See [issue #31611](https://github.com/NixOS/nixpkgs/issues/31611) ::: ''; - example = [ "/etc/ssh/authorized_keys.d/%u" ]; - default = config.services.openssh.authorizedKeysFiles; - defaultText = literalExpression "config.services.openssh.authorizedKeysFiles"; + default = [ "/etc/ssh/authorized_keys.d/%u" ]; }; }; diff --git a/nixos/modules/services/backup/znapzend.nix b/nixos/modules/services/backup/znapzend.nix index 71e5977c4464..7f2c89edbf37 100644 --- a/nixos/modules/services/backup/znapzend.nix +++ b/nixos/modules/services/backup/znapzend.nix @@ -315,6 +315,14 @@ in ''; }; + mailErrorSummaryTo = mkOption { + type = singleLineStr; + default = ""; + description = '' + Email address to send a summary to if "send task(s) failed". + ''; + }; + noDestroy = mkOption { type = bool; default = false; @@ -455,6 +463,8 @@ in "--loglevel=${cfg.logLevel}" (optionalString cfg.noDestroy "--nodestroy") (optionalString cfg.autoCreation "--autoCreation") + (optionalString (cfg.mailErrorSummaryTo != "") + "--mailErrorSummaryTo=${cfg.mailErrorSummaryTo}") (optionalString (enabledFeatures != []) "--features=${concatStringsSep "," enabledFeatures}") ]; in "${pkgs.znapzend}/bin/znapzend ${args}"; diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix index 8a386b4848b9..8a9d8c210b34 100644 --- a/nixos/modules/services/databases/postgresql.nix +++ b/nixos/modules/services/databases/postgresql.nix @@ -1,8 +1,31 @@ { config, lib, pkgs, ... }: -with lib; - let + inherit (lib) + attrValues + concatMapStrings + concatStringsSep + const + elem + filterAttrs + isString + literalExpression + mapAttrs + mapAttrsToList + mkAfter + mkBefore + mkDefault + mkEnableOption + mkIf + mkMerge + mkOption + mkPackageOption + mkRemovedOptionModule + mkRenamedOptionModule + optionalString + types + versionAtLeast + ; cfg = config.services.postgresql; @@ -14,7 +37,7 @@ let # package = pkgs.postgresql_; # }; # works. - base = if cfg.enableJIT then cfg.package.withJIT else cfg.package; + base = if cfg.enableJIT then cfg.package.withJIT else cfg.package.withoutJIT; in if cfg.extraPlugins == [] then base @@ -24,7 +47,7 @@ let if true == value then "yes" else if false == value then "no" else if isString value then "'${lib.replaceStrings ["'"] ["''"] value}'" - else toString value; + else builtins.toString value; # The main PostgreSQL configuration file. configFile = pkgs.writeTextDir "postgresql.conf" (concatStringsSep "\n" (mapAttrsToList (n: v: "${n} = ${toStr v}") (filterAttrs (const (x: x != null)) cfg.settings))); @@ -439,7 +462,7 @@ in config = mkIf cfg.enable { assertions = map ({ name, ensureDBOwnership, ... }: { - assertion = ensureDBOwnership -> builtins.elem name cfg.ensureDatabases; + assertion = ensureDBOwnership -> elem name cfg.ensureDatabases; message = '' For each database user defined with `services.postgresql.ensureUsers` and `ensureDBOwnership = true;`, a database with the same name must be defined @@ -537,7 +560,7 @@ in # Wait for PostgreSQL to be ready to accept connections. postStart = '' - PSQL="psql --port=${toString cfg.settings.port}" + PSQL="psql --port=${builtins.toString cfg.settings.port}" while ! $PSQL -d postgres -c "" 2> /dev/null; do if ! kill -0 "$MAINPID"; then exit 1; fi diff --git a/nixos/modules/services/databases/redis.nix b/nixos/modules/services/databases/redis.nix index 1da2fa9f1160..ad88a4f589a2 100644 --- a/nixos/modules/services/databases/redis.nix +++ b/nixos/modules/services/databases/redis.nix @@ -57,9 +57,9 @@ in { package = mkPackageOption pkgs "redis" { }; vmOverCommit = mkEnableOption '' - setting of vm.overcommit_memory to 1 + set `vm.overcommit_memory` sysctl to 1 (Suggested for Background Saving: ) - ''; + '' // { default = true; }; servers = mkOption { type = with types; attrsOf (submodule ({ config, name, ... }: { @@ -312,10 +312,9 @@ in { ''; }) enabledServers); - boot.kernel.sysctl = mkMerge [ - { "vm.nr_hugepages" = "0"; } - ( mkIf cfg.vmOverCommit { "vm.overcommit_memory" = "1"; } ) - ]; + boot.kernel.sysctl = mkIf cfg.vmOverCommit { + "vm.overcommit_memory" = "1"; + }; networking.firewall.allowedTCPPorts = concatMap (conf: optional conf.openFirewall conf.port diff --git a/nixos/modules/services/desktop-managers/plasma6.nix b/nixos/modules/services/desktop-managers/plasma6.nix index 856d36b8a303..842b0716b928 100644 --- a/nixos/modules/services/desktop-managers/plasma6.nix +++ b/nixos/modules/services/desktop-managers/plasma6.nix @@ -238,7 +238,7 @@ in { services.system-config-printer.enable = mkIf config.services.printing.enable (mkDefault true); services.udisks2.enable = true; services.upower.enable = config.powerManagement.enable; - services.xserver.libinput.enable = mkDefault true; + services.libinput.enable = mkDefault true; # Extra UDEV rules used by Solid services.udev.packages = [ @@ -286,6 +286,15 @@ in { kde-smartcard = lib.mkIf config.security.pam.p11.enable { p11Auth = true; }; }; + security.wrappers = { + kwin_wayland = { + owner = "root"; + group = "root"; + capabilities = "cap_sys_nice+ep"; + source = "${lib.getBin pkgs.kdePackages.kwin}/bin/kwin_wayland"; + }; + }; + programs.dconf.enable = true; programs.firefox.nativeMessagingHosts.packages = [kdePackages.plasma-browser-integration]; diff --git a/nixos/modules/services/desktops/gnome/at-spi2-core.nix b/nixos/modules/services/desktops/gnome/at-spi2-core.nix index 446f363fce83..6ed5b198fe4f 100644 --- a/nixos/modules/services/desktops/gnome/at-spi2-core.nix +++ b/nixos/modules/services/desktops/gnome/at-spi2-core.nix @@ -2,30 +2,19 @@ { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; ###### interface - - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "at-spi2-core" "enable" ] - [ "services" "gnome" "at-spi2-core" "enable" ] - ) - ]; - options = { services.gnome.at-spi2-core = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable at-spi2-core, a service for the Assistive Technologies @@ -43,14 +32,14 @@ with lib; ###### implementation - config = mkMerge [ - (mkIf config.services.gnome.at-spi2-core.enable { + config = lib.mkMerge [ + (lib.mkIf config.services.gnome.at-spi2-core.enable { environment.systemPackages = [ pkgs.at-spi2-core ]; services.dbus.packages = [ pkgs.at-spi2-core ]; systemd.packages = [ pkgs.at-spi2-core ]; }) - (mkIf (!config.services.gnome.at-spi2-core.enable) { + (lib.mkIf (!config.services.gnome.at-spi2-core.enable) { environment.sessionVariables = { NO_AT_BRIDGE = "1"; GTK_A11Y = "none"; diff --git a/nixos/modules/services/desktops/gnome/evolution-data-server.nix b/nixos/modules/services/desktops/gnome/evolution-data-server.nix index 34a91170d424..a43e8dadb421 100644 --- a/nixos/modules/services/desktops/gnome/evolution-data-server.nix +++ b/nixos/modules/services/desktops/gnome/evolution-data-server.nix @@ -2,44 +2,30 @@ { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "evolution-data-server" "enable" ] - [ "services" "gnome" "evolution-data-server" "enable" ] - ) - (mkRenamedOptionModule - [ "services" "gnome3" "evolution-data-server" "plugins" ] - [ "services" "gnome" "evolution-data-server" "plugins" ] - ) - ]; - ###### interface options = { services.gnome.evolution-data-server = { - enable = mkEnableOption "Evolution Data Server, a collection of services for storing addressbooks and calendars"; - plugins = mkOption { - type = types.listOf types.package; + enable = lib.mkEnableOption "Evolution Data Server, a collection of services for storing addressbooks and calendars"; + plugins = lib.mkOption { + type = lib.types.listOf lib.types.package; default = [ ]; description = "Plugins for Evolution Data Server."; }; }; programs.evolution = { - enable = mkEnableOption "Evolution, a Personal information management application that provides integrated mail, calendaring and address book functionality"; - plugins = mkOption { - type = types.listOf types.package; + enable = lib.mkEnableOption "Evolution, a Personal information management application that provides integrated mail, calendaring and address book functionality"; + plugins = lib.mkOption { + type = lib.types.listOf lib.types.package; default = [ ]; - example = literalExpression "[ pkgs.evolution-ews ]"; + example = lib.literalExpression "[ pkgs.evolution-ews ]"; description = "Plugins for Evolution."; }; @@ -52,15 +38,15 @@ with lib; let bundle = pkgs.evolutionWithPlugins.override { inherit (config.services.gnome.evolution-data-server) plugins; }; in - mkMerge [ - (mkIf config.services.gnome.evolution-data-server.enable { + lib.mkMerge [ + (lib.mkIf config.services.gnome.evolution-data-server.enable { environment.systemPackages = [ bundle ]; services.dbus.packages = [ bundle ]; systemd.packages = [ bundle ]; }) - (mkIf config.programs.evolution.enable { + (lib.mkIf config.programs.evolution.enable { services.gnome.evolution-data-server = { enable = true; plugins = [ pkgs.evolution ] ++ config.programs.evolution.plugins; diff --git a/nixos/modules/services/desktops/gnome/glib-networking.nix b/nixos/modules/services/desktops/gnome/glib-networking.nix index 1039605391ab..905901f47084 100644 --- a/nixos/modules/services/desktops/gnome/glib-networking.nix +++ b/nixos/modules/services/desktops/gnome/glib-networking.nix @@ -2,29 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "glib-networking" "enable" ] - [ "services" "gnome" "glib-networking" "enable" ] - ) - ]; - ###### interface options = { services.gnome.glib-networking = { - enable = mkEnableOption "network extensions for GLib"; + enable = lib.mkEnableOption "network extensions for GLib"; }; @@ -32,7 +22,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.glib-networking.enable { + config = lib.mkIf config.services.gnome.glib-networking.enable { services.dbus.packages = [ pkgs.glib-networking ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix index 34fc24f7d574..4f0c36883a3f 100644 --- a/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix +++ b/nixos/modules/services/desktops/gnome/gnome-browser-connector.nix @@ -9,19 +9,6 @@ in maintainers = teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "chrome-gnome-shell" "enable" ] - [ "services" "gnome" "gnome-browser-connector" "enable" ] - ) - # Added 2022-07-25 - (mkRenamedOptionModule - [ "services" "gnome" "chrome-gnome-shell" "enable" ] - [ "services" "gnome" "gnome-browser-connector" "enable" ] - ) - ]; - options = { services.gnome.gnome-browser-connector.enable = mkEnableOption '' native host connector for the GNOME Shell browser extension, a DBus service diff --git a/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix b/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix index ceda49337472..8deb12ec18bf 100644 --- a/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix +++ b/nixos/modules/services/desktops/gnome/gnome-initial-setup.nix @@ -2,8 +2,6 @@ { config, pkgs, lib, ... }: -with lib; - let # GNOME initial setup's run is conditioned on whether @@ -45,24 +43,16 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-initial-setup" "enable" ] - [ "services" "gnome" "gnome-initial-setup" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-initial-setup = { - enable = mkEnableOption "GNOME Initial Setup, a Simple, easy, and safe way to prepare a new system"; + enable = lib.mkEnableOption "GNOME Initial Setup, a Simple, easy, and safe way to prepare a new system"; }; @@ -71,12 +61,12 @@ in ###### implementation - config = mkIf config.services.gnome.gnome-initial-setup.enable { + config = lib.mkIf config.services.gnome.gnome-initial-setup.enable { environment.systemPackages = [ pkgs.gnome.gnome-initial-setup ] - ++ optional (versionOlder config.system.stateVersion "20.03") createGisStampFilesAutostart + ++ lib.optional (lib.versionOlder config.system.stateVersion "20.03") createGisStampFilesAutostart ; systemd.packages = [ diff --git a/nixos/modules/services/desktops/gnome/gnome-keyring.nix b/nixos/modules/services/desktops/gnome/gnome-keyring.nix index d821da164beb..79bce0ade2fc 100644 --- a/nixos/modules/services/desktops/gnome/gnome-keyring.nix +++ b/nixos/modules/services/desktops/gnome/gnome-keyring.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-keyring" "enable" ] - [ "services" "gnome" "gnome-keyring" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-keyring = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Keyring daemon, a service designed to @@ -41,7 +31,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-keyring.enable { + config = lib.mkIf config.services.gnome.gnome-keyring.enable { environment.systemPackages = [ pkgs.gnome.gnome-keyring ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix b/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix index 01f7e3695cf0..de3c3789594a 100644 --- a/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix +++ b/nixos/modules/services/desktops/gnome/gnome-online-accounts.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-online-accounts" "enable" ] - [ "services" "gnome" "gnome-online-accounts" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-online-accounts = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Online Accounts daemon, a service that provides @@ -40,7 +30,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-online-accounts.enable { + config = lib.mkIf config.services.gnome.gnome-online-accounts.enable { environment.systemPackages = [ pkgs.gnome-online-accounts ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-online-miners.nix b/nixos/modules/services/desktops/gnome/gnome-online-miners.nix index 5f9039f68c4e..9496752ed3a2 100644 --- a/nixos/modules/services/desktops/gnome/gnome-online-miners.nix +++ b/nixos/modules/services/desktops/gnome/gnome-online-miners.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-online-miners" "enable" ] - [ "services" "gnome" "gnome-online-miners" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-online-miners = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable GNOME Online Miners, a service that @@ -40,7 +30,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-online-miners.enable { + config = lib.mkIf config.services.gnome.gnome-online-miners.enable { environment.systemPackages = [ pkgs.gnome.gnome-online-miners ]; diff --git a/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix b/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix index b5573d2fc21b..d81a9edfa126 100644 --- a/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix +++ b/nixos/modules/services/desktops/gnome/gnome-remote-desktop.nix @@ -1,32 +1,36 @@ # Remote desktop daemon using Pipewire. { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2021-05-07 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-remote-desktop" "enable" ] - [ "services" "gnome" "gnome-remote-desktop" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-remote-desktop = { - enable = mkEnableOption "Remote Desktop support using Pipewire"; + enable = lib.mkEnableOption "Remote Desktop support using Pipewire"; }; }; ###### implementation - config = mkIf config.services.gnome.gnome-remote-desktop.enable { + config = lib.mkIf config.services.gnome.gnome-remote-desktop.enable { services.pipewire.enable = true; + services.dbus.packages = [ pkgs.gnome.gnome-remote-desktop ]; + + environment.systemPackages = [ pkgs.gnome.gnome-remote-desktop ]; systemd.packages = [ pkgs.gnome.gnome-remote-desktop ]; + systemd.tmpfiles.packages = [ pkgs.gnome.gnome-remote-desktop ]; + + # TODO: if possible, switch to using provided g-r-d sysusers.d + users = { + users.gnome-remote-desktop = { + isSystemUser = true; + group = "gnome-remote-desktop"; + home = "/var/lib/gnome-remote-desktop"; + }; + groups.gnome-remote-desktop = { }; + }; }; } diff --git a/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix b/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix index 9c68c9b76e9e..30b35f669092 100644 --- a/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix +++ b/nixos/modules/services/desktops/gnome/gnome-settings-daemon.nix @@ -2,8 +2,6 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.services.gnome.gnome-settings-daemon; @@ -13,28 +11,16 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - (mkRemovedOptionModule - ["services" "gnome3" "gnome-settings-daemon" "package"] - "") - - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-settings-daemon" "enable" ] - [ "services" "gnome" "gnome-settings-daemon" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-settings-daemon = { - enable = mkEnableOption "GNOME Settings Daemon"; + enable = lib.mkEnableOption "GNOME Settings Daemon"; }; @@ -43,7 +29,7 @@ in ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ pkgs.gnome.gnome-settings-daemon diff --git a/nixos/modules/services/desktops/gnome/gnome-user-share.nix b/nixos/modules/services/desktops/gnome/gnome-user-share.nix index 38256af309cc..2c6d94b7bdfc 100644 --- a/nixos/modules/services/desktops/gnome/gnome-user-share.nix +++ b/nixos/modules/services/desktops/gnome/gnome-user-share.nix @@ -2,29 +2,19 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "gnome-user-share" "enable" ] - [ "services" "gnome" "gnome-user-share" "enable" ] - ) - ]; - ###### interface options = { services.gnome.gnome-user-share = { - enable = mkEnableOption "GNOME User Share, a user-level file sharing service for GNOME"; + enable = lib.mkEnableOption "GNOME User Share, a user-level file sharing service for GNOME"; }; @@ -33,7 +23,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.gnome-user-share.enable { + config = lib.mkIf config.services.gnome.gnome-user-share.enable { environment.systemPackages = [ pkgs.gnome.gnome-user-share diff --git a/nixos/modules/services/desktops/gnome/rygel.nix b/nixos/modules/services/desktops/gnome/rygel.nix index 8932d438cf1e..c980b239d521 100644 --- a/nixos/modules/services/desktops/gnome/rygel.nix +++ b/nixos/modules/services/desktops/gnome/rygel.nix @@ -1,38 +1,28 @@ # rygel service. { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "rygel" "enable" ] - [ "services" "gnome" "rygel" "enable" ] - ) - ]; - ###### interface options = { services.gnome.rygel = { - enable = mkOption { + enable = lib.mkOption { default = false; description = '' Whether to enable Rygel UPnP Mediaserver. You will need to also allow UPnP connections in firewall, see the following [comment](https://github.com/NixOS/nixpkgs/pull/45045#issuecomment-416030795). ''; - type = types.bool; + type = lib.types.bool; }; }; }; ###### implementation - config = mkIf config.services.gnome.rygel.enable { + config = lib.mkIf config.services.gnome.rygel.enable { environment.systemPackages = [ pkgs.gnome.rygel ]; services.dbus.packages = [ pkgs.gnome.rygel ]; diff --git a/nixos/modules/services/desktops/gnome/sushi.nix b/nixos/modules/services/desktops/gnome/sushi.nix index 3133a3a0d985..946030e4bb22 100644 --- a/nixos/modules/services/desktops/gnome/sushi.nix +++ b/nixos/modules/services/desktops/gnome/sushi.nix @@ -2,30 +2,20 @@ { config, lib, pkgs, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "sushi" "enable" ] - [ "services" "gnome" "sushi" "enable" ] - ) - ]; - ###### interface options = { services.gnome.sushi = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable Sushi, a quick previewer for nautilus. @@ -39,7 +29,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.sushi.enable { + config = lib.mkIf config.services.gnome.sushi.enable { environment.systemPackages = [ pkgs.gnome.sushi ]; diff --git a/nixos/modules/services/desktops/gnome/tracker-miners.nix b/nixos/modules/services/desktops/gnome/tracker-miners.nix index 9351007d30b5..d5d42cee9f8b 100644 --- a/nixos/modules/services/desktops/gnome/tracker-miners.nix +++ b/nixos/modules/services/desktops/gnome/tracker-miners.nix @@ -2,30 +2,20 @@ { config, pkgs, lib, ... }: -with lib; - { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "tracker-miners" "enable" ] - [ "services" "gnome" "tracker-miners" "enable" ] - ) - ]; - ###### interface options = { services.gnome.tracker-miners = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable Tracker miners, indexing services for Tracker @@ -39,7 +29,7 @@ with lib; ###### implementation - config = mkIf config.services.gnome.tracker-miners.enable { + config = lib.mkIf config.services.gnome.tracker-miners.enable { environment.systemPackages = [ pkgs.tracker-miners ]; diff --git a/nixos/modules/services/desktops/gnome/tracker.nix b/nixos/modules/services/desktops/gnome/tracker.nix index fef399d0112e..45b679571c70 100644 --- a/nixos/modules/services/desktops/gnome/tracker.nix +++ b/nixos/modules/services/desktops/gnome/tracker.nix @@ -2,33 +2,23 @@ { config, pkgs, lib, ... }: -with lib; - let cfg = config.services.gnome.tracker; in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - imports = [ - # Added 2021-05-07 - (mkRenamedOptionModule - [ "services" "gnome3" "tracker" "enable" ] - [ "services" "gnome" "tracker" "enable" ] - ) - ]; - ###### interface options = { services.gnome.tracker = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to enable Tracker services, a search engine, @@ -36,8 +26,8 @@ in ''; }; - subcommandPackages = mkOption { - type = types.listOf types.package; + subcommandPackages = lib.mkOption { + type = lib.types.listOf lib.types.package; default = [ ]; internal = true; description = '' @@ -52,7 +42,7 @@ in ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ pkgs.tracker ]; diff --git a/nixos/modules/services/desktops/gvfs.nix b/nixos/modules/services/desktops/gvfs.nix index 09ac06d9f6fe..8a02cdd4a650 100644 --- a/nixos/modules/services/desktops/gvfs.nix +++ b/nixos/modules/services/desktops/gvfs.nix @@ -2,8 +2,6 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.services.gvfs; @@ -13,26 +11,19 @@ in { meta = { - maintainers = teams.gnome.members; + maintainers = lib.teams.gnome.members; }; - # Added 2019-08-19 - imports = [ - (mkRenamedOptionModule - [ "services" "gnome3" "gvfs" "enable" ] - [ "services" "gvfs" "enable" ]) - ]; - ###### interface options = { services.gvfs = { - enable = mkEnableOption "GVfs, a userspace virtual filesystem"; + enable = lib.mkEnableOption "GVfs, a userspace virtual filesystem"; # gvfs can be built with multiple configurations - package = mkPackageOption pkgs [ "gnome" "gvfs" ] { }; + package = lib.mkPackageOption pkgs [ "gnome" "gvfs" ] { }; }; @@ -41,7 +32,7 @@ in ###### implementation - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/services/desktops/pipewire/wireplumber.nix b/nixos/modules/services/desktops/pipewire/wireplumber.nix index 6ab62eb03c25..c924801bcd8b 100644 --- a/nixos/modules/services/desktops/pipewire/wireplumber.nix +++ b/nixos/modules/services/desktops/pipewire/wireplumber.nix @@ -1,18 +1,40 @@ { config, lib, pkgs, ... }: let - inherit (builtins) attrNames concatMap length; + inherit (builtins) concatMap; inherit (lib) maintainers; - inherit (lib.attrsets) attrByPath filterAttrs; + inherit (lib.attrsets) attrByPath mapAttrsToList; inherit (lib.lists) flatten optional; inherit (lib.modules) mkIf; inherit (lib.options) literalExpression mkOption; - inherit (lib.strings) hasPrefix; - inherit (lib.types) bool listOf package; + inherit (lib.strings) concatStringsSep makeSearchPath; + inherit (lib.types) bool listOf attrsOf package lines; + inherit (lib.path) subpath; pwCfg = config.services.pipewire; cfg = pwCfg.wireplumber; pwUsedForAudio = pwCfg.audio.enable; + + json = pkgs.formats.json { }; + + configSectionsToConfFile = path: value: + pkgs.writeTextDir + path + (concatStringsSep "\n" ( + mapAttrsToList + (section: content: "${section} = " + (builtins.toJSON content)) + value + )); + + mapConfigToFiles = config: + mapAttrsToList + (name: value: configSectionsToConfFile "share/wireplumber/wireplumber.conf.d/${name}.conf" value) + config; + + mapScriptsToFiles = scripts: + mapAttrsToList + (relativePath: value: pkgs.writeTextDir (subpath.join ["share/wireplumber/scripts" relativePath]) value) + scripts; in { meta.maintainers = [ maintainers.k900 ]; @@ -33,6 +55,114 @@ in description = "The WirePlumber derivation to use."; }; + extraConfig = mkOption { + # Two layer attrset is necessary before using JSON, because of the whole + # config file not being a JSON object, but a concatenation of JSON objects + # in sections. + type = attrsOf (attrsOf json.type); + default = { }; + example = literalExpression ''{ + "log-level-debug" = { + "context.properties" = { + # Output Debug log messages as opposed to only the default level (Notice) + "log.level" = "D"; + }; + }; + "wh-1000xm3-ldac-hq" = { + "monitor.bluez.rules" = [ + { + matches = [ + { + # Match any bluetooth device with ids equal to that of a WH-1000XM3 + "device.name" = "~bluez_card.*"; + "device.product.id" = "0x0cd3"; + "device.vendor.id" = "usb:054c"; + } + ]; + actions = { + update-props = { + # Set quality to high quality instead of the default of auto + "bluez5.a2dp.ldac.quality" = "hq"; + }; + }; + } + ]; + }; + }''; + description = '' + Additional configuration for the WirePlumber daemon when run in + single-instance mode (the default in nixpkgs and currently the only + supported way to run WirePlumber configured via `extraConfig`). + + See also: + - [The configuration file][docs-the-conf-file] + - [Modifying configuration][docs-modifying-config] + - [Locations of files][docs-file-locations] + - and the [configuration section][docs-config-section] of the docs in general + + Note that WirePlumber (and PipeWire) use dotted attribute names like + `device.product.id`. These are not nested, but flat objects for WirePlumber/PipeWire, + so to write these in nix expressions, remember to quote them like `"device.product.id"`. + Have a look at the example for this. + + [docs-the-conf-file]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/conf_file.html + [docs-modifying-config]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/modifying_configuration.html + [docs-file-locations]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/locations.html + [docs-config-section]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration.html + ''; + }; + + extraScripts = mkOption { + type = attrsOf lines; + default = { }; + example = { + "test/hello-world.lua" = '' + print("Hello, world!") + ''; + }; + description = '' + Additional scripts for WirePlumber to be used by configuration files. + + Every item in this attrset becomes a separate lua file with the path + relative to the `scripts` directory specified in the name of the item. + The scripts get passed to the WirePlumber service via the `XDG_DATA_DIRS` + variable. Scripts specified here are preferred over those shipped with + WirePlumber if they occupy the same relative path. + + For a script to be loaded, it needs to be specified as part of a component, + and that component needs to be required by an active profile (e.g. `main`). + Components can be defined in config files either via `extraConfig` or `configPackages`. + + For the hello-world example, you'd have to add the following `extraConfig`: + ```nix + services.pipewire.wireplumber.extraConfig."99-hello-world" = { + "wireplumber.components" = [ + { + name = "test/hello-world.lua"; + type = "script/lua"; + provides = "custom.hello-world"; + } + ]; + + "wireplumber.profiles" = { + main = { + "custom.hello-world" = "required"; + }; + }; + }; + ``` + + See also: + - [Location of scripts][docs-file-locations-scripts] + - [Components & Profiles][docs-components-profiles] + - [Migration - Loading custom scripts][docs-migration-loading-custom-scripts] + + [docs-file-locations-scripts]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/locations.html#location-of-scripts + [docs-components-profiles]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/components_and_profiles.html + [docs-migration-loading-custom-scripts]: https://pipewire.pages.freedesktop.org/wireplumber/daemon/configuration/migration.html#loading-custom-scripts + ''; + }; + configPackages = mkOption { type = listOf package; default = [ ]; @@ -57,7 +187,7 @@ in extraLv2Packages = mkOption { type = listOf package; - default = []; + default = [ ]; example = literalExpression "[ pkgs.lsp-plugins ]"; description = '' List of packages that provide LV2 plugins in `lib/lv2` that should @@ -96,9 +226,22 @@ in } ''; + extraConfigPkg = pkgs.buildEnv { + name = "wireplumber-extra-config"; + paths = mapConfigToFiles cfg.extraConfig; + pathsToLink = [ "/share/wireplumber/wireplumber.conf.d" ]; + }; + + extraScriptsPkg = pkgs.buildEnv { + name = "wireplumber-extra-scrips"; + paths = mapScriptsToFiles cfg.extraScripts; + pathsToLink = [ "/share/wireplumber/scripts" ]; + }; + configPackages = cfg.configPackages - ++ optional (!pwUsedForAudio) pwNotForAudioConfigPkg - ++ optional pwCfg.systemWide systemwideConfigPkg; + ++ [ extraConfigPkg extraScriptsPkg ] + ++ optional (!pwUsedForAudio) pwNotForAudioConfigPkg + ++ optional pwCfg.systemWide systemwideConfigPkg; configs = pkgs.buildEnv { name = "wireplumber-configs"; @@ -110,7 +253,7 @@ in ( concatMap (p: - attrByPath ["passthru" "requiredLv2Packages"] [] p + attrByPath [ "passthru" "requiredLv2Packages" ] [ ] p ) configPackages ); @@ -127,24 +270,10 @@ in assertion = !config.hardware.bluetooth.hsphfpd.enable; message = "Using WirePlumber conflicts with hsphfpd, as it provides the same functionality. `hardware.bluetooth.hsphfpd.enable` needs be set to false"; } - { - assertion = length - (attrNames - ( - filterAttrs - (name: value: - hasPrefix "wireplumber/" name || name == "wireplumber" - ) - config.environment.etc - )) == 1; - message = "Using `environment.etc.\"wireplumber<...>\"` directly is no longer supported in 24.05. Use `services.pipewire.wireplumber.configPackages` instead."; - } ]; environment.systemPackages = [ cfg.package ]; - environment.etc.wireplumber.source = "${configs}/share/wireplumber"; - systemd.packages = [ cfg.package ]; systemd.services.wireplumber.enable = pwCfg.systemWide; @@ -156,10 +285,16 @@ in systemd.services.wireplumber.environment = mkIf pwCfg.systemWide { # Force WirePlumber to use system dbus. DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket"; + + # Make WirePlumber find our config/script files and lv2 plugins required by those + # (but also the configs/scripts shipped with WirePlumber) + XDG_DATA_DIRS = makeSearchPath "share" [ configs cfg.package ]; LV2_PATH = "${lv2Plugins}/lib/lv2"; }; - systemd.user.services.wireplumber.environment.LV2_PATH = - mkIf (!pwCfg.systemWide) "${lv2Plugins}/lib/lv2"; + systemd.user.services.wireplumber.environment = mkIf (!pwCfg.systemWide) { + XDG_DATA_DIRS = makeSearchPath "share" [ configs cfg.package ]; + LV2_PATH = "${lv2Plugins}/lib/lv2"; + }; }; } diff --git a/nixos/modules/services/display-managers/default.nix b/nixos/modules/services/display-managers/default.nix index de3feb500f33..6fa8556e39be 100644 --- a/nixos/modules/services/display-managers/default.nix +++ b/nixos/modules/services/display-managers/default.nix @@ -29,12 +29,6 @@ let fi '') cfg.sessionPackages} ''; - - dmDefault = config.services.xserver.desktopManager.default; - # fallback default for cases when only default wm is set - dmFallbackDefault = if dmDefault != null then dmDefault else "none"; - wmDefault = config.services.xserver.windowManager.default; - defaultSessionFromLegacyOptions = dmFallbackDefault + lib.optionalString (wmDefault != null && wmDefault != "none") "+${wmDefault}"; in { options = { @@ -122,17 +116,10 @@ in lib.assertMsg (d != null -> (lib.types.str.check d && lib.elem d config.services.displayManager.sessionData.sessionNames)) '' Default graphical session, '${d}', not found. Valid names for 'services.displayManager.defaultSession' are: - ${lib.concatStringsSep "\n " cfg.displayManager.sessionData.sessionNames} + ${lib.concatStringsSep "\n " cfg.sessionData.sessionNames} ''; }; - default = - if dmDefault != null || wmDefault != null then - defaultSessionFromLegacyOptions - else - null; - defaultText = lib.literalMD '' - Taken from display manager settings or window manager settings, if either is set. - ''; + default = null; example = "gnome"; description = '' Graphical session to pre-select in the session chooser (only effective for GDM, LightDM and SDDM). @@ -192,20 +179,6 @@ in } ]; - warnings = - lib.mkIf (dmDefault != null || wmDefault != null) [ - '' - The following options are deprecated: - ${lib.concatStringsSep "\n " (map ({c, t}: t) (lib.filter ({c, t}: c != null) [ - { c = dmDefault; t = "- services.xserver.desktopManager.default"; } - { c = wmDefault; t = "- services.xserver.windowManager.default"; } - ]))} - Please use - services.displayManager.defaultSession = "${defaultSessionFromLegacyOptions}"; - instead. - '' - ]; - # Make xsessions and wayland sessions available in XDG_DATA_DIRS # as some programs have behavior that depends on them being present environment.sessionVariables.XDG_DATA_DIRS = lib.mkIf (cfg.sessionPackages != [ ]) [ diff --git a/nixos/modules/services/display-managers/sddm.nix b/nixos/modules/services/display-managers/sddm.nix index aaf1f0dcfc65..a6bfa213fe38 100644 --- a/nixos/modules/services/display-managers/sddm.nix +++ b/nixos/modules/services/display-managers/sddm.nix @@ -111,8 +111,8 @@ let let westonIni = (pkgs.formats.ini { }).generate "weston.ini" { libinput = { - enable-tap = xcfg.libinput.mouse.tapping; - left-handed = xcfg.libinput.mouse.leftHanded; + enable-tap = config.services.libinput.mouse.tapping; + left-handed = config.services.libinput.mouse.leftHanded; }; keyboard = { keymap_model = xcfg.xkb.model; diff --git a/nixos/modules/services/editors/emacs.md b/nixos/modules/services/editors/emacs.md index 885f927422bd..da1028675155 100644 --- a/nixos/modules/services/editors/emacs.md +++ b/nixos/modules/services/editors/emacs.md @@ -366,44 +366,3 @@ convenient if you regularly edit Nix files. You can use `woman` to get completion of all available man pages. For example, type `M-x woman nixos-rebuild .` -### Editing DocBook 5 XML Documents {#sec-emacs-docbook-xml} - -Emacs includes -[nXML](https://www.gnu.org/software/emacs/manual/html_node/nxml-mode/Introduction.html), -a major-mode for validating and editing XML documents. When editing DocBook -5.0 documents, such as [this one](#book-nixos-manual), -nXML needs to be configured with the relevant schema, which is not -included. - -To install the DocBook 5.0 schemas, either add -{var}`pkgs.docbook5` to [](#opt-environment.systemPackages) -([NixOS](#sec-declarative-package-mgmt)), or run -`nix-env -f '' -iA docbook5` -([Nix](#sec-ad-hoc-packages)). - -Then customize the variable {var}`rng-schema-locating-files` to -include {file}`~/.emacs.d/schemas.xml` and put the following -text into that file: -::: {.example #ex-emacs-docbook-xml} -### nXML Schema Configuration (`~/.emacs.d/schemas.xml`) - -```xml - - - - - - - -``` -::: diff --git a/nixos/modules/services/x11/hardware/libinput.nix b/nixos/modules/services/hardware/libinput.nix similarity index 95% rename from nixos/modules/services/x11/hardware/libinput.nix rename to nixos/modules/services/hardware/libinput.nix index 54ff7d85a033..b8aa59035d33 100644 --- a/nixos/modules/services/x11/hardware/libinput.nix +++ b/nixos/modules/services/hardware/libinput.nix @@ -2,7 +2,7 @@ with lib; -let cfg = config.services.xserver.libinput; +let cfg = config.services.libinput; xorgBool = v: if v then "on" else "off"; @@ -223,7 +223,7 @@ let cfg = config.services.xserver.libinput; in { imports = - (map (option: mkRenamedOptionModule ([ "services" "xserver" "libinput" option ]) [ "services" "xserver" "libinput" "touchpad" option ]) [ + (map (option: mkRenamedOptionModule ([ "services" "xserver" "libinput" option ]) [ "services" "libinput" "touchpad" option ]) [ "accelProfile" "accelSpeed" "buttonMapping" @@ -242,11 +242,15 @@ in { "transformationMatrix" "disableWhileTyping" "additionalOptions" - ]); + ]) ++ [ + (mkRenamedOptionModule [ "services" "xserver" "libinput" "enable" ] [ "services" "libinput" "enable" ]) + (mkRenamedOptionModule [ "services" "xserver" "libinput" "mouse" ] [ "services" "libinput" "mouse" ]) + (mkRenamedOptionModule [ "services" "xserver" "libinput" "touchpad" ] [ "services" "libinput" "touchpad" ]) + ]; options = { - services.xserver.libinput = { + services.libinput = { enable = mkEnableOption "libinput" // { default = config.services.xserver.enable; defaultText = lib.literalExpression "config.services.xserver.enable"; diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix b/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix deleted file mode 100644 index 1aaa2d07b9bd..000000000000 --- a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/cdi-generate.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ - addDriverRunpath, - glibc, - jq, - lib, - nvidia-container-toolkit, - nvidia-driver, - runtimeShell, - writeScriptBin, -}: -let - mountOptions = { options = ["ro" "nosuid" "nodev" "bind"]; }; - mounts = [ - # FIXME: Making /usr mounts optional - { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-control"; - containerPath = "/usr/bin/nvidia-cuda-mps-control"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-server"; - containerPath = "/usr/bin/nvidia-cuda-mps-server"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-debugdump"; - containerPath = "/usr/bin/nvidia-debugdump"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-powerd"; - containerPath = "/usr/bin/nvidia-powerd"; } - { hostPath = lib.getExe' nvidia-driver "nvidia-smi"; - containerPath = "/usr/bin/nvidia-smi"; } - { hostPath = lib.getExe' nvidia-container-toolkit "nvidia-ctk"; - containerPath = "/usr/bin/nvidia-ctk"; } - { hostPath = "${lib.getLib glibc}/lib"; - containerPath = "${lib.getLib glibc}/lib"; } - - # FIXME: use closureinfo - { - hostPath = addDriverRunpath.driverLink; - containerPath = addDriverRunpath.driverLink; - } - { hostPath = "${lib.getLib glibc}/lib"; - containerPath = "${lib.getLib glibc}/lib"; } - { hostPath = "${lib.getLib glibc}/lib64"; - containerPath = "${lib.getLib glibc}/lib64"; } - ]; - jqAddMountExpression = ".containerEdits.mounts[.containerEdits.mounts | length] |= . +"; - mountsToJq = lib.concatMap - (mount: - ["${lib.getExe jq} '${jqAddMountExpression} ${builtins.toJSON (mount // mountOptions)}'"]) - mounts; -in -writeScriptBin "nvidia-cdi-generator" -'' -#! ${runtimeShell} - -function cdiGenerate { - ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} cdi generate \ - --format json \ - --ldconfig-path ${lib.getExe' glibc "ldconfig"} \ - --library-search-path ${lib.getLib nvidia-driver}/lib \ - --nvidia-ctk-path ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} -} - -cdiGenerate | \ - ${lib.concatStringsSep " | " mountsToJq} > $RUNTIME_DIRECTORY/nvidia-container-toolkit.json -'' diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix b/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix deleted file mode 100644 index 5aa3c72ee0a0..000000000000 --- a/nixos/modules/services/hardware/nvidia-container-toolkit-cdi-generator/default.nix +++ /dev/null @@ -1,40 +0,0 @@ -{ config, lib, pkgs, ... }: - -{ - - options = { - - hardware.nvidia-container-toolkit-cdi-generator.enable = lib.mkOption { - default = false; - internal = true; - visible = false; - type = lib.types.bool; - description = '' - Enable dynamic CDI configuration for NVidia devices by running - nvidia-container-toolkit on boot. - ''; - }; - - }; - - config = { - - systemd.services.nvidia-container-toolkit-cdi-generator = lib.mkIf config.hardware.nvidia-container-toolkit-cdi-generator.enable { - description = "Container Device Interface (CDI) for Nvidia generator"; - wantedBy = [ "multi-user.target" ]; - after = [ "systemd-udev-settle.service" ]; - serviceConfig = { - RuntimeDirectory = "cdi"; - RemainAfterExit = true; - ExecStart = - let - script = pkgs.callPackage ./cdi-generate.nix { nvidia-driver = config.hardware.nvidia.package; }; - in - lib.getExe script; - Type = "oneshot"; - }; - }; - - }; - -} diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit/cdi-generate.nix b/nixos/modules/services/hardware/nvidia-container-toolkit/cdi-generate.nix new file mode 100644 index 000000000000..ca769cc44e5c --- /dev/null +++ b/nixos/modules/services/hardware/nvidia-container-toolkit/cdi-generate.nix @@ -0,0 +1,35 @@ +{ + glibc, + jq, + lib, + mounts, + nvidia-container-toolkit, + nvidia-driver, + runtimeShell, + writeScriptBin, +}: let + mkMount = {hostPath, containerPath, mountOptions}: { + inherit hostPath containerPath; + options = mountOptions; + }; + jqAddMountExpression = ".containerEdits.mounts[.containerEdits.mounts | length] |= . +"; + allJqMounts = lib.concatMap + (mount: + ["${lib.getExe jq} '${jqAddMountExpression} ${builtins.toJSON (mkMount mount)}'"]) + mounts; +in +writeScriptBin "nvidia-cdi-generator" +'' +#! ${runtimeShell} + +function cdiGenerate { + ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} cdi generate \ + --format json \ + --ldconfig-path ${lib.getExe' glibc "ldconfig"} \ + --library-search-path ${lib.getLib nvidia-driver}/lib \ + --nvidia-ctk-path ${lib.getExe' nvidia-container-toolkit "nvidia-ctk"} +} + +cdiGenerate | \ + ${lib.concatStringsSep " | " allJqMounts} > $RUNTIME_DIRECTORY/nvidia-container-toolkit.json +'' diff --git a/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix new file mode 100644 index 000000000000..6c6bc667e649 --- /dev/null +++ b/nixos/modules/services/hardware/nvidia-container-toolkit/default.nix @@ -0,0 +1,127 @@ +{ config, lib, pkgs, ... }: + +{ + imports = [ + (lib.mkRenamedOptionModule + [ "virtualisation" "containers" "cdi" "dynamic" "nvidia" "enable" ] + [ "hardware" "nvidia-container-toolkit" "enable" ]) + ]; + + options = let + mountType = { + options = { + hostPath = lib.mkOption { + type = lib.types.str; + description = "Host path."; + }; + containerPath = lib.mkOption { + type = lib.types.str; + description = "Container path."; + }; + mountOptions = lib.mkOption { + default = [ "ro" "nosuid" "nodev" "bind" ]; + type = lib.types.listOf lib.types.str; + description = "Mount options."; + }; + }; + }; + in { + + hardware.nvidia-container-toolkit = { + enable = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Enable dynamic CDI configuration for NVidia devices by running + nvidia-container-toolkit on boot. + ''; + }; + + mounts = lib.mkOption { + type = lib.types.listOf (lib.types.submodule mountType); + default = []; + description = "Mounts to be added to every container under the Nvidia CDI profile."; + }; + + mount-nvidia-executables = lib.mkOption { + default = true; + type = lib.types.bool; + description = '' + Mount executables nvidia-smi, nvidia-cuda-mps-control, nvidia-cuda-mps-server, + nvidia-debugdump, nvidia-powerd and nvidia-ctk on containers. + ''; + }; + + mount-nvidia-docker-1-directories = lib.mkOption { + default = true; + type = lib.types.bool; + description = '' + Mount nvidia-docker-1 directories on containers: /usr/local/nvidia/lib and + /usr/local/nvidia/lib64. + ''; + }; + }; + + }; + + config = { + + virtualisation.docker.daemon.settings = lib.mkIf + (config.hardware.nvidia-container-toolkit.enable && + (lib.versionAtLeast config.virtualisation.docker.package.version "25")) { + features.cdi = true; + }; + + hardware.nvidia-container-toolkit.mounts = let + nvidia-driver = config.hardware.nvidia.package; + in (lib.mkMerge [ + [{ hostPath = pkgs.addDriverRunpath.driverLink; + containerPath = pkgs.addDriverRunpath.driverLink; } + { hostPath = "${lib.getLib pkgs.glibc}/lib"; + containerPath = "${lib.getLib pkgs.glibc}/lib"; } + { hostPath = "${lib.getLib pkgs.glibc}/lib64"; + containerPath = "${lib.getLib pkgs.glibc}/lib64"; }] + (lib.mkIf config.hardware.nvidia-container-toolkit.mount-nvidia-executables + [{ hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-control"; + containerPath = "/usr/bin/nvidia-cuda-mps-control"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-cuda-mps-server"; + containerPath = "/usr/bin/nvidia-cuda-mps-server"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-debugdump"; + containerPath = "/usr/bin/nvidia-debugdump"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-powerd"; + containerPath = "/usr/bin/nvidia-powerd"; } + { hostPath = lib.getExe' nvidia-driver "nvidia-smi"; + containerPath = "/usr/bin/nvidia-smi"; }]) + # nvidia-docker 1.0 uses /usr/local/nvidia/lib{,64} + # e.g. + # - https://gitlab.com/nvidia/container-images/cuda/-/blob/e3ff10eab3a1424fe394899df0e0f8ca5a410f0f/dist/12.3.1/ubi9/base/Dockerfile#L44 + # - https://github.com/NVIDIA/nvidia-docker/blob/01d2c9436620d7dde4672e414698afe6da4a282f/src/nvidia/volumes.go#L104-L173 + (lib.mkIf config.hardware.nvidia-container-toolkit.mount-nvidia-docker-1-directories + [{ hostPath = "${lib.getLib nvidia-driver}/lib"; + containerPath = "/usr/local/nvidia/lib"; } + { hostPath = "${lib.getLib nvidia-driver}/lib"; + containerPath = "/usr/local/nvidia/lib64"; }]) + ]); + + systemd.services.nvidia-container-toolkit-cdi-generator = lib.mkIf config.hardware.nvidia-container-toolkit.enable { + description = "Container Device Interface (CDI) for Nvidia generator"; + wantedBy = [ "multi-user.target" ]; + after = [ "systemd-udev-settle.service" ]; + serviceConfig = { + RuntimeDirectory = "cdi"; + RemainAfterExit = true; + ExecStart = + let + script = pkgs.callPackage ./cdi-generate.nix { + inherit (config.hardware.nvidia-container-toolkit) mounts; + nvidia-driver = config.hardware.nvidia.package; + }; + in + lib.getExe script; + Type = "oneshot"; + }; + }; + + }; + +} diff --git a/nixos/modules/services/home-automation/ebusd.nix b/nixos/modules/services/home-automation/ebusd.nix index aaf2ca1d775d..ac9ec06639c1 100644 --- a/nixos/modules/services/home-automation/ebusd.nix +++ b/nixos/modules/services/home-automation/ebusd.nix @@ -4,41 +4,6 @@ with lib; let cfg = config.services.ebusd; - - package = pkgs.ebusd; - - arguments = [ - "${package}/bin/ebusd" - "--foreground" - "--updatecheck=off" - "--device=${cfg.device}" - "--port=${toString cfg.port}" - "--configpath=${cfg.configpath}" - "--scanconfig=${cfg.scanconfig}" - "--log=all:${cfg.logs.all}" - "--log=main:${cfg.logs.main}" - "--log=network:${cfg.logs.network}" - "--log=bus:${cfg.logs.bus}" - "--log=update:${cfg.logs.update}" - "--log=other:${cfg.logs.other}" - ] ++ lib.optionals cfg.readonly [ - "--readonly" - ] ++ lib.optionals cfg.mqtt.enable [ - "--mqtthost=${cfg.mqtt.host}" - "--mqttport=${toString cfg.mqtt.port}" - "--mqttuser=${cfg.mqtt.user}" - "--mqttpass=${cfg.mqtt.password}" - ] ++ lib.optionals cfg.mqtt.home-assistant [ - "--mqttint=${package}/etc/ebusd/mqtt-hassio.cfg" - "--mqttjson" - ] ++ lib.optionals cfg.mqtt.retain [ - "--mqttretain" - ] ++ cfg.extraArguments; - - usesDev = hasPrefix "/" cfg.device; - - command = concatStringsSep " " arguments; - in { meta.maintainers = with maintainers; [ nathan-gs ]; @@ -46,6 +11,8 @@ in options.services.ebusd = { enable = mkEnableOption "ebusd, a daemon for communication with eBUS heating systems"; + package = mkPackageOptionMD pkgs "ebusd" { }; + device = mkOption { type = types.str; default = ""; @@ -57,7 +24,8 @@ in ens:DEVICE for enhanced high speed serial device (only adapter v3 and newer with firmware since 20220731), DEVICE for serial device (normal speed, for all other serial adapters like adapter v2 as well as adapter v3 in non-enhanced mode), or [udp:]IP:PORT for network device. - https://github.com/john30/ebusd/wiki/2.-Run#device-options + + Source: ''; }; @@ -81,7 +49,7 @@ in type = types.str; default = "https://cfg.ebusd.eu/"; description = '' - Read CSV config files from PATH (local folder or HTTPS URL) [https://cfg.ebusd.eu/] + Directory to read CSV config files from. This can be a local folder or a URL. ''; }; @@ -95,65 +63,21 @@ in ''; }; - logs = { - main = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - network = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - bus = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - update = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - other = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - - all = mkOption { - type = types.enum [ "error" "notice" "info" "debug"]; - default = "info"; - description = '' - Only write log for matching AREAs (main|network|bus|update|other|all) below or equal to LEVEL (error|notice|info|debug) [all:notice]. - ''; - }; - }; + logs = let + # "all" must come first so it can be overridden by more specific areas + areas = [ "all" "main" "network" "bus" "update" "other" ]; + levels = [ "none" "error" "notice" "info" "debug" ]; + in listToAttrs (map (area: nameValuePair area (mkOption { + type = types.enum levels; + default = "notice"; + example = "debug"; + description = '' + Only write log for matching `AREA`s (${concatStringsSep "|" areas}) below or equal to `LEVEL` (${concatStringsSep "|" levels}) + ''; + })) areas); mqtt = { - - enable = mkOption { - type = types.bool; - default = false; - description = '' - Adds support for MQTT - ''; - }; + enable = mkEnableOption "support for MQTT"; host = mkOption { type = types.str; @@ -179,13 +103,7 @@ in ''; }; - retain = mkOption { - type = types.bool; - default = false; - description = '' - Set the retain flag on all topics instead of only selected global ones - ''; - }; + retain = mkEnableOption "set the retain flag on all topics instead of only selected global ones"; user = mkOption { type = types.str; @@ -200,7 +118,6 @@ in The MQTT password. ''; }; - }; extraArguments = mkOption { @@ -210,25 +127,44 @@ in Extra arguments to the ebus daemon ''; }; - }; - config = mkIf (cfg.enable) { - + config = let + usesDev = hasPrefix "/" cfg.device; + in mkIf cfg.enable { systemd.services.ebusd = { description = "EBUSd Service"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { - ExecStart = command; + ExecStart = let + args = cli.toGNUCommandLineShell { } (foldr (a: b: a // b) { } [ + { + inherit (cfg) device port configpath scanconfig readonly; + foreground = true; + updatecheck = "off"; + log = mapAttrsToList (name: value: "${name}:${value}") cfg.logs; + mqttretain = cfg.mqtt.retain; + } + (optionalAttrs cfg.mqtt.enable { + mqtthost = cfg.mqtt.host; + mqttport = cfg.mqtt.port; + mqttuser = cfg.mqtt.user; + mqttpass = cfg.mqtt.password; + }) + (optionalAttrs cfg.mqtt.home-assistant { + mqttint = "${cfg.package}/etc/ebusd/mqtt-hassio.cfg"; + mqttjson = true; + }) + ]); + in "${cfg.package}/bin/ebusd ${args} ${escapeShellArgs cfg.extraArguments}"; + DynamicUser = true; Restart = "on-failure"; # Hardening CapabilityBoundingSet = ""; - DeviceAllow = lib.optionals usesDev [ - cfg.device - ] ; + DeviceAllow = optionals usesDev [ cfg.device ]; DevicePolicy = "closed"; LockPersonality = true; MemoryDenyWriteExecute = false; @@ -254,9 +190,7 @@ in RestrictNamespaces = true; RestrictRealtime = true; RestrictSUIDSGID = true; - SupplementaryGroups = [ - "dialout" - ]; + SupplementaryGroups = [ "dialout" ]; SystemCallArchitectures = "native"; SystemCallFilter = [ "@system-service @pkey" @@ -265,6 +199,5 @@ in UMask = "0077"; }; }; - }; } diff --git a/nixos/modules/services/home-automation/evcc.nix b/nixos/modules/services/home-automation/evcc.nix index cf4043c946fa..a952437b1b56 100644 --- a/nixos/modules/services/home-automation/evcc.nix +++ b/nixos/modules/services/home-automation/evcc.nix @@ -63,6 +63,7 @@ in DynamicUser = true; LockPersonality = true; MemoryDenyWriteExecute = true; + Restart = "on-failure"; RestrictAddressFamilies = [ "AF_INET" "AF_INET6" diff --git a/nixos/modules/services/home-automation/wyoming/faster-whisper.nix b/nixos/modules/services/home-automation/wyoming/faster-whisper.nix index cbff3ab3e617..d0fca6a41c7b 100644 --- a/nixos/modules/services/home-automation/wyoming/faster-whisper.nix +++ b/nixos/modules/services/home-automation/wyoming/faster-whisper.nix @@ -119,6 +119,8 @@ in wantedBy = [ "multi-user.target" ]; + # https://github.com/rhasspy/wyoming-faster-whisper/issues/27 + environment."HF_HUB_CACHE" = "/tmp"; serviceConfig = { DynamicUser = true; User = "wyoming-faster-whisper"; diff --git a/nixos/modules/services/logging/logrotate.nix b/nixos/modules/services/logging/logrotate.nix index 3e29828eba2f..9344277fc1e0 100644 --- a/nixos/modules/services/logging/logrotate.nix +++ b/nixos/modules/services/logging/logrotate.nix @@ -224,7 +224,7 @@ in and users are replaced by dummy users), so tests are complemented by a logrotate-checkconf service that is enabled by default. This extra check can be disabled by disabling it at the systemd level with the - {option}`services.systemd.services.logrotate-checkconf.enable` option. + {option}`systemd.services.logrotate-checkconf.enable` option. Conversely there are still things that might make this check fail incorrectly (e.g. a file path where we don't have access to intermediate directories): diff --git a/nixos/modules/services/logging/promtail.nix b/nixos/modules/services/logging/promtail.nix index a34bc07b6ab2..9eccd34cef23 100644 --- a/nixos/modules/services/logging/promtail.nix +++ b/nixos/modules/services/logging/promtail.nix @@ -41,6 +41,10 @@ in { wantedBy = [ "multi-user.target" ]; stopIfChanged = false; + preStart = '' + ${lib.getExe pkgs.promtail} -config.file=${prettyJSON cfg.configuration} -check-syntax + ''; + serviceConfig = { Restart = "on-failure"; TimeoutStopSec = 10; diff --git a/nixos/modules/services/mail/mailman.nix b/nixos/modules/services/mail/mailman.nix index 7e7ca7e4060e..180c9800d734 100644 --- a/nixos/modules/services/mail/mailman.nix +++ b/nixos/modules/services/mail/mailman.nix @@ -534,14 +534,11 @@ in { hyperkittyApiKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64) secretKey=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 64) - mailmanWebCfgTmp=$(mktemp) - jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \ + install -m 0440 -o root -g mailman \ + <(jq -n '.MAILMAN_ARCHIVER_KEY=$archiver_key | .SECRET_KEY=$secret_key' \ --arg archiver_key "$hyperkittyApiKey" \ - --arg secret_key "$secretKey" \ - >"$mailmanWebCfgTmp" - chown root:mailman "$mailmanWebCfgTmp" - chmod 440 "$mailmanWebCfgTmp" - mv -n "$mailmanWebCfgTmp" "$mailmanWebCfg" + --arg secret_key "$secretKey") \ + "$mailmanWebCfg" fi hyperkittyApiKey="$(jq -r .MAILMAN_ARCHIVER_KEY "$mailmanWebCfg")" diff --git a/nixos/modules/services/mail/roundcube.nix b/nixos/modules/services/mail/roundcube.nix index 4499532ace89..78f627d33e2d 100644 --- a/nixos/modules/services/mail/roundcube.nix +++ b/nixos/modules/services/mail/roundcube.nix @@ -7,7 +7,7 @@ let fpm = config.services.phpfpm.pools.roundcube; localDB = cfg.database.host == "localhost"; user = cfg.database.username; - phpWithPspell = pkgs.php81.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled); + phpWithPspell = pkgs.php83.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled); in { options.services.roundcube = { @@ -247,14 +247,15 @@ in (mkIf (cfg.database.host == "localhost") { requires = [ "postgresql.service" ]; after = [ "postgresql.service" ]; - path = [ config.services.postgresql.package ]; }) { wants = [ "network-online.target" ]; after = [ "network-online.target" ]; wantedBy = [ "multi-user.target" ]; + + path = [ config.services.postgresql.package ]; script = let - psql = "${lib.optionalString (!localDB) "PGPASSFILE=${cfg.database.passwordFile}"} ${pkgs.postgresql}/bin/psql ${lib.optionalString (!localDB) "-h ${cfg.database.host} -U ${cfg.database.username} "} ${cfg.database.dbname}"; + psql = "${lib.optionalString (!localDB) "PGPASSFILE=${cfg.database.passwordFile}"} psql ${lib.optionalString (!localDB) "-h ${cfg.database.host} -U ${cfg.database.username} "} ${cfg.database.dbname}"; in '' version="$(${psql} -t <<< "select value from system where name = 'roundcube-version';" || true)" diff --git a/nixos/modules/services/matrix/appservice-irc.nix b/nixos/modules/services/matrix/appservice-irc.nix index 90790169142a..f4539a90f2e6 100644 --- a/nixos/modules/services/matrix/appservice-irc.nix +++ b/nixos/modules/services/matrix/appservice-irc.nix @@ -214,8 +214,9 @@ in { RestrictRealtime = true; PrivateMounts = true; SystemCallFilter = [ - "@system-service @pkey @chown" + "@system-service @pkey" "~@privileged @resources" + "@chown" ]; SystemCallArchitectures = "native"; # AF_UNIX is required to connect to a postgres socket. diff --git a/nixos/modules/services/matrix/conduit.nix b/nixos/modules/services/matrix/conduit.nix index e6685af562c0..b1d9b0424295 100644 --- a/nixos/modules/services/matrix/conduit.nix +++ b/nixos/modules/services/matrix/conduit.nix @@ -9,7 +9,7 @@ let configFile = format.generate "conduit.toml" cfg.settings; in { - meta.maintainers = with maintainers; [ pstn piegames ]; + meta.maintainers = with maintainers; [ pstn ]; options.services.matrix-conduit = { enable = mkEnableOption "matrix-conduit"; @@ -102,7 +102,7 @@ in default = {}; description = '' Generates the conduit.toml configuration file. Refer to - + for details on supported values. Note that database_path can not be edited because the service's reliance on systemd StateDir. ''; diff --git a/nixos/modules/services/misc/gitea.nix b/nixos/modules/services/misc/gitea.nix index e76ba0efd428..a8526688b074 100644 --- a/nixos/modules/services/misc/gitea.nix +++ b/nixos/modules/services/misc/gitea.nix @@ -722,5 +722,5 @@ in timerConfig.OnCalendar = cfg.dump.interval; }; }; - meta.maintainers = with lib.maintainers; [ srhb ma27 thehedgeh0g ]; + meta.maintainers = with lib.maintainers; [ srhb ma27 pyrox0 ]; } diff --git a/nixos/modules/services/misc/gitlab.nix b/nixos/modules/services/misc/gitlab.nix index 43568f29dd37..7b96a182f0d9 100644 --- a/nixos/modules/services/misc/gitlab.nix +++ b/nixos/modules/services/misc/gitlab.nix @@ -18,6 +18,8 @@ let gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket"; pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url; + gitlabVersionAtLeast = version: lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) version; + databaseConfig = let val = { adapter = "postgresql"; @@ -27,10 +29,16 @@ let encoding = "utf8"; pool = cfg.databasePool; } // cfg.extraDatabaseConfig; - in if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then { - production.main = val; - } else { - production = val; + in { + production = ( + if (gitlabVersionAtLeast "15.0") + then { main = val; } + else val + ) // lib.optionalAttrs (gitlabVersionAtLeast "15.9") { + ci = val // { + database_tasks = false; + }; + }; }; # We only want to create a database if we're actually going to connect to it. @@ -1168,7 +1176,7 @@ in { set -eu PSQL() { - psql --port=${toString pgsql.port} "$@" + psql --port=${toString pgsql.settings.port} "$@" } PSQL -tAc "SELECT 1 FROM pg_database WHERE datname = '${cfg.databaseName}'" | grep -q 1 || PSQL -tAc 'CREATE DATABASE "${cfg.databaseName}" OWNER "${cfg.databaseUsername}"' @@ -1348,7 +1356,7 @@ in { rm -f '${cfg.statePath}/config/database.yml' - ${if cfg.databasePasswordFile != null then '' + ${lib.optionalString (cfg.databasePasswordFile != null) '' db_password="$(<'${cfg.databasePasswordFile}')" export db_password @@ -1356,16 +1364,24 @@ in { >&2 echo "Database password was an empty string!" exit 1 fi + ''} - jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \ - '.${if lib.versionAtLeast (lib.getVersion cfg.packages.gitlab) "15.0" then "production.main" else "production"}.password = $ENV.db_password' \ - >'${cfg.statePath}/config/database.yml' - '' - else '' - jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} \ - >'${cfg.statePath}/config/database.yml' - '' - } + # GitLab expects the `production.main` section to be the first entry in the file. + jq <${pkgs.writeText "database.yml" (builtins.toJSON databaseConfig)} '{ + production: [ + ${lib.optionalString (cfg.databasePasswordFile != null) ( + builtins.concatStringsSep "\n " ( + [ ".production${lib.optionalString (gitlabVersionAtLeast "15.0") ".main"}.password = $ENV.db_password" ] + ++ lib.optional (gitlabVersionAtLeast "15.9") "| .production.ci.password = $ENV.db_password" + ++ [ "|" ] + ) + )} .production + | to_entries[] + ] + | sort_by(.key) + | reverse + | from_entries + }' >'${cfg.statePath}/config/database.yml' ${utils.genJqSecretsReplacementSnippet gitlabConfig diff --git a/nixos/modules/services/misc/greenclip.nix b/nixos/modules/services/misc/greenclip.nix index 9d1483a5a047..d92cd1854877 100644 --- a/nixos/modules/services/misc/greenclip.nix +++ b/nixos/modules/services/misc/greenclip.nix @@ -18,7 +18,10 @@ in { description = "greenclip daemon"; wantedBy = [ "graphical-session.target" ]; after = [ "graphical-session.target" ]; - serviceConfig.ExecStart = "${cfg.package}/bin/greenclip daemon"; + serviceConfig = { + ExecStart = "${cfg.package}/bin/greenclip daemon"; + Restart = "always"; + }; }; environment.systemPackages = [ cfg.package ]; diff --git a/nixos/modules/services/misc/heisenbridge.nix b/nixos/modules/services/misc/heisenbridge.nix index de109e726633..54c298f1b560 100644 --- a/nixos/modules/services/misc/heisenbridge.nix +++ b/nixos/modules/services/misc/heisenbridge.nix @@ -210,5 +210,5 @@ in }; }; - meta.maintainers = [ lib.maintainers.piegames ]; + meta.maintainers = [ ]; } diff --git a/nixos/modules/services/misc/ollama.nix b/nixos/modules/services/misc/ollama.nix index 948c8f17f989..c0341984aa35 100644 --- a/nixos/modules/services/misc/ollama.nix +++ b/nixos/modules/services/misc/ollama.nix @@ -21,6 +21,8 @@ in example = "/home/foo"; description = '' The home directory that the ollama service is started in. + + See also `services.ollama.writablePaths` and `services.ollama.sandbox`. ''; }; models = lib.mkOption { @@ -29,6 +31,37 @@ in example = "/path/to/ollama/models"; description = '' The directory that the ollama service will read models from and download new models to. + + See also `services.ollama.writablePaths` and `services.ollama.sandbox` + if downloading models or other mutation of the filesystem is required. + ''; + }; + sandbox = lib.mkOption { + type = types.bool; + default = true; + example = false; + description = '' + Whether to enable systemd's sandboxing capabilities. + + This sets [`DynamicUser`]( + https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#DynamicUser= + ), which runs the server as a unique user with read-only access to most of the filesystem. + + See also `services.ollama.writablePaths`. + ''; + }; + writablePaths = lib.mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "/home/foo" "/mnt/foo" ]; + description = '' + Paths that the server should have write access to. + + This sets [`ReadWritePaths`]( + https://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html#ReadWritePaths= + ), which allows specified paths to be written to through the default sandboxing. + + See also `services.ollama.sandbox`. ''; }; listenAddress = lib.mkOption { @@ -59,8 +92,8 @@ in type = types.attrsOf types.str; default = { }; example = { - HOME = "/tmp"; OLLAMA_LLM_LIBRARY = "cpu"; + HIP_VISIBLE_DEVICES = "0,1"; }; description = '' Set arbitrary environment variables for the ollama service. @@ -87,7 +120,8 @@ in ExecStart = "${lib.getExe ollamaPackage} serve"; WorkingDirectory = cfg.home; StateDirectory = [ "ollama" ]; - DynamicUser = true; + DynamicUser = cfg.sandbox; + ReadWritePaths = cfg.writablePaths; }; }; diff --git a/nixos/modules/services/misc/paperless.nix b/nixos/modules/services/misc/paperless.nix index 3456098073b3..e564fe3b8317 100644 --- a/nixos/modules/services/misc/paperless.nix +++ b/nixos/modules/services/misc/paperless.nix @@ -203,9 +203,12 @@ in apply = pkg: pkg.override { tesseract5 = pkg.tesseract5.override { # always enable detection modules + # tesseract fails to build when eng is not present enableLanguages = if cfg.settings ? PAPERLESS_OCR_LANGUAGE then - [ "equ" "osd" ] + lists.unique ( + [ "equ" "osd" "eng" ] ++ lib.splitString "+" cfg.settings.PAPERLESS_OCR_LANGUAGE + ) else null; }; }; diff --git a/nixos/modules/services/misc/podgrab.nix b/nixos/modules/services/misc/podgrab.nix index f95d2dc928cd..50dc70e2bd76 100644 --- a/nixos/modules/services/misc/podgrab.nix +++ b/nixos/modules/services/misc/podgrab.nix @@ -1,6 +1,8 @@ { config, lib, pkgs, ... }: let cfg = config.services.podgrab; + + stateDir = "/var/lib/podgrab"; in { options.services.podgrab = with lib; { @@ -22,28 +24,59 @@ in example = 4242; description = "The port on which Podgrab will listen for incoming HTTP traffic."; }; + + dataDirectory = mkOption { + type = types.path; + default = "${stateDir}/data"; + example = "/mnt/podcasts"; + description = "Directory to store downloads."; + }; + + user = mkOption { + type = types.str; + default = "podgrab"; + description = "User under which Podgrab runs, and which owns the download directory."; + }; + + group = mkOption { + type = types.str; + default = "podgrab"; + description = "Group under which Podgrab runs, and which owns the download directory."; + }; }; config = lib.mkIf cfg.enable { + systemd.tmpfiles.settings."10-pyload" = { + ${cfg.dataDirectory}.d = { inherit (cfg) user group; }; + }; + systemd.services.podgrab = { description = "Podgrab podcast manager"; wantedBy = [ "multi-user.target" ]; environment = { - CONFIG = "/var/lib/podgrab/config"; - DATA = "/var/lib/podgrab/data"; + CONFIG = "${stateDir}/config"; + DATA = cfg.dataDirectory; GIN_MODE = "release"; PORT = toString cfg.port; }; serviceConfig = { - DynamicUser = true; + User = cfg.user; + Group = cfg.group; EnvironmentFile = lib.optionals (cfg.passwordFile != null) [ cfg.passwordFile ]; ExecStart = "${pkgs.podgrab}/bin/podgrab"; WorkingDirectory = "${pkgs.podgrab}/share"; - StateDirectory = [ "podgrab/config" "podgrab/data" ]; + StateDirectory = [ "podgrab/config" ]; }; }; + + users.users.podgrab = lib.mkIf (cfg.user == "podgrab") { + isSystemUser = true; + group = cfg.group; + }; + + users.groups.podgrab = lib.mkIf (cfg.group == "podgrab") { }; }; meta.maintainers = with lib.maintainers; [ ambroisie ]; diff --git a/nixos/modules/services/misc/wastebin.nix b/nixos/modules/services/misc/wastebin.nix index 3d0af2862683..f24bf94fa52b 100644 --- a/nixos/modules/services/misc/wastebin.nix +++ b/nixos/modules/services/misc/wastebin.nix @@ -10,7 +10,7 @@ in options.services.wastebin = { - enable = mkEnableOption "Wastenbin pastebin service"; + enable = mkEnableOption "Wastebin, a pastebin service"; package = mkPackageOption pkgs "wastebin" { }; diff --git a/nixos/modules/services/monitoring/parsedmarc.nix b/nixos/modules/services/monitoring/parsedmarc.nix index 9191a4a697e0..a14ade59c29e 100644 --- a/nixos/modules/services/monitoring/parsedmarc.nix +++ b/nixos/modules/services/monitoring/parsedmarc.nix @@ -301,7 +301,7 @@ in description = '' The addresses to send outgoing mail to. ''; - apply = x: if x == [] then null else lib.concatStringsSep "," x; + apply = x: if x == [] || x == null then null else lib.concatStringsSep "," x; }; }; @@ -438,7 +438,7 @@ in ]; dashboards.settings.providers = lib.mkIf cfg.provision.grafana.dashboard [{ name = "parsedmarc"; - options.path = "${pkgs.python3Packages.parsedmarc.dashboard}"; + options.path = "${pkgs.parsedmarc.dashboard}"; }]; }; }; @@ -446,7 +446,7 @@ in services.parsedmarc.settings = lib.mkMerge [ (lib.mkIf cfg.provision.elasticsearch { elasticsearch = { - hosts = [ "localhost:9200" ]; + hosts = [ "http://localhost:9200" ]; ssl = false; }; }) @@ -530,7 +530,7 @@ in MemoryDenyWriteExecute = true; LockPersonality = true; SystemCallArchitectures = "native"; - ExecStart = "${pkgs.python3Packages.parsedmarc}/bin/parsedmarc -c /run/parsedmarc/parsedmarc.ini"; + ExecStart = "${lib.getExe pkgs.parsedmarc} -c /run/parsedmarc/parsedmarc.ini"; }; }; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix b/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix index 33a28ba132b8..f188fe1f68fb 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/apcupsd.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.apcupsd; + inherit (lib) mkOption types concatStringsSep; in { port = 9162; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix b/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix index 306726f47e39..e98982c0dd31 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/artifactory.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.artifactory; + inherit (lib) mkOption types concatStringsSep; in { port = 9531; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bind.nix b/nixos/modules/services/monitoring/prometheus/exporters/bind.nix index 0f3a13900a27..1c7dcf8b1ef0 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/bind.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/bind.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.bind; + inherit (lib) mkOption types concatStringsSep; in { port = 9119; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bird.nix b/nixos/modules/services/monitoring/prometheus/exporters/bird.nix index a020cd3d54b4..5d91eeed106d 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/bird.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/bird.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.bird; + inherit (lib) + mkOption + types + concatStringsSep + singleton + ; in { port = 9324; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix b/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix index b2bea158b07f..e1b7dc91a0d7 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/bitcoin.nix @@ -1,13 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.bitcoin; + inherit (lib) mkOption types concatStringsSep; in { port = 9332; extraOpts = { + package = lib.mkPackageOption pkgs "prometheus-bitcoin-exporter" { }; + rpcUser = mkOption { type = types.str; default = "bitcoinrpc"; @@ -66,7 +67,7 @@ in serviceOpts = { script = '' export BITCOIN_RPC_PASSWORD=$(cat ${cfg.rpcPasswordFile}) - exec ${pkgs.prometheus-bitcoin-exporter}/bin/bitcoind-monitor.py + exec ${cfg.package}/bin/bitcoind-monitor.py ''; environment = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix b/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix index 80d0cfcc5e45..33a1fdc52805 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/blackbox.nix @@ -1,10 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let logPrefix = "services.prometheus.exporter.blackbox"; cfg = config.services.prometheus.exporters.blackbox; + inherit (lib) + mkOption + types + concatStringsSep + escapeShellArg + ; # This ensures that we can deal with string paths, path types and # store-path strings with context. diff --git a/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix b/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix index ff1ee6a517b9..0af1e33b2c44 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/buildkite-agent.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.buildkite-agent; + inherit (lib) + mkOption + types + concatStringsSep + optionalString + literalExpression + ; in { port = 9876; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix b/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix index 339eb8c3f5f4..6f4c936fd409 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/collectd.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.collectd; + inherit (lib) + mkOption + mkEnableOption + types + optionalString + concatStringsSep + escapeShellArg + ; in { port = 9103; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix b/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix index 0f240cb30bb1..3674fab1e4f8 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.dmarc; + inherit (lib) mkOption types optionalString; json = builtins.toJSON { inherit (cfg) folders port; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix b/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix index f7ff2665f3d8..ba438ea74a3b 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/dnsmasq.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.dnsmasq; + inherit (lib) + mkOption + types + concatStringsSep + escapeShellArg + ; in { port = 9153; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/domain.nix b/nixos/modules/services/monitoring/prometheus/exporters/domain.nix index b2c8e6664c0f..c271a040d288 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/domain.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/domain.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.domain; + inherit (lib) concatStringsSep; in { port = 9222; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix b/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix index ca02f7372916..f11e91fd761a 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/dovecot.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.dovecot; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + ; in { port = 9166; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/flow.nix b/nixos/modules/services/monitoring/prometheus/exporters/flow.nix index a9e2446d0156..7719215952a5 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/flow.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/flow.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.flow; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + optionalString + ; in { port = 9590; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix b/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix index fe1d1834570a..29470147c13f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/fritzbox.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.fritzbox; + inherit (lib) mkOption types concatStringsSep; in { port = 9133; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix b/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix index 3d1123e18a32..54696187feb1 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/idrac.nix @@ -1,8 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.idrac; + inherit (lib) mkOption types; configFile = if cfg.configurationPath != null then cfg.configurationPath diff --git a/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix b/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix index c1e2a458f97b..92d02a3f1463 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/imap-mailstat.nix @@ -1,7 +1,5 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.imap-mailstat; valueToString = value: @@ -13,6 +11,15 @@ let else "XXX ${toString value}" ) ); + inherit (lib) + mkOption + types + concatStrings + concatStringsSep + attrValues + mapAttrs + optionalString + ; createConfigFile = accounts: # unfortunately on toTOML yet # https://github.com/NixOS/nix/issues/3929 diff --git a/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix b/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix index 9ac0c35bf816..3a5680439d4c 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/influxdb.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.influxdb; + inherit (lib) mkOption types concatStringsSep; in { port = 9122; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix b/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix index a51c09d5086c..51db6059081f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/ipmi.nix @@ -1,10 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let logPrefix = "services.prometheus.exporter.ipmi"; cfg = config.services.prometheus.exporters.ipmi; + inherit (lib) + mkOption + types + concatStringsSep + optionals + escapeShellArg + ; in { port = 9290; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix b/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix index f6c2d9172f4c..6a6c003c1977 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/jitsi.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.jitsi; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + ; in { port = 9700; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/json.nix b/nixos/modules/services/monitoring/prometheus/exporters/json.nix index 1e4632f9310e..1c8db0ea3e0b 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/json.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/json.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.json; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + mkRemovedOptionModule + ; in { port = 7979; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix b/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix index 75b8bb650478..3519cce6e821 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/junos-czerwonk.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.junos-czerwonk; + inherit (lib) + mkOption + types + escapeShellArg + mkIf + concatStringsSep + ; configFile = if cfg.configuration != null then configurationFile else (escapeShellArg cfg.configurationFile); diff --git a/nixos/modules/services/monitoring/prometheus/exporters/kea.nix b/nixos/modules/services/monitoring/prometheus/exporters/kea.nix index 88dc284a8cc6..d0f2eb6b8a3c 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/kea.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/kea.nix @@ -5,10 +5,14 @@ , ... }: -with lib; - let cfg = config.services.prometheus.exporters.kea; + inherit (lib) + mkOption + types + mkRenamedOptionModule + literalExpression + ; in { imports = [ (mkRenamedOptionModule [ "controlSocketPaths" ] [ "targets" ]) diff --git a/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix b/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix index afdb664a0de5..44169cce6745 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/keylight.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.keylight; + inherit (lib) concatStringsSep; in { port = 9288; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/knot.nix b/nixos/modules/services/monitoring/prometheus/exporters/knot.nix index 79d952dfb164..ed902fc27c15 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/knot.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/knot.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.knot; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + ; in { port = 9433; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix b/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix index cc8db6e1b4e4..edface276f54 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/lnd.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.lnd; + inherit (lib) mkOption types concatStringsSep; in { port = 9092; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/mail.nix b/nixos/modules/services/monitoring/prometheus/exporters/mail.nix index 7ace5c1968fb..f6dd6f7eb994 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/mail.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/mail.nix @@ -1,9 +1,19 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.mail; + inherit (lib) + mkOption + types + mapAttrs' + nameValuePair + toLower + filterAttrs + escapeShellArg + literalExpression + mkIf + concatStringsSep + ; configFile = if cfg.configuration != null then configurationFile else (escapeShellArg cfg.configFile); diff --git a/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix b/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix index 9e0a98f0ba64..cd438f13edd2 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/mikrotik.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.mikrotik; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + escapeShellArg + ; in { port = 9436; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/minio.nix b/nixos/modules/services/monitoring/prometheus/exporters/minio.nix index e1edd364c8fc..8faff5908b8a 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/minio.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/minio.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.minio; + inherit (lib) + mkOption + types + optionalString + concatStringsSep + escapeShellArg + ; in { port = 9290; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix b/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix index 37a2daebd973..37ff49b27000 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/modemmanager.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.modemmanager; + inherit (lib) mkOption types concatStringsSep; in { port = 9539; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix b/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix index 10d533a2bbda..288434e93abb 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/mongodb.nix @@ -1,9 +1,17 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.mongodb; + inherit (lib) + mkOption + types + optionalString + getExe + length + concatStringsSep + concatMapStringsSep + escapeShellArgs + ; in { port = 9216; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nats.nix b/nixos/modules/services/monitoring/prometheus/exporters/nats.nix index 83e60426f5ed..224ce474d537 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nats.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nats.nix @@ -1,11 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let - cfg = config.services.prometheus.exporters.nats; - + inherit (lib) mkOption types concatStringsSep; in { port = 7777; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix b/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix index f22c5e2e5cff..d221bac8421a 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nextcloud.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nextcloud; + inherit (lib) + mkOption + types + escapeShellArg + concatStringsSep + ; in { port = 9205; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix b/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix index d4939c7063a3..091ad2291d2a 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nginx.nix @@ -1,9 +1,16 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nginx; + inherit (lib) + mkOption + types + mkMerge + mkRemovedOptionModule + mkRenamedOptionModule + mkIf + concatStringsSep + ; in { port = 9113; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix b/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix index ebb13a8c3ee3..2b4fd12895a3 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nginxlog.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nginxlog; + inherit (lib) mkOption types; in { port = 9117; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/node.nix b/nixos/modules/services/monitoring/prometheus/exporters/node.nix index 8615bd04951c..9d6b51ad140d 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/node.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/node.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.node; + inherit (lib) + mkOption + types + concatStringsSep + concatMapStringsSep + any + optionals + ; collectorIsEnabled = final: any (collector: (final == collector)) cfg.enabledCollectors; collectorIsDisabled = final: any (collector: (final == collector)) cfg.disabledCollectors; in diff --git a/nixos/modules/services/monitoring/prometheus/exporters/nut.nix b/nixos/modules/services/monitoring/prometheus/exporters/nut.nix index e88059cea439..157bdadddfc9 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/nut.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/nut.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.nut; + inherit (lib) + mkOption + types + optionalString + concatStringsSep + ; in { port = 9199; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix b/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix index 9c1b39bb3a34..bb65bd270933 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/openldap.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, ... }: -with lib; - let cfg = config.services.prometheus.exporters.openldap; + inherit (lib) mkOption types concatStringsSep; in { port = 9330; extraOpts = { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix b/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix index 725a5679e271..71b602638632 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/pgbouncer.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.pgbouncer; + inherit (lib) + mkOption + types + optionals + escapeShellArg + concatStringsSep + ; in { port = 9127; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix b/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix index 926626b5e797..30b260dc3792 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/pihole.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.pihole; + inherit (lib) + mkOption + types + mkRemovedOptionModule + optionalString + ; in { imports = [ diff --git a/nixos/modules/services/monitoring/prometheus/exporters/ping.nix b/nixos/modules/services/monitoring/prometheus/exporters/ping.nix index a47db4c16f42..9122a6be66e6 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/ping.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/ping.nix @@ -1,9 +1,9 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.ping; + inherit (lib) mkOption types concatStringsSep; settingsFormat = pkgs.formats.yaml {}; configFile = settingsFormat.generate "config.yml" cfg.settings; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix b/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix index 188a5f9a1a14..7aa3622f16d6 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.postfix; + inherit (lib) + mkOption + types + mkIf + escapeShellArg + concatStringsSep + optional + ; in { port = 9154; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix b/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix index 7ed71ff9e10e..bf392382660a 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/postgres.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.postgres; + inherit (lib) + mkOption + types + mkIf + mkForce + concatStringsSep + ; in { port = 9187; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/process.nix b/nixos/modules/services/monitoring/prometheus/exporters/process.nix index b041a957b638..8e5eceee067c 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/process.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/process.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.process; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + ; configFile = pkgs.writeText "process-exporter.yaml" (builtins.toJSON cfg.settings); in { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/pve.nix b/nixos/modules/services/monitoring/prometheus/exporters/pve.nix index 96db49d9591f..8928577b6953 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/pve.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/pve.nix @@ -1,8 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.pve; + inherit (lib) + mkOption + types + mkPackageOption + optionalString + optionalAttrs + ; # pve exporter requires a config file so create an empty one if configFile is not provided emptyConfigFile = pkgs.writeTextFile { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix b/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix index 66a8423f8ff5..d788ce363d61 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/py-air-control.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.py-air-control; + inherit (lib) mkOption types; workingDir = "/var/lib/${cfg.stateDir}"; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/redis.nix b/nixos/modules/services/monitoring/prometheus/exporters/redis.nix index ee7d87e8e615..672e3dfe7b05 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/redis.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/redis.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.redis; + inherit (lib) concatStringsSep; in { port = 9121; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/restic.nix b/nixos/modules/services/monitoring/prometheus/exporters/restic.nix index aaf3c189a4d2..ef44803ba053 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/restic.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/restic.nix @@ -1,9 +1,18 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.restic; + inherit (lib) + mkOption + types + concatStringsSep + mkIf + mapAttrs' + splitString + toUpper + optionalAttrs + nameValuePair + ; in { port = 9753; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix b/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix index ee8047fb4599..8993aee5d248 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/rspamd.nix @@ -1,9 +1,16 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.rspamd; + inherit (lib) + mkOption + types + replaceStrings + mkRemovedOptionModule + recursiveUpdate + concatStringsSep + literalExpression + ; mkFile = conf: pkgs.writeText "rspamd-exporter-config.yml" (builtins.toJSON conf); diff --git a/nixos/modules/services/monitoring/prometheus/exporters/script.nix b/nixos/modules/services/monitoring/prometheus/exporters/script.nix index 5fe8512f554e..0967ce236a62 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/script.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/script.nix @@ -1,9 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.script; + inherit (lib) + mkOption + types + literalExpression + concatStringsSep + ; configFile = pkgs.writeText "script-exporter.yaml" (builtins.toJSON cfg.settings); in { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix b/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix index 5b3cf10b650b..be3e483c6ee1 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/shelly.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.shelly; + inherit (lib) mkOption types; in { port = 9784; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix b/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix index 84658c48c723..8aadd87abbed 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/smartctl.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.smartctl; + inherit (lib) mkOption types literalExpression; args = lib.escapeShellArgs ([ "--web.listen-address=${cfg.listenAddress}:${toString cfg.port}" "--smartctl.path=${pkgs.smartmontools}/bin/smartctl" diff --git a/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix b/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix index 79ed5129dda4..c3baed150376 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/smokeping.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.smokeping; + inherit (lib) mkOption types concatStringsSep; goDuration = types.mkOptionType { name = "goDuration"; description = "Go duration (https://golang.org/pkg/time/#ParseDuration)"; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix index 19ab31d735f8..dc10a9a2f92e 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/snmp.nix @@ -1,10 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let logPrefix = "services.prometheus.exporters.snmp"; cfg = config.services.prometheus.exporters.snmp; + inherit (lib) + mkOption + types + literalExpression + escapeShellArg + concatStringsSep + ; # This ensures that we can deal with string paths, path types and # store-path strings with context. diff --git a/nixos/modules/services/monitoring/prometheus/exporters/sql.nix b/nixos/modules/services/monitoring/prometheus/exporters/sql.nix index 4c4d8f880364..59715f5d33e2 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/sql.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/sql.nix @@ -1,7 +1,13 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.sql; + inherit (lib) + mkOption + types + mapAttrs + mapAttrsToList + concatStringsSep + ; cfgOptions = { options = with types; { jobs = mkOption { diff --git a/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix b/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix index 94df86167e8c..b1bc65c9a492 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/statsd.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.statsd; + inherit (lib) concatStringsSep; in { port = 9102; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix b/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix index 0e16d27b9d04..d848e263a3b6 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/surfboard.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.surfboard; + inherit (lib) mkOption types concatStringsSep; in { port = 9239; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix b/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix index 2edd1de83e1b..52bad81ed7d5 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/systemd.nix @@ -1,9 +1,8 @@ { config, pkgs, lib, ... }: -with lib; - -let cfg = config.services.prometheus.exporters.systemd; - +let + cfg = config.services.prometheus.exporters.systemd; + inherit (lib) concatStringsSep; in { port = 9558; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/tor.nix b/nixos/modules/services/monitoring/prometheus/exporters/tor.nix index 48406def9894..d39112d0c283 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/tor.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/tor.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.tor; + inherit (lib) mkOption types concatStringsSep; in { port = 9130; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix b/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix index 0452f630c2e2..df6011e2434b 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/unbound.nix @@ -5,10 +5,17 @@ , ... }: -with lib; - let cfg = config.services.prometheus.exporters.unbound; + inherit (lib) + mkOption + types + mkRemovedOptionModule + optionalAttrs + optionalString + mkMerge + mkIf + ; in { imports = [ diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix b/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix index 82309febf63b..07d177251f40 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/unifi.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.unifi; + inherit (lib) + mkOption + types + escapeShellArg + optionalString + concatStringsSep + ; in { port = 9130; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix b/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix index 0ea824fbf114..7b9ba4c5d1ed 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/unpoller.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.unpoller; + inherit (lib) mkEnableOption generators; configFile = pkgs.writeText "prometheus-unpoller-exporter.json" (generators.toJSON {} { poller = { inherit (cfg.log) debug quiet; }; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix b/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix index 1582554c1253..4fda15c9ee4e 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/v2ray.nix @@ -1,9 +1,8 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.v2ray; + inherit (lib) mkOption types concatStringsSep; in { port = 9299; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix b/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix index 811792674b96..e94c513ae84f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.varnish; + inherit (lib) + mkOption + types + mkDefault + optional + escapeShellArg + concatStringsSep + ; in { port = 9131; diff --git a/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix index 27c0c191c6e3..7a48c836425f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/wireguard.nix @@ -1,9 +1,15 @@ { config, lib, pkgs, options, ... }: -with lib; - let cfg = config.services.prometheus.exporters.wireguard; + inherit (lib) + mkOption + types + mkRenamedOptionModule + mkEnableOption + optionalString + escapeShellArg + ; in { port = 9586; imports = [ diff --git a/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix b/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix index ce9cd624dc27..a685b94b827f 100644 --- a/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix +++ b/nixos/modules/services/monitoring/prometheus/exporters/zfs.nix @@ -1,9 +1,14 @@ { config, lib, pkgs, options, ... }: -with lib; let cfg = config.services.prometheus.exporters.zfs; + inherit (lib) + mkOption + types + concatStringsSep + concatMapStringsSep + ; in { port = 9134; diff --git a/nixos/modules/services/monitoring/rustdesk-server.nix b/nixos/modules/services/monitoring/rustdesk-server.nix index fcfd57167dd8..21e6128c7226 100644 --- a/nixos/modules/services/monitoring/rustdesk-server.nix +++ b/nixos/modules/services/monitoring/rustdesk-server.nix @@ -53,15 +53,14 @@ in { Slice = "system-rustdesk.slice"; User = "rustdesk"; Group = "rustdesk"; + DynamicUser = "yes"; Environment = []; WorkingDirectory = "/var/lib/rustdesk"; StateDirectory = "rustdesk"; StateDirectoryMode = "0750"; LockPersonality = true; - NoNewPrivileges = true; PrivateDevices = true; PrivateMounts = true; - PrivateTmp = true; PrivateUsers = true; ProtectClock = true; ProtectControlGroups = true; @@ -71,10 +70,7 @@ in { ProtectKernelModules = true; ProtectKernelTunables = true; ProtectProc = "invisible"; - ProtectSystem = "strict"; - RemoveIPC = true; RestrictNamespaces = true; - RestrictSUIDSGID = true; }; }; in lib.mkIf cfg.enable { diff --git a/nixos/modules/services/monitoring/vmagent.nix b/nixos/modules/services/monitoring/vmagent.nix index cdcf1571154e..4838e0709d09 100644 --- a/nixos/modules/services/monitoring/vmagent.nix +++ b/nixos/modules/services/monitoring/vmagent.nix @@ -1,63 +1,62 @@ { config, pkgs, lib, ... }: -with lib; + let cfg = config.services.vmagent; settingsFormat = pkgs.formats.json { }; in { + imports = [ + (lib.mkRemovedOptionModule [ "services" "vmagent" "dataDir" ] "dataDir has been deprecated in favor of systemd provided CacheDirectory") + (lib.mkRemovedOptionModule [ "services" "vmagent" "user" ] "user has been deprecated in favor of systemd DynamicUser") + (lib.mkRemovedOptionModule [ "services" "vmagent" "group" ] "group has been deprecated in favor of systemd DynamicUser") + (lib.mkRenamedOptionModule [ "services" "vmagent" "remoteWriteUrl" ] [ "services" "vmagent" "remoteWrite" "url" ]) + ]; + options.services.vmagent = { - enable = mkEnableOption "vmagent"; + enable = lib.mkEnableOption "vmagent"; - user = mkOption { - default = "vmagent"; - type = types.str; - description = '' - User account under which vmagent runs. - ''; + package = lib.mkPackageOption pkgs "vmagent" { }; + + remoteWrite = { + url = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + Endpoint for prometheus compatible remote_write + ''; + }; + basicAuthUsername = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + Basic Auth username used to connect to remote_write endpoint + ''; + }; + basicAuthPasswordFile = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = '' + File that contains the Basic Auth password used to connect to remote_write endpoint + ''; + }; }; - group = mkOption { - type = types.str; - default = "vmagent"; - description = '' - Group under which vmagent runs. - ''; - }; - - package = mkPackageOption pkgs "vmagent" { }; - - dataDir = mkOption { - type = types.str; - default = "/var/lib/vmagent"; - description = '' - The directory where vmagent stores its data files. - ''; - }; - - remoteWriteUrl = mkOption { - default = "http://localhost:8428/api/v1/write"; - type = types.str; - description = '' - The storage endpoint such as VictoriaMetrics - ''; - }; - - prometheusConfig = mkOption { + prometheusConfig = lib.mkOption { type = lib.types.submodule { freeformType = settingsFormat.type; }; description = '' Config for prometheus style metrics ''; }; - openFirewall = mkOption { - type = types.bool; + openFirewall = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to open the firewall for the default ports. ''; }; - extraArgs = mkOption { - type = types.listOf types.str; + extraArgs = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Extra args to pass to `vmagent`. See the docs: @@ -67,37 +66,36 @@ in { }; }; - config = mkIf cfg.enable { - users.groups = mkIf (cfg.group == "vmagent") { vmagent = { }; }; - - users.users = mkIf (cfg.user == "vmagent") { - vmagent = { - group = cfg.group; - description = "vmagent daemon user"; - home = cfg.dataDir; - isSystemUser = true; - }; - }; - - networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ 8429 ]; + config = lib.mkIf cfg.enable { + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 8429 ]; systemd.services.vmagent = let prometheusConfig = settingsFormat.generate "prometheusConfig.yaml" cfg.prometheusConfig; + startCommandLine = lib.concatStringsSep " " ([ + "${cfg.package}/bin/vmagent" + "-promscrape.config=${prometheusConfig}" + ] ++ cfg.extraArgs + ++ lib.optionals (cfg.remoteWrite.url != null) [ + "-remoteWrite.url=${cfg.remoteWrite.url}" + "-remoteWrite.tmpDataPath=%C/vmagent/remote_write_tmp" + ] ++ lib.optional (cfg.remoteWrite.basicAuthUsername != null) "-remoteWrite.basicAuth.username=${cfg.remoteWrite.basicAuthUsername}" + ++ lib.optional (cfg.remoteWrite.basicAuthPasswordFile != null) "-remoteWrite.basicAuth.passwordFile=\${CREDENTIALS_DIRECTORY}/remote_write_basic_auth_password"); in { wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; description = "vmagent system service"; serviceConfig = { - User = cfg.user; - Group = cfg.group; + DynamicUser = true; + User = "vmagent"; + Group = "vmagent"; Type = "simple"; Restart = "on-failure"; - WorkingDirectory = cfg.dataDir; - ExecStart = "${cfg.package}/bin/vmagent -remoteWrite.url=${cfg.remoteWriteUrl} -promscrape.config=${prometheusConfig} ${escapeShellArgs cfg.extraArgs}"; + CacheDirectory = "vmagent"; + ExecStart = startCommandLine; + LoadCredential = lib.optional (cfg.remoteWrite.basicAuthPasswordFile != null) [ + "remote_write_basic_auth_password:${cfg.remoteWrite.basicAuthPasswordFile}" + ]; }; }; - - systemd.tmpfiles.rules = - [ "d '${cfg.dataDir}' 0755 ${cfg.user} ${cfg.group} -" ]; }; } diff --git a/nixos/modules/services/networking/adguardhome.nix b/nixos/modules/services/networking/adguardhome.nix index 6958bcccf54c..df9927351edc 100644 --- a/nixos/modules/services/networking/adguardhome.nix +++ b/nixos/modules/services/networking/adguardhome.nix @@ -4,6 +4,7 @@ with lib; let cfg = config.services.adguardhome; + settingsFormat = pkgs.formats.yaml { }; args = concatStringsSep " " ([ "--no-check-update" @@ -12,27 +13,33 @@ let "--config /var/lib/AdGuardHome/AdGuardHome.yaml" ] ++ cfg.extraArgs); - configFile = pkgs.writeTextFile { - name = "AdGuardHome.yaml"; - text = builtins.toJSON cfg.settings; - checkPhase = "${pkgs.adguardhome}/bin/adguardhome -c $out --check-config"; - }; - defaultBindPort = 3000; - -in -{ - - imports = - let cfgPath = [ "services" "adguardhome" ]; - in - [ - (mkRenamedOptionModuleWith { sinceRelease = 2211; from = cfgPath ++ [ "host" ]; to = cfgPath ++ [ "settings" "bind_host" ]; }) - (mkRenamedOptionModuleWith { sinceRelease = 2211; from = cfgPath ++ [ "port" ]; to = cfgPath ++ [ "settings" "bind_port" ]; }) - ]; + settings = if (cfg.settings != null) then + cfg.settings // (if cfg.settings.schema_version < 23 then { + bind_host = cfg.host; + bind_port = cfg.port; + } else { + http.address = "${cfg.host}:${toString cfg.port}"; + }) + else + null; + configFile = + (settingsFormat.generate "AdGuardHome.yaml" settings).overrideAttrs (_: { + checkPhase = "${cfg.package}/bin/adguardhome -c $out --check-config"; + }); +in { options.services.adguardhome = with types; { enable = mkEnableOption "AdGuard Home network-wide ad blocker"; + package = mkOption { + type = package; + default = pkgs.adguardhome; + defaultText = literalExpression "pkgs.adguardhome"; + description = '' + The package that runs adguardhome. + ''; + }; + openFirewall = mkOption { default = false; type = bool; @@ -43,8 +50,8 @@ in }; allowDHCP = mkOption { - default = cfg.settings.dhcp.enabled or false; - defaultText = literalExpression ''config.services.adguardhome.settings.dhcp.enabled or false''; + default = settings.dhcp.enabled or false; + defaultText = literalExpression "config.services.adguardhome.settings.dhcp.enabled or false"; type = bool; description = '' Allows AdGuard Home to open raw sockets (`CAP_NET_RAW`), which is @@ -65,32 +72,34 @@ in ''; }; + host = mkOption { + default = "0.0.0.0"; + type = str; + description = '' + Host address to bind HTTP server to. + ''; + }; + + port = mkOption { + default = 3000; + type = port; + description = '' + Port to serve HTTP pages on. + ''; + }; + settings = mkOption { default = null; type = nullOr (submodule { - freeformType = (pkgs.formats.yaml { }).type; + freeformType = settingsFormat.type; options = { schema_version = mkOption { - default = pkgs.adguardhome.schema_version; - defaultText = literalExpression "pkgs.adguardhome.schema_version"; + default = cfg.package.schema_version; + defaultText = literalExpression "cfg.package.schema_version"; type = int; description = '' Schema version for the configuration. - Defaults to the `schema_version` supplied by `pkgs.adguardhome`. - ''; - }; - bind_host = mkOption { - default = "0.0.0.0"; - type = str; - description = '' - Host address to bind HTTP server to. - ''; - }; - bind_port = mkOption { - default = defaultBindPort; - type = port; - description = '' - Port to serve HTTP pages on. + Defaults to the `schema_version` supplied by `cfg.package`. ''; }; }; @@ -107,7 +116,7 @@ in Set this to `null` (default) for a non-declarative configuration without any Nix-supplied values. - Declarative configurations are supplied with a default `schema_version`, `bind_host`, and `bind_port`. + Declarative configurations are supplied with a default `schema_version`, and `http.address`. ::: ''; }; @@ -124,17 +133,25 @@ in config = mkIf cfg.enable { assertions = [ { - assertion = cfg.settings != null -> cfg.mutableSettings - || (hasAttrByPath [ "dns" "bind_host" ] cfg.settings) - || (hasAttrByPath [ "dns" "bind_hosts" ] cfg.settings); - message = - "AdGuard setting dns.bind_host or dns.bind_hosts needs to be configured for a minimal working configuration"; + assertion = cfg.settings != null + -> !(hasAttrByPath [ "bind_host" ] cfg.settings); + message = "AdGuard option `settings.bind_host' has been superseded by `services.adguardhome.host'"; } { - assertion = cfg.settings != null -> cfg.mutableSettings - || hasAttrByPath [ "dns" "bootstrap_dns" ] cfg.settings; - message = - "AdGuard setting dns.bootstrap_dns needs to be configured for a minimal working configuration"; + assertion = cfg.settings != null + -> !(hasAttrByPath [ "bind_port" ] cfg.settings); + message = "AdGuard option `settings.bind_host' has been superseded by `services.adguardhome.port'"; + } + { + assertion = settings != null -> cfg.mutableSettings + || hasAttrByPath [ "dns" "bootstrap_dns" ] settings; + message = "AdGuard setting dns.bootstrap_dns needs to be configured for a minimal working configuration"; + } + { + assertion = settings != null -> cfg.mutableSettings + || hasAttrByPath [ "dns" "bootstrap_dns" ] settings + && isList settings.dns.bootstrap_dns; + message = "AdGuard setting dns.bootstrap_dns needs to be a list"; } ]; @@ -147,7 +164,7 @@ in StartLimitBurst = 10; }; - preStart = optionalString (cfg.settings != null) '' + preStart = optionalString (settings != null) '' if [ -e "$STATE_DIRECTORY/AdGuardHome.yaml" ] \ && [ "${toString cfg.mutableSettings}" = "1" ]; then # Writing directly to AdGuardHome.yaml results in empty file @@ -161,8 +178,9 @@ in serviceConfig = { DynamicUser = true; - ExecStart = "${pkgs.adguardhome}/bin/adguardhome ${args}"; - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ] ++ optionals cfg.allowDHCP [ "CAP_NET_RAW" ]; + ExecStart = "${cfg.package}/bin/adguardhome ${args}"; + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ] + ++ optionals cfg.allowDHCP [ "CAP_NET_RAW" ]; Restart = "always"; RestartSec = 10; RuntimeDirectory = "AdGuardHome"; @@ -170,6 +188,6 @@ in }; }; - networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.settings.bind_port or defaultBindPort ]; + networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ]; }; } diff --git a/nixos/modules/services/networking/clatd.nix b/nixos/modules/services/networking/clatd.nix new file mode 100644 index 000000000000..de6cde4e979c --- /dev/null +++ b/nixos/modules/services/networking/clatd.nix @@ -0,0 +1,81 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + cfg = config.services.clatd; + + settingsFormat = pkgs.formats.keyValue {}; + + configFile = settingsFormat.generate "clatd.conf" cfg.settings; +in +{ + options = { + services.clatd = { + enable = mkEnableOption "clatd"; + + package = mkPackageOption pkgs "clatd" { }; + + settings = mkOption { + type = types.submodule ({ name, ... }: { + freeformType = settingsFormat.type; + }); + default = { }; + example = literalExpression '' + { + plat-prefix = "64:ff9b::/96"; + } + ''; + description = '' + Configuration of clatd. See [clatd Documentation](https://github.com/toreanderson/clatd/blob/master/README.pod#configuration). + ''; + }; + }; + }; + + config = mkIf cfg.enable { + systemd.services.clatd = { + description = "464XLAT CLAT daemon"; + documentation = [ "man:clatd(8)" ]; + wantedBy = [ "multi-user.target" ]; + after = [ "network-online.target" ]; + wants = [ "network-online.target" ]; + startLimitIntervalSec = 0; + + serviceConfig = { + ExecStart = "${cfg.package}/bin/clatd -c ${configFile}"; + + # Hardening + CapabilityBoundingSet = [ + "CAP_NET_ADMIN" + ]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectProc = "invisible"; + ProtectSystem = true; + RestrictAddressFamilies = [ + "AF_INET" + "AF_INET6" + "AF_NETLINK" + ]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@network-io" + "@system-service" + "~@privileged" + "~@resources" + ]; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/deconz.nix b/nixos/modules/services/networking/deconz.nix index eaa7759d0407..88b0ee612d87 100644 --- a/nixos/modules/services/networking/deconz.nix +++ b/nixos/modules/services/networking/deconz.nix @@ -95,7 +95,7 @@ in ''; postStart = '' # Delay signalling service readiness until it's actually up. - while ! "${lib.getExe pkgs.curl}" -sSfl -o /dev/null "http://${cfg.listenAddress}:${toString cfg.httpPort}"; do + while ! "${lib.getExe pkgs.curl}" -sSfL -o /dev/null "http://${cfg.listenAddress}:${toString cfg.httpPort}"; do echo "Waiting for TCP port ${toString cfg.httpPort} to be open..." sleep 1 done diff --git a/nixos/modules/services/networking/firewall-nftables.nix b/nixos/modules/services/networking/firewall-nftables.nix index de336113843e..a5ee7efc3c32 100644 --- a/nixos/modules/services/networking/firewall-nftables.nix +++ b/nixos/modules/services/networking/firewall-nftables.nix @@ -45,6 +45,18 @@ in This option only works with the nftables based firewall. ''; }; + + extraReversePathFilterRules = mkOption { + type = types.lines; + default = ""; + example = "fib daddr . mark . iif type local accept"; + description = '' + Additional nftables rules to be appended to the rpfilter-allow + chain. + + This option only works with the nftables based firewall. + ''; + }; }; }; @@ -79,6 +91,8 @@ in meta nfproto ipv4 udp sport . udp dport { 67 . 68, 68 . 67 } accept comment "DHCPv4 client/server" fib saddr . mark ${optionalString (cfg.checkReversePath != "loose") ". iif"} oif exists accept + jump rpfilter-allow + ${optionalString cfg.logReversePathDrops '' log level info prefix "rpfilter drop: " ''} @@ -86,6 +100,10 @@ in } ''} + chain rpfilter-allow { + ${cfg.extraReversePathFilterRules} + } + chain input { type filter hook input priority filter; policy drop; diff --git a/nixos/modules/services/networking/inadyn.nix b/nixos/modules/services/networking/inadyn.nix new file mode 100644 index 000000000000..baa4302096c2 --- /dev/null +++ b/nixos/modules/services/networking/inadyn.nix @@ -0,0 +1,250 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.inadyn; + + # check if a value of an attrset is not null or an empty collection + nonEmptyValue = _: v: v != null && v != [ ] && v != { }; + + renderOption = k: v: + if builtins.elem k [ "provider" "custom" ] then + lib.concatStringsSep "\n" + (mapAttrsToList + (name: config: '' + ${k} ${name} { + ${lib.concatStringsSep "\n " (mapAttrsToList renderOption (filterAttrs nonEmptyValue config))} + }'') + v) + else if k == "include" then + "${k}(\"${v}\")" + else if k == "hostname" && builtins.isList v then + "${k} = { ${builtins.concatStringsSep ", " (map (s: "\"${s}\"") v)} }" + else if builtins.isBool v then + "${k} = ${boolToString v}" + else if builtins.isString v then + "${k} = \"${v}\"" + else + "${k} = ${toString v}"; + + configFile' = pkgs.writeText "inadyn.conf" + '' + # This file was generated by nix + # do not edit + + ${(lib.concatStringsSep "\n" (mapAttrsToList renderOption (filterAttrs nonEmptyValue cfg.settings)))} + ''; + + configFile = if (cfg.configFile != null) then cfg.configFile else configFile'; +in +{ + options.services.inadyn = with types; + let + providerOptions = + { + include = mkOption { + default = null; + description = "File to include additional settings for this provider from."; + type = nullOr path; + }; + ssl = mkOption { + default = true; + description = "Whether to use HTTPS for this DDNS provider."; + type = bool; + }; + username = mkOption { + default = null; + description = "Username for this DDNS provider."; + type = nullOr str; + }; + password = mkOption { + default = null; + description = '' + Password for this DDNS provider. + + WARNING: This will be world-readable in the nix store. + To store credentials securely, use the `include` or `configFile` options. + ''; + type = nullOr str; + }; + hostname = mkOption { + default = "*"; + example = "your.cool-domain.com"; + description = "Hostname alias(es)."; + type = either str (listOf str); + }; + }; + in + { + enable = mkEnableOption ('' + synchronise your machine's IP address with a dynamic DNS provider using inadyn + ''); + user = mkOption { + default = "inadyn"; + type = types.str; + description = '' + User account under which inadyn runs. + + ::: {.note} + If left as the default value this user will automatically be created + on system activation, otherwise you are responsible for + ensuring the user exists before the inadyn service starts. + ::: + ''; + }; + group = mkOption { + default = "inadyn"; + type = types.str; + description = '' + Group account under which inadyn runs. + + ::: {.note} + If left as the default value this user will automatically be created + on system activation, otherwise you are responsible for + ensuring the user exists before the inadyn service starts. + ::: + ''; + }; + interval = mkOption { + default = "*-*-* *:*:00"; + description = '' + How often to check the current IP. + Uses the format described in {manpage}`systemd.time(7)`"; + ''; + type = str; + }; + logLevel = lib.mkOption { + type = lib.types.enum [ "none" "err" "warning" "info" "notice" "debug" ]; + default = "notice"; + description = "Set inadyn's log level."; + }; + settings = mkOption { + default = { }; + description = "See `inadyn.conf (5)`"; + type = submodule { + freeformType = attrs; + options = { + allow-ipv6 = mkOption { + default = config.networking.enableIPv6; + defaultText = "`config.networking.enableIPv6`"; + description = "Whether to get IPv6 addresses from interfaces."; + type = bool; + }; + forced-update = mkOption { + default = 2592000; + description = "Duration (in seconds) after which an update is forced."; + type = ints.positive; + }; + provider = mkOption { + default = { }; + description = '' + Settings for DDNS providers built-in to inadyn. + + For a list of built-in providers, see `inadyn.conf (5)`. + ''; + type = attrsOf (submodule { + freeformType = attrs; + options = providerOptions; + }); + }; + custom = mkOption { + default = { }; + description = '' + Settings for custom DNS providers. + ''; + type = attrsOf (submodule { + freeformType = attrs; + options = providerOptions // { + ddns-server = mkOption { + description = "DDNS server name."; + type = str; + }; + ddns-path = mkOption { + description = '' + DDNS server path. + + See `inadnyn.conf (5)` for a list for format specifiers that can be used. + ''; + example = "/update?user=%u&password=%p&domain=%h&myip=%i"; + type = str; + }; + }; + }); + }; + }; + }; + }; + configFile = mkOption { + default = null; + description = '' + Configuration file for inadyn. + + Setting this will override all other configuration options. + + Passed to the inadyn service using LoadCredential. + ''; + type = nullOr path; + }; + }; + + config = lib.mkIf cfg.enable { + systemd = { + services.inadyn = { + description = "Update nameservers using inadyn"; + documentation = [ + "man:inadyn" + "man:inadyn.conf" + "file:${pkgs.inadyn}/share/doc/inadyn/README.md" + ]; + requires = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + startAt = cfg.interval; + serviceConfig = { + Type = "oneshot"; + ExecStart = ''${lib.getExe pkgs.inadyn} -f ${configFile} --cache-dir ''${CACHE_DIRECTORY}/inadyn -1 --foreground -l ${cfg.logLevel}''; + LoadCredential = "config:${configFile}"; + CacheDirectory = "inadyn"; + + User = cfg.user; + Group = cfg.group; + UMask = "0177"; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictAddressFamilies = "AF_INET AF_INET6 AF_NETLINK"; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectSystem = "strict"; + ProtectProc = "invisible"; + ProtectHome = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallErrorNumber = "EPERM"; + SystemCallFilter = "@system-service"; + CapabilityBoundingSet = ""; + }; + }; + + timers.inadyn.timerConfig.Persistent = true; + }; + + users.users.inadyn = mkIf (cfg.user == "inadyn") { + group = cfg.group; + isSystemUser = true; + }; + + users.groups = mkIf (cfg.group == "inadyn") { + inadyn = { }; + }; + }; +} diff --git a/nixos/modules/services/networking/jotta-cli.md b/nixos/modules/services/networking/jotta-cli.md new file mode 100644 index 000000000000..335e5c8e3856 --- /dev/null +++ b/nixos/modules/services/networking/jotta-cli.md @@ -0,0 +1,27 @@ +# Jottacloud Command-line Tool {#module-services-jotta-cli} + +The [Jottacloud Command-line Tool](https://docs.jottacloud.com/en/articles/1436834-jottacloud-command-line-tool) is a headless [Jottacloud](https://jottacloud.com) client. + +## Quick Start {#module-services-jotta-cli-quick-start} + +```nix +{ + services.jotta-cli.enable = true; +} +``` + +This adds `jotta-cli` to `environment.systemPackages` and starts a user service that runs `jottad` with the default options. + +## Example Configuration {#module-services-jotta-cli-example-configuration} + +```nix +services.jotta-cli = { + enable = true; + options = [ "slow" ]; + package = pkgs.jotta-cli; +}; +``` + +This uses `jotta-cli` and `jottad` from the `pkgs.jotta-cli` package and starts `jottad` in low memory mode. + +`jottad` is also added to `environment.systemPackages`, so `jottad --help` can be used to explore options. diff --git a/nixos/modules/services/networking/jotta-cli.nix b/nixos/modules/services/networking/jotta-cli.nix new file mode 100644 index 000000000000..e0fa1ef332fe --- /dev/null +++ b/nixos/modules/services/networking/jotta-cli.nix @@ -0,0 +1,43 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.jotta-cli; +in { + options = { + services.jotta-cli = { + + enable = mkEnableOption "Jottacloud Command-line Tool"; + + options = mkOption { + default = [ "stdoutlog" "datadir" "%h/.jottad/" ]; + example = [ ]; + type = with types; listOf str; + description = "Command-line options passed to jottad."; + }; + + package = lib.mkPackageOption pkgs "jotta-cli" { }; + }; + }; + config = mkIf cfg.enable { + systemd.user.services.jottad = { + + description = "Jottacloud Command-line Tool daemon"; + + serviceConfig = { + Type = "notify"; + EnvironmentFile = "-%h/.config/jotta-cli/jotta-cli.env"; + ExecStart = "${lib.getExe' cfg.package "jottad"} ${concatStringsSep " " cfg.options}"; + Restart = "on-failure"; + }; + + wantedBy = [ "default.target" ]; + wants = [ "network-online.target" ]; + after = [ "network-online.target" ]; + }; + environment.systemPackages = [ pkgs.jotta-cli ]; + }; + + meta.maintainers = with lib.maintainers; [ evenbrenden ]; + meta.doc = ./jotta-cli.md; +} diff --git a/nixos/modules/services/networking/knot.nix b/nixos/modules/services/networking/knot.nix index 6488a159b3b7..145b4ad1dd3f 100644 --- a/nixos/modules/services/networking/knot.nix +++ b/nixos/modules/services/networking/knot.nix @@ -226,7 +226,7 @@ in { }; settings = mkOption { - type = types.attrs; + type = (pkgs.formats.yaml {}).type; default = {}; description = '' Extra configuration as nix values. diff --git a/nixos/modules/services/networking/netbird/coturn.nix b/nixos/modules/services/networking/netbird/coturn.nix new file mode 100644 index 000000000000..746d70a07250 --- /dev/null +++ b/nixos/modules/services/networking/netbird/coturn.nix @@ -0,0 +1,160 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + getExe + literalExpression + mkAfter + mkEnableOption + mkIf + mkMerge + mkOption + optionalAttrs + optionalString + ; + + inherit (lib.types) + bool + listOf + nullOr + path + port + str + ; + + cfg = config.services.netbird.server.coturn; +in + +{ + options.services.netbird.server.coturn = { + enable = mkEnableOption "a Coturn server for Netbird, will also open the firewall on the configured range"; + + useAcmeCertificates = mkOption { + type = bool; + default = false; + description = '' + Whether to use ACME certificates corresponding to the given domain for the server. + ''; + }; + + domain = mkOption { + type = str; + description = "The domain under which the coturn server runs."; + }; + + user = mkOption { + type = str; + default = "netbird"; + description = '' + The username used by netbird to connect to the coturn server. + ''; + }; + + password = mkOption { + type = nullOr str; + default = null; + description = '' + The password of the user used by netbird to connect to the coturn server. + ''; + }; + + passwordFile = mkOption { + type = nullOr path; + default = null; + description = '' + The path to a file containing the password of the user used by netbird to connect to the coturn server. + ''; + }; + + openPorts = mkOption { + type = listOf port; + default = with config.services.coturn; [ + listening-port + alt-listening-port + tls-listening-port + alt-tls-listening-port + ]; + defaultText = literalExpression '' + with config.services.coturn; [ + listening-port + alt-listening-port + tls-listening-port + alt-tls-listening-port + ]; + ''; + + description = '' + The list of ports used by coturn for listening to open in the firewall. + ''; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + { + assertions = [ + { + assertion = (cfg.password == null) != (cfg.passwordFile == null); + message = "Exactly one of `password` or `passwordFile` must be given for the coturn setup."; + } + ]; + + services.coturn = + { + enable = true; + + realm = cfg.domain; + lt-cred-mech = true; + no-cli = true; + + extraConfig = '' + fingerprint + user=${cfg.user}:${if cfg.password != null then cfg.password else "@password@"} + no-software-attribute + ''; + } + // (optionalAttrs cfg.useAcmeCertificates { + cert = "@cert@"; + pkey = "@pkey@"; + }); + + systemd.services.coturn = + let + dir = config.security.acme.certs.${cfg.domain}.directory; + preStart' = + (optionalString (cfg.passwordFile != null) '' + ${getExe pkgs.replace-secret} @password@ ${cfg.passwordFile} /run/coturn/turnserver.cfg + '') + + (optionalString cfg.useAcmeCertificates '' + ${getExe pkgs.replace-secret} @cert@ "$CREDENTIALS_DIRECTORY/cert.pem" /run/coturn/turnserver.cfg + ${getExe pkgs.replace-secret} @pkey@ "$CREDENTIALS_DIRECTORY/pkey.pem" /run/coturn/turnserver.cfg + ''); + in + (optionalAttrs (preStart' != "") { preStart = mkAfter preStart'; }) + // (optionalAttrs cfg.useAcmeCertificates { + serviceConfig.LoadCredential = [ + "cert.pem:${dir}/fullchain.pem" + "pkey.pem:${dir}/key.pem" + ]; + }); + + security.acme.certs.${cfg.domain}.postRun = optionalString cfg.useAcmeCertificates "systemctl restart coturn.service"; + + networking.firewall = { + allowedUDPPorts = cfg.openPorts; + allowedTCPPorts = cfg.openPorts; + + allowedUDPPortRanges = with config.services.coturn; [ + { + from = min-port; + to = max-port; + } + ]; + }; + } + ]); +} diff --git a/nixos/modules/services/networking/netbird/dashboard.nix b/nixos/modules/services/networking/netbird/dashboard.nix new file mode 100644 index 000000000000..6fc308615590 --- /dev/null +++ b/nixos/modules/services/networking/netbird/dashboard.nix @@ -0,0 +1,186 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + boolToString + concatStringsSep + hasAttr + isBool + mapAttrs + mkDefault + mkEnableOption + mkIf + mkOption + mkPackageOption + ; + + inherit (lib.types) + attrsOf + bool + either + package + str + submodule + ; + + toStringEnv = value: if isBool value then boolToString value else toString value; + + cfg = config.services.netbird.server.dashboard; +in + +{ + options.services.netbird.server.dashboard = { + enable = mkEnableOption "the static netbird dashboard frontend"; + + package = mkPackageOption pkgs "netbird-dashboard" { }; + + enableNginx = mkEnableOption "Nginx reverse-proxy to serve the dashboard."; + + domain = mkOption { + type = str; + default = "localhost"; + description = "The domain under which the dashboard runs."; + }; + + managementServer = mkOption { + type = str; + description = "The address of the management server, used for the API endpoints."; + }; + + settings = mkOption { + type = submodule { freeformType = attrsOf (either str bool); }; + + defaultText = '' + { + AUTH_AUDIENCE = "netbird"; + AUTH_CLIENT_ID = "netbird"; + AUTH_SUPPORTED_SCOPES = "openid profile email"; + NETBIRD_TOKEN_SOURCE = "idToken"; + USE_AUTH0 = false; + } + ''; + + description = '' + An attribute set that will be used to substitute variables when building the dashboard. + Any values set here will be templated into the frontend and be public for anyone that can reach your website. + The exact values sadly aren't documented anywhere. + A starting point when searching for valid values is this [script](https://github.com/netbirdio/dashboard/blob/main/docker/init_react_envs.sh) + The only mandatory value is 'AUTH_AUTHORITY' as we cannot set a default value here. + ''; + }; + + finalDrv = mkOption { + readOnly = true; + type = package; + description = '' + The derivation containing the final templated dashboard. + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + { + assertion = hasAttr "AUTH_AUTHORITY" cfg.settings; + message = "The setting AUTH_AUTHORITY is required for the dasboard to function."; + } + ]; + + services.netbird.server.dashboard = { + settings = + { + # Due to how the backend and frontend work this secret will be templated into the backend + # and then served statically from your website + # This enables you to login without the normally needed indirection through the backend + # but this also means anyone that can reach your website can + # fetch this secret, which is why there is no real need to put it into + # special options as its public anyway + # As far as I know leaking this secret is just + # an information leak as one can fetch some basic app + # informations from the IDP + # To actually do something one still needs to have login + # data and this secret so this being public will not + # suffice for anything just decreasing security + AUTH_CLIENT_SECRET = ""; + + NETBIRD_MGMT_API_ENDPOINT = cfg.managementServer; + NETBIRD_MGMT_GRPC_API_ENDPOINT = cfg.managementServer; + } + // (mapAttrs (_: mkDefault) { + # Those values have to be easily overridable + AUTH_AUDIENCE = "netbird"; # must be set for your devices to be able to log in + AUTH_CLIENT_ID = "netbird"; + AUTH_SUPPORTED_SCOPES = "openid profile email"; + NETBIRD_TOKEN_SOURCE = "idToken"; + USE_AUTH0 = false; + }); + + # The derivation containing the templated dashboard + finalDrv = + pkgs.runCommand "netbird-dashboard" + { + nativeBuildInputs = [ pkgs.gettext ]; + env = { + ENV_STR = concatStringsSep " " [ + "$AUTH_AUDIENCE" + "$AUTH_AUTHORITY" + "$AUTH_CLIENT_ID" + "$AUTH_CLIENT_SECRET" + "$AUTH_REDIRECT_URI" + "$AUTH_SILENT_REDIRECT_URI" + "$AUTH_SUPPORTED_SCOPES" + "$NETBIRD_DRAG_QUERY_PARAMS" + "$NETBIRD_GOOGLE_ANALYTICS_ID" + "$NETBIRD_HOTJAR_TRACK_ID" + "$NETBIRD_MGMT_API_ENDPOINT" + "$NETBIRD_MGMT_GRPC_API_ENDPOINT" + "$NETBIRD_TOKEN_SOURCE" + "$USE_AUTH0" + ]; + } // (mapAttrs (_: toStringEnv) cfg.settings); + } + '' + cp -R ${cfg.package} build + + find build -type d -exec chmod 755 {} \; + OIDC_TRUSTED_DOMAINS="build/OidcTrustedDomains.js" + + envsubst "$ENV_STR" < "$OIDC_TRUSTED_DOMAINS.tmpl" > "$OIDC_TRUSTED_DOMAINS" + + for f in $(grep -R -l AUTH_SUPPORTED_SCOPES build/); do + mv "$f" "$f.copy" + envsubst "$ENV_STR" < "$f.copy" > "$f" + rm "$f.copy" + done + + cp -R build $out + ''; + }; + + services.nginx = mkIf cfg.enableNginx { + enable = true; + + virtualHosts.${cfg.domain} = { + locations = { + "/" = { + root = cfg.finalDrv; + tryFiles = "$uri $uri.html $uri/ =404"; + }; + + "/404.html".extraConfig = '' + internal; + ''; + }; + + extraConfig = '' + error_page 404 /404.html; + ''; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/netbird/management.nix b/nixos/modules/services/networking/netbird/management.nix new file mode 100644 index 000000000000..52f033959143 --- /dev/null +++ b/nixos/modules/services/networking/netbird/management.nix @@ -0,0 +1,460 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: + +let + inherit (lib) + any + concatMap + getExe' + literalExpression + mkEnableOption + mkIf + mkOption + mkPackageOption + optional + recursiveUpdate + ; + + inherit (lib.types) + bool + enum + listOf + port + str + ; + + inherit (utils) escapeSystemdExecArgs genJqSecretsReplacementSnippet; + + stateDir = "/var/lib/netbird-mgmt"; + + settingsFormat = pkgs.formats.json { }; + + defaultSettings = { + Stuns = [ + { + Proto = "udp"; + URI = "stun:${cfg.turnDomain}:3478"; + Username = ""; + Password = null; + } + ]; + + TURNConfig = { + Turns = [ + { + Proto = "udp"; + URI = "turn:${cfg.turnDomain}:${builtins.toString cfg.turnPort}"; + Username = "netbird"; + Password = "netbird"; + } + ]; + + CredentialsTTL = "12h"; + Secret = "not-secure-secret"; + TimeBasedCredentials = false; + }; + + Signal = { + Proto = "https"; + URI = "${cfg.domain}:443"; + Username = ""; + Password = null; + }; + + ReverseProxy = { + TrustedHTTPProxies = [ ]; + TrustedHTTPProxiesCount = 0; + TrustedPeers = [ "0.0.0.0/0" ]; + }; + + Datadir = "${stateDir}/data"; + DataStoreEncryptionKey = "very-insecure-key"; + StoreConfig = { + Engine = "sqlite"; + }; + + HttpConfig = { + Address = "127.0.0.1:${builtins.toString cfg.port}"; + IdpSignKeyRefreshEnabled = true; + OIDCConfigEndpoint = cfg.oidcConfigEndpoint; + }; + + IdpManagerConfig = { + ManagerType = "none"; + ClientConfig = { + Issuer = ""; + TokenEndpoint = ""; + ClientID = "netbird"; + ClientSecret = ""; + GrantType = "client_credentials"; + }; + + ExtraConfig = { }; + Auth0ClientCredentials = null; + AzureClientCredentials = null; + KeycloakClientCredentials = null; + ZitadelClientCredentials = null; + }; + + DeviceAuthorizationFlow = { + Provider = "none"; + ProviderConfig = { + Audience = "netbird"; + Domain = null; + ClientID = "netbird"; + TokenEndpoint = null; + DeviceAuthEndpoint = ""; + Scope = "openid profile email"; + UseIDToken = false; + }; + }; + + PKCEAuthorizationFlow = { + ProviderConfig = { + Audience = "netbird"; + ClientID = "netbird"; + ClientSecret = ""; + AuthorizationEndpoint = ""; + TokenEndpoint = ""; + Scope = "openid profile email"; + RedirectURLs = [ "http://localhost:53000" ]; + UseIDToken = false; + }; + }; + }; + + managementConfig = recursiveUpdate defaultSettings cfg.settings; + + managementFile = settingsFormat.generate "config.json" managementConfig; + + cfg = config.services.netbird.server.management; +in + +{ + options.services.netbird.server.management = { + enable = mkEnableOption "Netbird Management Service."; + + package = mkPackageOption pkgs "netbird" { }; + + domain = mkOption { + type = str; + description = "The domain under which the management API runs."; + }; + + turnDomain = mkOption { + type = str; + description = "The domain of the TURN server to use."; + }; + + turnPort = mkOption { + type = port; + default = 3478; + description = '' + The port of the TURN server to use. + ''; + }; + + dnsDomain = mkOption { + type = str; + default = "netbird.selfhosted"; + description = "Domain used for peer resolution."; + }; + + singleAccountModeDomain = mkOption { + type = str; + default = "netbird.selfhosted"; + description = '' + Enables single account mode. + This means that all the users will be under the same account grouped by the specified domain. + If the installation has more than one account, the property is ineffective. + ''; + }; + + disableAnonymousMetrics = mkOption { + type = bool; + default = true; + description = "Disables push of anonymous usage metrics to NetBird."; + }; + + disableSingleAccountMode = mkOption { + type = bool; + default = false; + description = '' + If set to true, disables single account mode. + The `singleAccountModeDomain` property will be ignored and every new user will have a separate NetBird account. + ''; + }; + + port = mkOption { + type = port; + default = 8011; + description = "Internal port of the management server."; + }; + + extraOptions = mkOption { + type = listOf str; + default = [ ]; + description = '' + Additional options given to netbird-mgmt as commandline arguments. + ''; + }; + + oidcConfigEndpoint = mkOption { + type = str; + description = "The oidc discovery endpoint."; + example = "https://example.eu.auth0.com/.well-known/openid-configuration"; + }; + + settings = mkOption { + inherit (settingsFormat) type; + + defaultText = literalExpression '' + defaultSettings = { + Stuns = [ + { + Proto = "udp"; + URI = "stun:''${cfg.turnDomain}:3478"; + Username = ""; + Password = null; + } + ]; + + TURNConfig = { + Turns = [ + { + Proto = "udp"; + URI = "turn:''${cfg.turnDomain}:3478"; + Username = "netbird"; + Password = "netbird"; + } + ]; + + CredentialsTTL = "12h"; + Secret = "not-secure-secret"; + TimeBasedCredentials = false; + }; + + Signal = { + Proto = "https"; + URI = "''${cfg.domain}:443"; + Username = ""; + Password = null; + }; + + ReverseProxy = { + TrustedHTTPProxies = [ ]; + TrustedHTTPProxiesCount = 0; + TrustedPeers = [ "0.0.0.0/0" ]; + }; + + Datadir = "''${stateDir}/data"; + DataStoreEncryptionKey = "genEVP6j/Yp2EeVujm0zgqXrRos29dQkpvX0hHdEUlQ="; + StoreConfig = { Engine = "sqlite"; }; + + HttpConfig = { + Address = "127.0.0.1:''${builtins.toString cfg.port}"; + IdpSignKeyRefreshEnabled = true; + OIDCConfigEndpoint = cfg.oidcConfigEndpoint; + }; + + IdpManagerConfig = { + ManagerType = "none"; + ClientConfig = { + Issuer = ""; + TokenEndpoint = ""; + ClientID = "netbird"; + ClientSecret = ""; + GrantType = "client_credentials"; + }; + + ExtraConfig = { }; + Auth0ClientCredentials = null; + AzureClientCredentials = null; + KeycloakClientCredentials = null; + ZitadelClientCredentials = null; + }; + + DeviceAuthorizationFlow = { + Provider = "none"; + ProviderConfig = { + Audience = "netbird"; + Domain = null; + ClientID = "netbird"; + TokenEndpoint = null; + DeviceAuthEndpoint = ""; + Scope = "openid profile email offline_access api"; + UseIDToken = false; + }; + }; + + PKCEAuthorizationFlow = { + ProviderConfig = { + Audience = "netbird"; + ClientID = "netbird"; + ClientSecret = ""; + AuthorizationEndpoint = ""; + TokenEndpoint = ""; + Scope = "openid profile email offline_access api"; + RedirectURLs = "http://localhost:53000"; + UseIDToken = false; + }; + }; + }; + ''; + + default = { }; + + description = '' + Configuration of the netbird management server. + Options containing secret data should be set to an attribute set containing the attribute _secret + - a string pointing to a file containing the value the option should be set to. + See the example to get a better picture of this: in the resulting management.json file, + the `DataStoreEncryptionKey` key will be set to the contents of the /run/agenix/netbird_mgmt-data_store_encryption_key file. + ''; + + example = { + DataStoreEncryptionKey = { + _secret = "/run/agenix/netbird_mgmt-data_store_encryption_key"; + }; + }; + }; + + logLevel = mkOption { + type = enum [ + "ERROR" + "WARN" + "INFO" + "DEBUG" + ]; + default = "INFO"; + description = "Log level of the netbird services."; + }; + + enableNginx = mkEnableOption "Nginx reverse-proxy for the netbird management service."; + }; + + config = mkIf cfg.enable { + warnings = + concatMap + ( + { check, name }: + optional check "${name} is world-readable in the Nix Store, you should provide it as a _secret." + ) + [ + { + check = builtins.isString managementConfig.TURNConfig.Secret; + name = "The TURNConfig.secret"; + } + { + check = builtins.isString managementConfig.DataStoreEncryptionKey; + name = "The DataStoreEncryptionKey"; + } + { + check = any (T: (T ? Password) && builtins.isString T.Password) managementConfig.TURNConfig.Turns; + name = "A Turn configuration's password"; + } + ]; + + systemd.services.netbird-management = { + description = "The management server for Netbird, a wireguard VPN"; + documentation = [ "https://netbird.io/docs/" ]; + + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ managementFile ]; + + preStart = genJqSecretsReplacementSnippet managementConfig "${stateDir}/management.json"; + + serviceConfig = { + ExecStart = escapeSystemdExecArgs ( + [ + (getExe' cfg.package "netbird-mgmt") + "management" + # Config file + "--config" + "${stateDir}/management.json" + # Data directory + "--datadir" + "${stateDir}/data" + # DNS domain + "--dns-domain" + cfg.dnsDomain + # Port to listen on + "--port" + cfg.port + # Log to stdout + "--log-file" + "console" + # Log level + "--log-level" + cfg.logLevel + # + "--idp-sign-key-refresh-enabled" + # Domain for internal resolution + "--single-account-mode-domain" + cfg.singleAccountModeDomain + ] + ++ (optional cfg.disableAnonymousMetrics "--disable-anonymous-metrics") + ++ (optional cfg.disableSingleAccountMode "--disable-single-account-mode") + ++ cfg.extraOptions + ); + Restart = "always"; + RuntimeDirectory = "netbird-mgmt"; + StateDirectory = [ + "netbird-mgmt" + "netbird-mgmt/data" + ]; + WorkingDirectory = stateDir; + + # hardening + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateMounts = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = true; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + + stopIfChanged = false; + }; + + services.nginx = mkIf cfg.enableNginx { + enable = true; + + virtualHosts.${cfg.domain} = { + locations = { + "/api".proxyPass = "http://localhost:${builtins.toString cfg.port}"; + + "/management.ManagementService/".extraConfig = '' + # This is necessary so that grpc connections do not get closed early + # see https://stackoverflow.com/a/67805465 + client_body_timeout 1d; + + grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + grpc_pass grpc://localhost:${builtins.toString cfg.port}; + grpc_read_timeout 1d; + grpc_send_timeout 1d; + grpc_socket_keepalive on; + ''; + }; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/netbird/server.md b/nixos/modules/services/networking/netbird/server.md new file mode 100644 index 000000000000..3649e97b379e --- /dev/null +++ b/nixos/modules/services/networking/netbird/server.md @@ -0,0 +1,42 @@ +# Netbird server {#module-services-netbird-server} + +NetBird is a VPN built on top of WireGuard® making it easy to create secure private networks for your organization or home. + +## Quickstart {#module-services-netbird-server-quickstart} + +To fully setup Netbird as a self-hosted server, we need both a Coturn server and an identity provider, the list of supported SSOs and their setup are available [on Netbird's documentation](https://docs.netbird.io/selfhosted/selfhosted-guide#step-3-configure-identity-provider-idp). + +There are quite a few settings that need to be passed to Netbird for it to function, and a minimal config looks like : + +```nix +services.netbird.server = { + enable = true; + + domain = "netbird.example.selfhosted"; + + enableNginx = true; + + coturn = { + enable = true; + + passwordFile = "/path/to/a/secret/password"; + }; + + management = { + oidcConfigEndpoint = "https://sso.example.selfhosted/oauth2/openid/netbird/.well-known/openid-configuration"; + + settings = { + TURNConfig = { + Turns = [ + { + Proto = "udp"; + URI = "turn:netbird.example.selfhosted:3478"; + Username = "netbird"; + Password._secret = "/path/to/a/secret/password"; + } + ]; + }; + }; + }; +}; +``` diff --git a/nixos/modules/services/networking/netbird/server.nix b/nixos/modules/services/networking/netbird/server.nix new file mode 100644 index 000000000000..a4de0fda6a13 --- /dev/null +++ b/nixos/modules/services/networking/netbird/server.nix @@ -0,0 +1,67 @@ +{ config, lib, ... }: + +let + inherit (lib) + mkEnableOption + mkIf + mkOption + optionalAttrs + ; + + inherit (lib.types) str; + + cfg = config.services.netbird.server; +in + +{ + meta = { + maintainers = with lib.maintainers; [ thubrecht ]; + doc = ./server.md; + }; + + # Import the separate components + imports = [ + ./coturn.nix + ./dashboard.nix + ./management.nix + ./signal.nix + ]; + + options.services.netbird.server = { + enable = mkEnableOption "Netbird Server stack, comprising the dashboard, management API and signal service"; + + enableNginx = mkEnableOption "Nginx reverse-proxy for the netbird server services."; + + domain = mkOption { + type = str; + description = "The domain under which the netbird server runs."; + }; + }; + + config = mkIf cfg.enable { + services.netbird.server = { + dashboard = { + inherit (cfg) enable domain enableNginx; + + managementServer = "https://${cfg.domain}"; + }; + + management = + { + inherit (cfg) enable domain enableNginx; + } + // (optionalAttrs cfg.coturn.enable { + turnDomain = cfg.domain; + turnPort = config.services.coturn.tls-listening-port; + }); + + signal = { + inherit (cfg) enable domain enableNginx; + }; + + coturn = { + inherit (cfg) domain; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/netbird/signal.nix b/nixos/modules/services/networking/netbird/signal.nix new file mode 100644 index 000000000000..8408d20e874b --- /dev/null +++ b/nixos/modules/services/networking/netbird/signal.nix @@ -0,0 +1,123 @@ +{ + config, + lib, + pkgs, + utils, + ... +}: + +let + inherit (lib) + getExe' + mkEnableOption + mkIf + mkPackageOption + mkOption + ; + + inherit (lib.types) enum port str; + + inherit (utils) escapeSystemdExecArgs; + + cfg = config.services.netbird.server.signal; +in + +{ + options.services.netbird.server.signal = { + enable = mkEnableOption "Netbird's Signal Service"; + + package = mkPackageOption pkgs "netbird" { }; + + enableNginx = mkEnableOption "Nginx reverse-proxy for the netbird signal service."; + + domain = mkOption { + type = str; + description = "The domain name for the signal service."; + }; + + port = mkOption { + type = port; + default = 8012; + description = "Internal port of the signal server."; + }; + + logLevel = mkOption { + type = enum [ + "ERROR" + "WARN" + "INFO" + "DEBUG" + ]; + default = "INFO"; + description = "Log level of the netbird signal service."; + }; + }; + + config = mkIf cfg.enable { + systemd.services.netbird-signal = { + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + ExecStart = escapeSystemdExecArgs [ + (getExe' cfg.package "netbird-signal") + "run" + # Port to listen on + "--port" + cfg.port + # Log to stdout + "--log-file" + "console" + # Log level + "--log-level" + cfg.logLevel + ]; + + Restart = "always"; + RuntimeDirectory = "netbird-mgmt"; + StateDirectory = "netbird-mgmt"; + WorkingDirectory = "/var/lib/netbird-mgmt"; + + # hardening + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateMounts = true; + PrivateTmp = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectSystem = true; + RemoveIPC = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + }; + + stopIfChanged = false; + }; + + services.nginx = mkIf cfg.enableNginx { + enable = true; + + virtualHosts.${cfg.domain} = { + locations."/signalexchange.SignalExchange/".extraConfig = '' + # This is necessary so that grpc connections do not get closed early + # see https://stackoverflow.com/a/67805465 + client_body_timeout 1d; + + grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + grpc_pass grpc://localhost:${builtins.toString cfg.port}; + grpc_read_timeout 1d; + grpc_send_timeout 1d; + grpc_socket_keepalive on; + ''; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index e33bbb2af178..b7143cf520f9 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -470,7 +470,7 @@ in - [main] - no-auto-default=* - ''' - + extraConfig.main.no-auto-default = "*"; + + settings.main.no-auto-default = "*"; }; ``` '' diff --git a/nixos/modules/services/networking/pixiecore.nix b/nixos/modules/services/networking/pixiecore.nix index e61d32e13609..cfdb8014136e 100644 --- a/nixos/modules/services/networking/pixiecore.nix +++ b/nixos/modules/services/networking/pixiecore.nix @@ -6,7 +6,7 @@ let cfg = config.services.pixiecore; in { - meta.maintainers = with maintainers; [ bbigras danderson ]; + meta.maintainers = with maintainers; [ bbigras ]; options = { services.pixiecore = { diff --git a/nixos/modules/services/networking/pppd.nix b/nixos/modules/services/networking/pppd.nix index d937456efddd..8310b119b5f6 100644 --- a/nixos/modules/services/networking/pppd.nix +++ b/nixos/modules/services/networking/pppd.nix @@ -7,7 +7,7 @@ let in { meta = { - maintainers = with maintainers; [ danderson ]; + maintainers = with maintainers; [ ]; }; options = { diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix index 5f2f6cb07af7..0fdb708bf052 100644 --- a/nixos/modules/services/networking/ssh/sshd.nix +++ b/nixos/modules/services/networking/ssh/sshd.nix @@ -296,6 +296,17 @@ in ''; }; + authorizedKeysInHomedir = mkOption { + type = types.bool; + default = true; + description = '' + Enables the use of the `~/.ssh/authorized_keys` file. + + Otherwise, the only files trusted by default are those in `/etc/ssh/authorized_keys.d`, + *i.e.* SSH keys from [](#opt-users.users._name_.openssh.authorizedKeys.keys). + ''; + }; + authorizedKeysCommand = mkOption { type = types.str; default = "none"; @@ -346,6 +357,7 @@ in violates the privacy of users and is not recommended. ''; }; + UsePAM = mkEnableOption "PAM authentication" // { default = true; }; UseDns = mkOption { type = types.bool; # apply if cfg.useDns then "yes" else "no" @@ -489,6 +501,8 @@ in {manpage}`sshd_config(5)` for details. ''; }; + # Disabled by default, since pam_motd handles this. + PrintMotd = mkEnableOption "printing /etc/motd when a user logs in interactively"; }; }); }; @@ -622,7 +636,7 @@ in networking.firewall.allowedTCPPorts = optionals cfg.openFirewall cfg.ports; - security.pam.services.sshd = + security.pam.services.sshd = lib.mkIf cfg.settings.UsePAM { startSession = true; showMotd = true; unixAuth = cfg.settings.PasswordAuthentication; @@ -632,14 +646,12 @@ in # https://github.com/NixOS/nixpkgs/pull/10155 # https://github.com/NixOS/nixpkgs/pull/41745 services.openssh.authorizedKeysFiles = - [ "%h/.ssh/authorized_keys" "/etc/ssh/authorized_keys.d/%u" ]; + lib.optional cfg.authorizedKeysInHomedir "%h/.ssh/authorized_keys" ++ [ "/etc/ssh/authorized_keys.d/%u" ]; services.openssh.settings.AuthorizedPrincipalsFile = mkIf (authPrincipalsFiles != {}) "/etc/ssh/authorized_principals.d/%u"; services.openssh.extraConfig = mkOrder 0 '' - UsePAM yes - Banner ${if cfg.banner == null then "none" else pkgs.writeText "ssh_banner" cfg.banner} AddressFamily ${if config.networking.enableIPv6 then "any" else "inet"} @@ -657,7 +669,6 @@ in ${optionalString cfg.allowSFTP '' Subsystem sftp ${cfg.sftpServerExecutable} ${concatStringsSep " " cfg.sftpFlags} ''} - PrintMotd no # handled by pam_motd AuthorizedKeysFile ${toString cfg.authorizedKeysFiles} ${optionalString (cfg.authorizedKeysCommand != "none") '' AuthorizedKeysCommand ${cfg.authorizedKeysCommand} diff --git a/nixos/modules/services/networking/sunshine.nix b/nixos/modules/services/networking/sunshine.nix new file mode 100644 index 000000000000..ec78db1f3f8e --- /dev/null +++ b/nixos/modules/services/networking/sunshine.nix @@ -0,0 +1,163 @@ +{ config, lib, pkgs, utils, ... }: +let + inherit (lib) mkEnableOption mkPackageOption mkOption literalExpression mkIf mkDefault types optionals getExe; + inherit (utils) escapeSystemdExecArgs; + cfg = config.services.sunshine; + + # ports used are offset from a single base port, see https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/advanced_usage.html#port + generatePorts = port: offsets: map (offset: port + offset) offsets; + defaultPort = 47989; + + appsFormat = pkgs.formats.json { }; + settingsFormat = pkgs.formats.keyValue { }; + + appsFile = appsFormat.generate "apps.json" cfg.applications; + configFile = settingsFormat.generate "sunshine.conf" cfg.settings; +in +{ + options.services.sunshine = with types; { + enable = mkEnableOption "Sunshine, a self-hosted game stream host for Moonlight"; + package = mkPackageOption pkgs "sunshine" { }; + openFirewall = mkOption { + type = bool; + default = false; + description = '' + Whether to automatically open ports in the firewall. + ''; + }; + capSysAdmin = mkOption { + type = bool; + default = false; + description = '' + Whether to give the Sunshine binary CAP_SYS_ADMIN, required for DRM/KMS screen capture. + ''; + }; + autoStart = mkOption { + type = bool; + default = true; + description = '' + Whether sunshine should be started automatically. + ''; + }; + settings = mkOption { + default = { }; + description = '' + Settings to be rendered into the configuration file. If this is set, no configuration is possible from the web UI. + + See https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/advanced_usage.html#configuration for syntax. + ''; + example = literalExpression '' + { + sunshine_name = "nixos"; + } + ''; + type = submodule (settings: { + freeformType = settingsFormat.type; + options.port = mkOption { + type = port; + default = defaultPort; + description = '' + Base port -- others used are offset from this one, see https://docs.lizardbyte.dev/projects/sunshine/en/latest/about/advanced_usage.html#port for details. + ''; + }; + }); + }; + applications = mkOption { + default = { }; + description = '' + Configuration for applications to be exposed to Moonlight. If this is set, no configuration is possible from the web UI, and must be by the `settings` option. + ''; + example = literalExpression '' + { + env = { + PATH = "$(PATH):$(HOME)/.local/bin"; + }; + apps = [ + { + name = "1440p Desktop"; + prep-cmd = [ + { + do = "''${pkgs.kdePackages.libkscreen}/bin/kscreen-doctor output.DP-4.mode.2560x1440@144"; + undo = "''${pkgs.kdePackages.libkscreen}/bin/kscreen-doctor output.DP-4.mode.3440x1440@144"; + } + ]; + exclude-global-prep-cmd = "false"; + auto-detach = "true"; + } + ]; + } + ''; + type = submodule { + options = { + env = mkOption { + default = { }; + description = '' + Environment variables to be set for the applications. + ''; + type = attrsOf str; + }; + apps = mkOption { + default = [ ]; + description = '' + Applications to be exposed to Moonlight. + ''; + type = listOf attrs; + }; + }; + }; + }; + }; + + config = mkIf cfg.enable { + services.sunshine.settings.file_apps = mkIf (cfg.applications.apps != [ ]) "${appsFile}"; + + environment.systemPackages = [ + cfg.package + ]; + + networking.firewall = mkIf cfg.openFirewall { + allowedTCPPorts = generatePorts cfg.settings.port [ (-5) 0 1 21 ]; + allowedUDPPorts = generatePorts cfg.settings.port [ 9 10 11 13 21 ]; + }; + + boot.kernelModules = [ "uinput" ]; + + services.udev.packages = [ cfg.package ]; + + services.avahi = { + enable = mkDefault true; + publish = { + enable = mkDefault true; + userServices = mkDefault true; + }; + }; + + security.wrappers.sunshine = mkIf cfg.capSysAdmin { + owner = "root"; + group = "root"; + capabilities = "cap_sys_admin+p"; + source = getExe cfg.package; + }; + + systemd.user.services.sunshine = { + description = "Self-hosted game stream host for Moonlight"; + + wantedBy = mkIf cfg.autoStart [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + wants = [ "graphical-session.target" ]; + after = [ "graphical-session.target" ]; + + startLimitIntervalSec = 500; + startLimitBurst = 5; + + serviceConfig = { + # only add configFile if an application or a setting other than the default port is set to allow configuration from web UI + ExecStart = escapeSystemdExecArgs ([ + (if cfg.capSysAdmin then "${config.security.wrapperDir}/sunshine" else "${getExe cfg.package}") + ] ++ optionals (cfg.applications.apps != [ ] || (builtins.length (builtins.attrNames cfg.settings) > 1 || cfg.settings.port != defaultPort)) [ "${configFile}" ]); + Restart = "on-failure"; + RestartSec = "5s"; + }; + }; + }; +} diff --git a/nixos/modules/services/networking/tailscale.nix b/nixos/modules/services/networking/tailscale.nix index 2a77c0c7a23e..a79e47d8491b 100644 --- a/nixos/modules/services/networking/tailscale.nix +++ b/nixos/modules/services/networking/tailscale.nix @@ -6,7 +6,7 @@ let cfg = config.services.tailscale; isNetworkd = config.networking.useNetworkd; in { - meta.maintainers = with maintainers; [ danderson mbaillie twitchyliquid64 mfrw ]; + meta.maintainers = with maintainers; [ mbaillie mfrw ]; options.services.tailscale = { enable = mkEnableOption "Tailscale client daemon"; diff --git a/nixos/modules/services/networking/trust-dns.nix b/nixos/modules/services/networking/trust-dns.nix index e6f8cc15819f..039b7de26350 100644 --- a/nixos/modules/services/networking/trust-dns.nix +++ b/nixos/modules/services/networking/trust-dns.nix @@ -51,7 +51,7 @@ in package = mkPackageOption pkgs "trust-dns" { extraDescription = '' ::: {.note} - The package must provide `meta.mainProgram` which names the server binayr; any other utilities (client, resolver) are not needed. + The package must provide `meta.mainProgram` which names the server binary; any other utilities (client, resolver) are not needed. ::: ''; }; @@ -86,7 +86,7 @@ in type = types.listOf types.str; default = [ "0.0.0.0" ]; description = '' - List of ipv4 addresses on which to listen for DNS queries. + List of ipv4 addresses on which to listen for DNS queries. ''; }; listen_addrs_ipv6 = mkOption { @@ -114,7 +114,7 @@ in }; zones = mkOption { description = "List of zones to serve."; - default = {}; + default = []; type = types.listOf (types.coercedTo types.str (zone: { inherit zone; }) zoneType); }; }; diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix index c9dd1d1b0f01..435cd530c18d 100644 --- a/nixos/modules/services/networking/wpa_supplicant.nix +++ b/nixos/modules/services/networking/wpa_supplicant.nix @@ -124,11 +124,20 @@ let fi ''} + # ensure wpa_supplicant.conf exists, or the daemon will fail to start + ${optionalString cfg.allowAuxiliaryImperativeNetworks '' + touch /etc/wpa_supplicant.conf + ''} + # substitute environment variables if [ -f "${configFile}" ]; then ${pkgs.gawk}/bin/awk '{ - for(varname in ENVIRON) - gsub("@"varname"@", ENVIRON[varname]) + for(varname in ENVIRON) { + find = "@"varname"@" + repl = ENVIRON[varname] + if (i = index($0, find)) + $0 = substr($0, 1, i-1) repl substr($0, i+length(find)) + } print }' "${configFile}" > "${finalConfig}" else diff --git a/nixos/modules/services/search/manticore.nix b/nixos/modules/services/search/manticore.nix new file mode 100644 index 000000000000..a8fcd9d0b382 --- /dev/null +++ b/nixos/modules/services/search/manticore.nix @@ -0,0 +1,131 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.manticore; + format = pkgs.formats.json { }; + + toSphinx = { + mkKeyValue ? mkKeyValueDefault {} "=", + listsAsDuplicateKeys ? true + }: attrsOfAttrs: + let + # map function to string for each key val + mapAttrsToStringsSep = sep: mapFn: attrs: + concatStringsSep sep + (mapAttrsToList mapFn attrs); + mkSection = sectName: sectValues: '' + ${sectName} { + '' + lib.generators.toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } sectValues + ''}''; + in + # map input to ini sections + mapAttrsToStringsSep "\n" mkSection attrsOfAttrs; + + configFile = pkgs.writeText "manticore.conf" ( + toSphinx { + mkKeyValue = k: v: " ${k} = ${v}"; + } cfg.settings + ); + +in { + + options = { + services.manticore = { + + enable = mkEnableOption "Manticoresearch"; + + settings = mkOption { + default = { + searchd = { + listen = [ + "127.0.0.1:9312" + "127.0.0.1:9306:mysql" + "127.0.0.1:9308:http" + ]; + log = "/var/log/manticore/searchd.log"; + query_log = "/var/log/manticore/query.log"; + pid_file = "/run/manticore/searchd.pid"; + data_dir = "/var/lib/manticore"; + }; + }; + description = '' + Configuration for Manticoresearch. See + + for more information. + ''; + type = types.submodule { + freeformType = format.type; + }; + example = literalExpression '' + { + searchd = { + listen = [ + "127.0.0.1:9312" + "127.0.0.1:9306:mysql" + "127.0.0.1:9308:http" + ]; + log = "/var/log/manticore/searchd.log"; + query_log = "/var/log/manticore/query.log"; + pid_file = "/run/manticore/searchd.pid"; + data_dir = "/var/lib/manticore"; + }; + } + ''; + }; + + }; + }; + + config = mkIf cfg.enable { + + systemd = { + packages = [ pkgs.manticoresearch ]; + services.manticore = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + ExecStart = [ + "" + "${pkgs.manticoresearch}/bin/searchd --config ${configFile}" + ]; + ExecStop = [ + "" + "${pkgs.manticoresearch}/bin/searchd --config ${configFile} --stopwait" + ]; + ExecStartPre = [ "" ]; + DynamicUser = true; + LogsDirectory = "manticore"; + RuntimeDirectory = "manticore"; + StateDirectory = "manticore"; + ReadWritePaths = ""; + CapabilityBoundingSet = ""; + RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ]; + RestrictNamespaces = true; + PrivateDevices = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@privileged" ]; + RestrictRealtime = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + UMask = "0066"; + ProtectHostname = true; + } // lib.optionalAttrs (cfg.settings.searchd.pid_file != null) { + PIDFile = cfg.settings.searchd.pid_file; + }; + }; + }; + + }; + + meta.maintainers = with lib.maintainers; [ onny ]; + +} diff --git a/nixos/modules/services/security/oauth2-proxy-nginx.nix b/nixos/modules/services/security/oauth2-proxy-nginx.nix new file mode 100644 index 000000000000..c05bd304752d --- /dev/null +++ b/nixos/modules/services/security/oauth2-proxy-nginx.nix @@ -0,0 +1,130 @@ +{ config, lib, ... }: +let + cfg = config.services.oauth2-proxy.nginx; +in +{ + options.services.oauth2-proxy.nginx = { + proxy = lib.mkOption { + type = lib.types.str; + default = config.services.oauth2-proxy.httpAddress; + defaultText = lib.literalExpression "config.services.oauth2-proxy.httpAddress"; + description = '' + The address of the reverse proxy endpoint for oauth2-proxy + ''; + }; + + domain = lib.mkOption { + type = lib.types.str; + description = '' + The domain under which the oauth2-proxy will be accesible and the path of cookies are set to. + This setting must be set to ensure back-redirects are working properly + if oauth2-proxy is configured with {option}`services.oauth2-proxy.cookie.domain` + or multiple {option}`services.oauth2-proxy.nginx.virtualHosts` that are not on the same domain. + ''; + }; + + virtualHosts = lib.mkOption { + type = let + vhostSubmodule = lib.types.submodule { + options = { + allowed_groups = lib.mkOption { + type = lib.types.nullOr (lib.types.listOf lib.types.str); + description = "List of groups to allow access to this vhost, or null to allow all."; + default = null; + }; + allowed_emails = lib.mkOption { + type = lib.types.nullOr (lib.types.listOf lib.types.str); + description = "List of emails to allow access to this vhost, or null to allow all."; + default = null; + }; + allowed_email_domains = lib.mkOption { + type = lib.types.nullOr (lib.types.listOf lib.types.str); + description = "List of email domains to allow access to this vhost, or null to allow all."; + default = null; + }; + }; + }; + oldType = lib.types.listOf lib.types.str; + convertFunc = x: + lib.warn "services.oauth2-proxy.nginx.virtualHosts should be an attrset, found ${lib.generators.toPretty {} x}" + lib.genAttrs x (_: {}); + newType = lib.types.attrsOf vhostSubmodule; + in lib.types.coercedTo oldType convertFunc newType; + default = {}; + example = { + "protected.foo.com" = { + allowed_groups = ["admins"]; + allowed_emails = ["boss@foo.com"]; + }; + }; + description = '' + Nginx virtual hosts to put behind the oauth2 proxy. + You can exclude specific locations by setting `auth_request off;` in the locations extraConfig setting. + ''; + }; + }; + + config.services.oauth2-proxy = lib.mkIf (cfg.virtualHosts != [] && (lib.hasPrefix "127.0.0.1:" cfg.proxy)) { + enable = true; + }; + + config.services.nginx = lib.mkIf (cfg.virtualHosts != [] && config.services.oauth2-proxy.enable) (lib.mkMerge ([ + { + virtualHosts.${cfg.domain}.locations."/oauth2/" = { + proxyPass = cfg.proxy; + extraConfig = '' + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; + ''; + }; + } + ] ++ lib.optional (cfg.virtualHosts != []) { + recommendedProxySettings = true; # needed because duplicate headers + } ++ (lib.mapAttrsToList (vhost: conf: { + virtualHosts.${vhost} = { + locations = { + "/oauth2/auth" = let + maybeQueryArg = name: value: + if value == null then null + else "${name}=${lib.concatStringsSep "," (builtins.map lib.escapeURL value)}"; + allArgs = lib.mapAttrsToList maybeQueryArg conf; + cleanArgs = builtins.filter (x: x != null) allArgs; + cleanArgsStr = lib.concatStringsSep "&" cleanArgs; + in { + # nginx doesn't support passing query string arguments to auth_request, + # so pass them here instead + proxyPass = "${cfg.proxy}/oauth2/auth?${cleanArgsStr}"; + extraConfig = '' + auth_request off; + proxy_set_header X-Scheme $scheme; + # nginx auth_request includes headers but not body + proxy_set_header Content-Length ""; + proxy_pass_request_body off; + ''; + }; + "@redirectToAuth2ProxyLogin" = { + return = "307 https://${cfg.domain}/oauth2/start?rd=$scheme://$host$request_uri"; + extraConfig = '' + auth_request off; + ''; + }; + }; + + extraConfig = '' + auth_request /oauth2/auth; + error_page 401 = @redirectToAuth2ProxyLogin; + + # pass information via X-User and X-Email headers to backend, + # requires running with --set-xauthrequest flag + auth_request_set $user $upstream_http_x_auth_request_user; + auth_request_set $email $upstream_http_x_auth_request_email; + proxy_set_header X-User $user; + proxy_set_header X-Email $email; + + # if you enabled --cookie-refresh, this is needed for it to work with auth_request + auth_request_set $auth_cookie $upstream_http_set_cookie; + add_header Set-Cookie $auth_cookie; + ''; + }; + }) cfg.virtualHosts))); +} diff --git a/nixos/modules/services/security/oauth2_proxy.nix b/nixos/modules/services/security/oauth2-proxy.nix similarity index 70% rename from nixos/modules/services/security/oauth2_proxy.nix rename to nixos/modules/services/security/oauth2-proxy.nix index abf1ce9ba020..075e64b743b1 100644 --- a/nixos/modules/services/security/oauth2_proxy.nix +++ b/nixos/modules/services/security/oauth2-proxy.nix @@ -1,15 +1,12 @@ -# NixOS module for oauth2_proxy. - { config, lib, pkgs, ... }: -with lib; let - cfg = config.services.oauth2_proxy; + cfg = config.services.oauth2-proxy; - # oauth2_proxy provides many options that are only relevant if you are using + # oauth2-proxy provides many options that are only relevant if you are using # a certain provider. This set maps from provider name to a function that # takes the configuration and returns a string that can be inserted into the - # command-line to launch oauth2_proxy. + # command-line to launch oauth2-proxy. providerSpecificOptions = { azure = cfg: { azure-tenant = cfg.azure.tenant; @@ -47,6 +44,7 @@ let reverse-proxy = reverseProxy; proxy-prefix = proxyPrefix; profile-url = profileURL; + oidc-issuer-url = oidcIssuerUrl; redeem-url = redeemURL; redirect-url = redirectURL; request-logging = requestLogging; @@ -72,28 +70,28 @@ let } // (getProviderOptions cfg cfg.provider) // cfg.extraConfig; mapConfig = key: attr: - optionalString (attr != null && attr != []) ( - if isDerivation attr then mapConfig key (toString attr) else - if (builtins.typeOf attr) == "set" then concatStringsSep " " - (mapAttrsToList (name: value: mapConfig (key + "-" + name) value) attr) else - if (builtins.typeOf attr) == "list" then concatMapStringsSep " " (mapConfig key) attr else - if (builtins.typeOf attr) == "bool" then "--${key}=${boolToString attr}" else + lib.optionalString (attr != null && attr != []) ( + if lib.isDerivation attr then mapConfig key (toString attr) else + if (builtins.typeOf attr) == "set" then lib.concatStringsSep " " + (lib.mapAttrsToList (name: value: mapConfig (key + "-" + name) value) attr) else + if (builtins.typeOf attr) == "list" then lib.concatMapStringsSep " " (mapConfig key) attr else + if (builtins.typeOf attr) == "bool" then "--${key}=${lib.boolToString attr}" else if (builtins.typeOf attr) == "string" then "--${key}='${attr}'" else "--${key}=${toString attr}"); - configString = concatStringsSep " " (mapAttrsToList mapConfig allConfig); + configString = lib.concatStringsSep " " (lib.mapAttrsToList mapConfig allConfig); in { - options.services.oauth2_proxy = { - enable = mkEnableOption "oauth2_proxy"; + options.services.oauth2-proxy = { + enable = lib.mkEnableOption "oauth2-proxy"; - package = mkPackageOption pkgs "oauth2-proxy" { }; + package = lib.mkPackageOption pkgs "oauth2-proxy" { }; ############################################## # PROVIDER configuration # Taken from: https://github.com/oauth2-proxy/oauth2-proxy/blob/master/providers/providers.go - provider = mkOption { - type = types.enum [ + provider = lib.mkOption { + type = lib.types.enum [ "adfs" "azure" "bitbucket" @@ -115,31 +113,40 @@ in ''; }; - approvalPrompt = mkOption { - type = types.enum ["force" "auto"]; + approvalPrompt = lib.mkOption { + type = lib.types.enum ["force" "auto"]; default = "force"; description = '' OAuth approval_prompt. ''; }; - clientID = mkOption { - type = types.nullOr types.str; + clientID = lib.mkOption { + type = lib.types.nullOr lib.types.str; description = '' The OAuth Client ID. ''; example = "123456.apps.googleusercontent.com"; }; - clientSecret = mkOption { - type = types.nullOr types.str; + oidcIssuerUrl = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + description = '' + The OAuth issuer URL. + ''; + example = "https://login.microsoftonline.com/{TENANT_ID}/v2.0"; + }; + + clientSecret = lib.mkOption { + type = lib.types.nullOr lib.types.str; description = '' The OAuth Client Secret. ''; }; - skipAuthRegexes = mkOption { - type = types.listOf types.str; + skipAuthRegexes = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Skip authentication for requests matching any of these regular @@ -149,8 +156,8 @@ in # XXX: Not clear whether these two options are mutually exclusive or not. email = { - domains = mkOption { - type = types.listOf types.str; + domains = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Authenticate emails with the specified domains. Use @@ -158,8 +165,8 @@ in ''; }; - addresses = mkOption { - type = types.nullOr types.lines; + addresses = lib.mkOption { + type = lib.types.nullOr lib.types.lines; default = null; description = '' Line-separated email addresses that are allowed to authenticate. @@ -167,8 +174,8 @@ in }; }; - loginURL = mkOption { - type = types.nullOr types.str; + loginURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Authentication endpoint. @@ -180,8 +187,8 @@ in example = "https://provider.example.com/oauth/authorize"; }; - redeemURL = mkOption { - type = types.nullOr types.str; + redeemURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Token redemption endpoint. @@ -193,8 +200,8 @@ in example = "https://provider.example.com/oauth/token"; }; - validateURL = mkOption { - type = types.nullOr types.str; + validateURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Access token validation endpoint. @@ -206,10 +213,10 @@ in example = "https://provider.example.com/user/emails"; }; - redirectURL = mkOption { + redirectURL = lib.mkOption { # XXX: jml suspects this is always necessary, but the command-line # doesn't require it so making it optional. - type = types.nullOr types.str; + type = lib.types.nullOr lib.types.str; default = null; description = '' The OAuth2 redirect URL. @@ -218,16 +225,16 @@ in }; azure = { - tenant = mkOption { - type = types.str; + tenant = lib.mkOption { + type = lib.types.str; default = "common"; description = '' Go to a tenant-specific or common (tenant-independent) endpoint. ''; }; - resource = mkOption { - type = types.str; + resource = lib.mkOption { + type = lib.types.str; description = '' The resource that is protected. ''; @@ -235,8 +242,8 @@ in }; google = { - adminEmail = mkOption { - type = types.str; + adminEmail = lib.mkOption { + type = lib.types.str; description = '' The Google Admin to impersonate for API calls. @@ -248,16 +255,16 @@ in ''; }; - groups = mkOption { - type = types.listOf types.str; + groups = lib.mkOption { + type = lib.types.listOf lib.types.str; default = []; description = '' Restrict logins to members of these Google groups. ''; }; - serviceAccountJSON = mkOption { - type = types.path; + serviceAccountJSON = lib.mkOption { + type = lib.types.path; description = '' The path to the service account JSON credentials. ''; @@ -265,16 +272,16 @@ in }; github = { - org = mkOption { - type = types.nullOr types.str; + org = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Restrict logins to members of this organisation. ''; }; - team = mkOption { - type = types.nullOr types.str; + team = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Restrict logins to members of this team. @@ -285,8 +292,8 @@ in #################################################### # UPSTREAM Configuration - upstream = mkOption { - type = with types; coercedTo str (x: [x]) (listOf str); + upstream = lib.mkOption { + type = with lib.types; coercedTo str (x: [x]) (listOf str); default = []; description = '' The http url(s) of the upstream endpoint or `file://` @@ -294,40 +301,40 @@ in ''; }; - passAccessToken = mkOption { - type = types.bool; + passAccessToken = lib.mkOption { + type = lib.types.bool; default = false; description = '' Pass OAuth access_token to upstream via X-Forwarded-Access-Token header. ''; }; - passBasicAuth = mkOption { - type = types.bool; + passBasicAuth = lib.mkOption { + type = lib.types.bool; default = true; description = '' Pass HTTP Basic Auth, X-Forwarded-User and X-Forwarded-Email information to upstream. ''; }; - basicAuthPassword = mkOption { - type = types.nullOr types.str; + basicAuthPassword = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' The password to set when passing the HTTP Basic Auth header. ''; }; - passHostHeader = mkOption { - type = types.bool; + passHostHeader = lib.mkOption { + type = lib.types.bool; default = true; description = '' Pass the request Host Header to upstream. ''; }; - signatureKey = mkOption { - type = types.nullOr types.str; + signatureKey = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' GAP-Signature request signature key. @@ -336,8 +343,8 @@ in }; cookie = { - domain = mkOption { - type = types.nullOr types.str; + domain = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Optional cookie domains to force cookies to (ie: `.yourcompany.com`). @@ -347,33 +354,33 @@ in example = ".yourcompany.com"; }; - expire = mkOption { - type = types.str; + expire = lib.mkOption { + type = lib.types.str; default = "168h0m0s"; description = '' Expire timeframe for cookie. ''; }; - httpOnly = mkOption { - type = types.bool; + httpOnly = lib.mkOption { + type = lib.types.bool; default = true; description = '' Set HttpOnly cookie flag. ''; }; - name = mkOption { - type = types.str; + name = lib.mkOption { + type = lib.types.str; default = "_oauth2_proxy"; description = '' The name of the cookie that the oauth_proxy creates. ''; }; - refresh = mkOption { + refresh = lib.mkOption { # XXX: Unclear what the behavior is when this is not specified. - type = types.nullOr types.str; + type = lib.types.nullOr lib.types.str; default = null; description = '' Refresh the cookie after this duration; 0 to disable. @@ -381,15 +388,15 @@ in example = "168h0m0s"; }; - secret = mkOption { - type = types.nullOr types.str; + secret = lib.mkOption { + type = lib.types.nullOr lib.types.str; description = '' The seed string for secure cookies. ''; }; - secure = mkOption { - type = types.bool; + secure = lib.mkOption { + type = lib.types.bool; default = true; description = '' Set secure (HTTPS) cookie flag. @@ -400,8 +407,8 @@ in #################################################### # OAUTH2 PROXY configuration - httpAddress = mkOption { - type = types.str; + httpAddress = lib.mkOption { + type = lib.types.str; default = "http://127.0.0.1:4180"; description = '' HTTPS listening address. This module does not expose the port by @@ -411,8 +418,8 @@ in }; htpasswd = { - file = mkOption { - type = types.nullOr types.path; + file = lib.mkOption { + type = lib.types.nullOr lib.types.path; default = null; description = '' Additionally authenticate against a htpasswd file. Entries must be @@ -420,8 +427,8 @@ in ''; }; - displayForm = mkOption { - type = types.bool; + displayForm = lib.mkOption { + type = lib.types.bool; default = true; description = '' Display username / password login form if an htpasswd file is provided. @@ -429,16 +436,16 @@ in }; }; - customTemplatesDir = mkOption { - type = types.nullOr types.path; + customTemplatesDir = lib.mkOption { + type = lib.types.nullOr lib.types.path; default = null; description = '' Path to custom HTML templates. ''; }; - reverseProxy = mkOption { - type = types.bool; + reverseProxy = lib.mkOption { + type = lib.types.bool; default = false; description = '' In case when running behind a reverse proxy, controls whether headers @@ -448,8 +455,8 @@ in ''; }; - proxyPrefix = mkOption { - type = types.str; + proxyPrefix = lib.mkOption { + type = lib.types.str; default = "/oauth2"; description = '' The url root path that this proxy should be nested under. @@ -457,30 +464,30 @@ in }; tls = { - enable = mkOption { - type = types.bool; + enable = lib.mkOption { + type = lib.types.bool; default = false; description = '' Whether to serve over TLS. ''; }; - certificate = mkOption { - type = types.path; + certificate = lib.mkOption { + type = lib.types.path; description = '' Path to certificate file. ''; }; - key = mkOption { - type = types.path; + key = lib.mkOption { + type = lib.types.path; description = '' Path to private key file. ''; }; - httpsAddress = mkOption { - type = types.str; + httpsAddress = lib.mkOption { + type = lib.types.str; default = ":443"; description = '' `addr:port` to listen on for HTTPS clients. @@ -492,8 +499,8 @@ in }; }; - requestLogging = mkOption { - type = types.bool; + requestLogging = lib.mkOption { + type = lib.types.bool; default = true; description = '' Log requests to stdout. @@ -504,42 +511,42 @@ in # UNKNOWN # XXX: Is this mandatory? Is it part of another group? Is it part of the provider specification? - scope = mkOption { + scope = lib.mkOption { # XXX: jml suspects this is always necessary, but the command-line # doesn't require it so making it optional. - type = types.nullOr types.str; + type = lib.types.nullOr lib.types.str; default = null; description = '' OAuth scope specification. ''; }; - profileURL = mkOption { - type = types.nullOr types.str; + profileURL = lib.mkOption { + type = lib.types.nullOr lib.types.str; default = null; description = '' Profile access endpoint. ''; }; - setXauthrequest = mkOption { - type = types.nullOr types.bool; + setXauthrequest = lib.mkOption { + type = lib.types.nullOr lib.types.bool; default = false; description = '' Set X-Auth-Request-User and X-Auth-Request-Email response headers (useful in Nginx auth_request mode). Setting this to 'null' means using the upstream default (false). ''; }; - extraConfig = mkOption { + extraConfig = lib.mkOption { default = {}; - type = types.attrsOf types.anything; + type = lib.types.attrsOf lib.types.anything; description = '' Extra config to pass to oauth2-proxy. ''; }; - keyFile = mkOption { - type = types.nullOr types.path; + keyFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; default = null; description = '' oauth2-proxy allows passing sensitive configuration via environment variables. @@ -547,28 +554,30 @@ in OAUTH2_PROXY_CLIENT_SECRET=asdfasdfasdf.apps.googleuserscontent.com and specify the path here. ''; - example = "/run/keys/oauth2_proxy"; + example = "/run/keys/oauth2-proxy"; }; - }; - config = mkIf cfg.enable { + imports = [ + (lib.mkRenamedOptionModule [ "services" "oauth2_proxy" ] [ "services" "oauth2-proxy" ]) + ]; - services.oauth2_proxy = mkIf (cfg.keyFile != null) { - clientID = mkDefault null; - clientSecret = mkDefault null; - cookie.secret = mkDefault null; + config = lib.mkIf cfg.enable { + services.oauth2-proxy = lib.mkIf (cfg.keyFile != null) { + clientID = lib.mkDefault null; + clientSecret = lib.mkDefault null; + cookie.secret = lib.mkDefault null; }; - users.users.oauth2_proxy = { + users.users.oauth2-proxy = { description = "OAuth2 Proxy"; isSystemUser = true; - group = "oauth2_proxy"; + group = "oauth2-proxy"; }; - users.groups.oauth2_proxy = {}; + users.groups.oauth2-proxy = {}; - systemd.services.oauth2_proxy = { + systemd.services.oauth2-proxy = { description = "OAuth2 Proxy"; path = [ cfg.package ]; wantedBy = [ "multi-user.target" ]; @@ -576,10 +585,10 @@ in after = [ "network-online.target" ]; serviceConfig = { - User = "oauth2_proxy"; + User = "oauth2-proxy"; Restart = "always"; ExecStart = "${cfg.package}/bin/oauth2-proxy ${configString}"; - EnvironmentFile = mkIf (cfg.keyFile != null) cfg.keyFile; + EnvironmentFile = lib.mkIf (cfg.keyFile != null) cfg.keyFile; }; }; diff --git a/nixos/modules/services/security/oauth2_proxy_nginx.nix b/nixos/modules/services/security/oauth2_proxy_nginx.nix deleted file mode 100644 index 87ea61276837..000000000000 --- a/nixos/modules/services/security/oauth2_proxy_nginx.nix +++ /dev/null @@ -1,91 +0,0 @@ -{ config, lib, ... }: -with lib; -let - cfg = config.services.oauth2_proxy.nginx; -in -{ - options.services.oauth2_proxy.nginx = { - proxy = mkOption { - type = types.str; - default = config.services.oauth2_proxy.httpAddress; - defaultText = literalExpression "config.services.oauth2_proxy.httpAddress"; - description = '' - The address of the reverse proxy endpoint for oauth2_proxy - ''; - }; - - domain = mkOption { - type = types.str; - description = '' - The domain under which the oauth2_proxy will be accesible and the path of cookies are set to. - This setting must be set to ensure back-redirects are working properly - if oauth2-proxy is configured with {option}`services.oauth2_proxy.cookie.domain` - or multiple {option}`services.oauth2_proxy.nginx.virtualHosts` that are not on the same domain. - ''; - }; - - virtualHosts = mkOption { - type = types.listOf types.str; - default = []; - description = '' - A list of nginx virtual hosts to put behind the oauth2 proxy. - You can exclude specific locations by setting `auth_request off;` in the locations extraConfig setting. - ''; - }; - }; - - config.services.oauth2_proxy = mkIf (cfg.virtualHosts != [] && (hasPrefix "127.0.0.1:" cfg.proxy)) { - enable = true; - }; - - config.services.nginx = mkIf (cfg.virtualHosts != [] && config.services.oauth2_proxy.enable) (mkMerge ([ - { - virtualHosts.${cfg.domain}.locations."/oauth2/" = { - proxyPass = cfg.proxy; - extraConfig = '' - proxy_set_header X-Scheme $scheme; - proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; - ''; - }; - } - ] ++ optional (cfg.virtualHosts != []) { - recommendedProxySettings = true; # needed because duplicate headers - } ++ (map (vhost: { - virtualHosts.${vhost} = { - locations = { - "/oauth2/auth" = { - proxyPass = cfg.proxy; - extraConfig = '' - auth_request off; - proxy_set_header X-Scheme $scheme; - # nginx auth_request includes headers but not body - proxy_set_header Content-Length ""; - proxy_pass_request_body off; - ''; - }; - "@redirectToAuth2ProxyLogin" = { - return = "307 https://${cfg.domain}/oauth2/start?rd=$scheme://$host$request_uri"; - extraConfig = '' - auth_request off; - ''; - }; - }; - - extraConfig = '' - auth_request /oauth2/auth; - error_page 401 = @redirectToAuth2ProxyLogin; - - # pass information via X-User and X-Email headers to backend, - # requires running with --set-xauthrequest flag - auth_request_set $user $upstream_http_x_auth_request_user; - auth_request_set $email $upstream_http_x_auth_request_email; - proxy_set_header X-User $user; - proxy_set_header X-Email $email; - - # if you enabled --cookie-refresh, this is needed for it to work with auth_request - auth_request_set $auth_cookie $upstream_http_set_cookie; - add_header Set-Cookie $auth_cookie; - ''; - }; - }) cfg.virtualHosts))); -} diff --git a/nixos/modules/services/security/vault.nix b/nixos/modules/services/security/vault.nix index ab86da47b2e1..650f9bda99c3 100644 --- a/nixos/modules/services/security/vault.nix +++ b/nixos/modules/services/security/vault.nix @@ -56,8 +56,8 @@ in }; devRootTokenID = mkOption { - type = types.str; - default = false; + type = types.nullOr types.str; + default = null; description = '' Initial root token. This only applies when {option}`services.vault.dev` is true ''; diff --git a/nixos/modules/services/security/vaultwarden/default.nix b/nixos/modules/services/security/vaultwarden/default.nix index b2920931f9a9..33957be437b3 100644 --- a/nixos/modules/services/security/vaultwarden/default.nix +++ b/nixos/modules/services/security/vaultwarden/default.nix @@ -131,21 +131,13 @@ in { Additional environment file as defined in {manpage}`systemd.exec(5)`. Secrets like {env}`ADMIN_TOKEN` and {env}`SMTP_PASSWORD` - may be passed to the service without adding them to the world-readable Nix store. + should be passed to the service without adding them to the world-readable Nix store. - Note that this file needs to be available on the host on which - `vaultwarden` is running. + Note that this file needs to be available on the host on which `vaultwarden` is running. - As a concrete example, to make the Admin UI available - (from which new users can be invited initially), + As a concrete example, to make the Admin UI available (from which new users can be invited initially), the secret {env}`ADMIN_TOKEN` needs to be defined as described - [here](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page). - Setting `environmentFile` to `/var/lib/vaultwarden.env` - and ensuring permissions with e.g. - `chown vaultwarden:vaultwarden /var/lib/vaultwarden.env` - (the `vaultwarden` user will only exist after activating with - `enable = true;` before this), we can set the contents of the file to have - contents such as: + [here](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page): ``` # Admin secret token, see diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix index a9fc88e320c6..26f4eba707f9 100644 --- a/nixos/modules/services/system/dbus.nix +++ b/nixos/modules/services/system/dbus.nix @@ -39,7 +39,7 @@ in implementation = mkOption { type = types.enum [ "dbus" "broker" ]; - default = "broker"; + default = "dbus"; description = '' The implementation to use for the message bus defined by the D-Bus specification. Can be either the classic dbus daemon or dbus-broker, which aims to provide high @@ -147,6 +147,10 @@ in }; systemd.services.dbus = { + aliases = [ + # hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus + "dbus-broker.service" + ]; # Don't restart dbus-daemon. Bad things tend to happen if we do. reloadIfChanged = true; restartTriggers = [ @@ -158,6 +162,10 @@ in }; systemd.user.services.dbus = { + aliases = [ + # hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus + "dbus-broker.service" + ]; # Don't restart dbus-daemon. Bad things tend to happen if we do. reloadIfChanged = true; restartTriggers = [ @@ -184,6 +192,8 @@ in # https://github.com/NixOS/nixpkgs/issues/108643 systemd.services.dbus-broker = { aliases = [ + # allow other services to just depend on dbus, + # but also a hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus "dbus.service" ]; unitConfig = { @@ -203,6 +213,8 @@ in systemd.user.services.dbus-broker = { aliases = [ + # allow other services to just depend on dbus, + # but also a hack aiding to prevent dbus from restarting when switching from dbus-broker back to dbus "dbus.service" ]; # Don't restart dbus. Bad things tend to happen if we do. diff --git a/nixos/modules/services/system/earlyoom.nix b/nixos/modules/services/system/earlyoom.nix index bcdf7d6512d5..7e012dee02cb 100644 --- a/nixos/modules/services/system/earlyoom.nix +++ b/nixos/modules/services/system/earlyoom.nix @@ -4,15 +4,29 @@ let cfg = config.services.earlyoom; inherit (lib) - mkDefault mkEnableOption mkIf mkOption types - mkRemovedOptionModule literalExpression - escapeShellArg concatStringsSep optional optionalString; - + concatStringsSep + escapeShellArg + literalExpression + mkDefault + mkEnableOption + mkIf + mkOption + mkPackageOption + mkRemovedOptionModule + optionalString + optionals + types; in { + meta = { + maintainers = with lib.maintainers; [ AndersonTorres ]; + }; + options.services.earlyoom = { enable = mkEnableOption "early out of memory killing"; + package = mkPackageOption pkgs "earlyoom" { }; + freeMemThreshold = mkOption { type = types.ints.between 1 100; default = 10; @@ -138,22 +152,21 @@ in systemd.services.earlyoom = { description = "Early OOM Daemon for Linux"; wantedBy = [ "multi-user.target" ]; - path = optional cfg.enableNotifications pkgs.dbus; + path = optionals cfg.enableNotifications [ pkgs.dbus ]; serviceConfig = { StandardError = "journal"; ExecStart = concatStringsSep " " ([ - "${pkgs.earlyoom}/bin/earlyoom" + "${lib.getExe cfg.package}" ("-m ${toString cfg.freeMemThreshold}" - + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}") + + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}") ("-s ${toString cfg.freeSwapThreshold}" - + optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}") + + optionalString (cfg.freeSwapKillThreshold != null) ",${toString cfg.freeSwapKillThreshold}") "-r ${toString cfg.reportInterval}" ] - ++ optional cfg.enableDebugInfo "-d" - ++ optional cfg.enableNotifications "-n" - ++ optional (cfg.killHook != null) "-N ${escapeShellArg cfg.killHook}" - ++ cfg.extraArgs - ); + ++ optionals cfg.enableDebugInfo [ "-d" ] + ++ optionals cfg.enableNotifications [ "-n" ] + ++ optionals (cfg.killHook != null) [ "-N ${escapeShellArg cfg.killHook}" ] + ++ cfg.extraArgs); }; }; }; diff --git a/nixos/modules/services/web-apps/akkoma.nix b/nixos/modules/services/web-apps/akkoma.nix index eca498549df3..7c9bf6c46516 100644 --- a/nixos/modules/services/web-apps/akkoma.nix +++ b/nixos/modules/services/web-apps/akkoma.nix @@ -817,11 +817,11 @@ in { base_url = mkOption { type = types.nullOr types.nonEmptyStr; default = if lib.versionOlder config.system.stateVersion "24.05" - then "${httpConf.scheme}://${httpConf.host}:${builtins.toString httpConf.port}/media/" + then "${httpConf.scheme}://${httpConf.host}:${builtins.toString httpConf.port}" else null; defaultText = literalExpression '' if lib.versionOlder config.system.stateVersion "24.05" - then "$\{httpConf.scheme}://$\{httpConf.host}:$\{builtins.toString httpConf.port}/media/" + then "$\{httpConf.scheme}://$\{httpConf.host}:$\{builtins.toString httpConf.port}" else null; ''; description = '' @@ -957,7 +957,7 @@ in { assertions = optionals (cfg.config.":pleroma".":media_proxy".enabled && cfg.config.":pleroma".":media_proxy".base_url == null) ['' `services.akkoma.config.":pleroma".":media_proxy".base_url` must be set when the media proxy is enabled. '']; - warnings = optionals (with config.security; (!sudo.enable) && (!sudo-rs.enable)) ['' + warnings = optionals (with config.security; cfg.installWrapper && (!sudo.enable) && (!sudo-rs.enable)) ['' The pleroma_ctl wrapper enabled by the installWrapper option relies on sudo, which appears to have been disabled through security.sudo.enable. '']; diff --git a/nixos/modules/services/web-apps/castopod.nix b/nixos/modules/services/web-apps/castopod.nix index 69ee670276a7..d3750c3dd393 100644 --- a/nixos/modules/services/web-apps/castopod.nix +++ b/nixos/modules/services/web-apps/castopod.nix @@ -17,7 +17,7 @@ let in { meta.doc = ./castopod.md; - meta.maintainers = with lib.maintainers; [ alexoundos misuzu ]; + meta.maintainers = with lib.maintainers; [ alexoundos ]; options.services = { castopod = { diff --git a/nixos/modules/services/web-apps/coder.nix b/nixos/modules/services/web-apps/coder.nix index 318a7c8fc135..5450adbe118d 100644 --- a/nixos/modules/services/web-apps/coder.nix +++ b/nixos/modules/services/web-apps/coder.nix @@ -169,7 +169,7 @@ in { after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; - environment = config.environment.extra // { + environment = cfg.environment.extra // { CODER_ACCESS_URL = cfg.accessUrl; CODER_WILDCARD_ACCESS_URL = cfg.wildcardAccessUrl; CODER_PG_CONNECTION_URL = "user=${cfg.database.username} ${optionalString (cfg.database.password != null) "password=${cfg.database.password}"} database=${cfg.database.database} host=${cfg.database.host} ${optionalString (cfg.database.sslmode != null) "sslmode=${cfg.database.sslmode}"}"; @@ -223,4 +223,5 @@ in { }; }; }; + meta.maintainers = pkgs.coder.meta.maintainers; } diff --git a/nixos/modules/services/web-apps/firefly-iii.nix b/nixos/modules/services/web-apps/firefly-iii.nix new file mode 100644 index 000000000000..b0024ce09c38 --- /dev/null +++ b/nixos/modules/services/web-apps/firefly-iii.nix @@ -0,0 +1,367 @@ +{ pkgs, config, lib, ... }: + +let + inherit (lib) optionalString mkDefault mkIf mkOption mkEnableOption literalExpression; + inherit (lib.types) nullOr attrsOf oneOf str int bool path package enum submodule; + inherit (lib.strings) concatMapStringsSep removePrefix toShellVars removeSuffix hasSuffix; + inherit (lib.attrsets) attrValues genAttrs filterAttrs mapAttrs' nameValuePair; + inherit (builtins) isInt isString toString typeOf; + + cfg = config.services.firefly-iii; + + user = cfg.user; + group = cfg.group; + + defaultUser = "firefly-iii"; + defaultGroup = "firefly-iii"; + + artisan = "${cfg.package}/artisan"; + + env-file-values = mapAttrs' (n: v: nameValuePair (removeSuffix "_FILE" n) v) + (filterAttrs (n: v: hasSuffix "_FILE" n) cfg.settings); + env-nonfile-values = filterAttrs (n: v: ! hasSuffix "_FILE" n) cfg.settings; + + envfile = pkgs.writeText "firefly-iii-env" '' + ${toShellVars env-file-values} + ${toShellVars env-nonfile-values} + ''; + + fileenv-func = '' + cp --no-preserve=mode ${envfile} /tmp/firefly-iii-env + ${concatMapStringsSep "\n" + (n: "${pkgs.replace-secret}/bin/replace-secret ${n} ${n} /tmp/firefly-iii-env") + (attrValues env-file-values)} + set -a + . /tmp/firefly-iii-env + set +a + ''; + + firefly-iii-maintenance = pkgs.writeShellScript "firefly-iii-maintenance.sh" '' + ${fileenv-func} + + ${optionalString (cfg.settings.DB_CONNECTION == "sqlite") + "touch ${cfg.dataDir}/storage/database/database.sqlite"} + ${artisan} migrate --seed --no-interaction --force + ${artisan} firefly-iii:decrypt-all + ${artisan} firefly-iii:upgrade-database + ${artisan} firefly-iii:correct-database + ${artisan} firefly-iii:report-integrity + ${artisan} firefly-iii:laravel-passport-keys + ${artisan} cache:clear + + mv /tmp/firefly-iii-env /run/phpfpm/firefly-iii-env + ''; + + commonServiceConfig = { + Type = "oneshot"; + User = user; + Group = group; + StateDirectory = "${removePrefix "/var/lib/" cfg.dataDir}"; + WorkingDirectory = cfg.package; + PrivateTmp = true; + PrivateDevices = true; + CapabilityBoundingSet = ""; + AmbientCapabilities = ""; + ProtectSystem = "strict"; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + ProtectClock = true; + ProtectHostname = true; + ProtectHome = "tmpfs"; + ProtectKernelLogs = true; + ProtectProc = "invisible"; + ProcSubset = "pid"; + PrivateNetwork = false; + RestrictAddressFamilies = "AF_INET AF_INET6 AF_UNIX"; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "@system-service @resources" + "~@obsolete @privileged" + ]; + RestrictSUIDSGID = true; + RemoveIPC = true; + NoNewPrivileges = true; + RestrictRealtime = true; + RestrictNamespaces = true; + LockPersonality = true; + PrivateUsers = true; + }; + +in { + + options.services.firefly-iii = { + + enable = mkEnableOption "Firefly III: A free and open source personal finance manager"; + + user = mkOption { + type = str; + default = defaultUser; + description = "User account under which firefly-iii runs."; + }; + + group = mkOption { + type = str; + default = if cfg.enableNginx then "nginx" else defaultGroup; + defaultText = "If `services.firefly-iii.enableNginx` is true then `nginx` else ${defaultGroup}"; + description = '' + Group under which firefly-iii runs. It is best to set this to the group + of whatever webserver is being used as the frontend. + ''; + }; + + dataDir = mkOption { + type = path; + default = "/var/lib/firefly-iii"; + description = '' + The place where firefly-iii stores its state. + ''; + }; + + package = mkOption { + type = package; + default = pkgs.firefly-iii; + defaultText = literalExpression "pkgs.firefly-iii"; + description = '' + The firefly-iii package served by php-fpm and the webserver of choice. + This option can be used to point the webserver to the correct root. It + may also be used to set the package to a different version, say a + development version. + ''; + apply = firefly-iii : firefly-iii.override (prev: { + dataDir = cfg.dataDir; + }); + }; + + enableNginx = mkOption { + type = bool; + default = false; + description = '' + Whether to enable nginx or not. If enabled, an nginx virtual host will + be created for access to firefly-iii. If not enabled, then you may use + `''${config.services.firefly-iii.package}` as your document root in + whichever webserver you wish to setup. + ''; + }; + + virtualHost = mkOption { + type = str; + description = '' + The hostname at which you wish firefly-iii to be served. If you have + enabled nginx using `services.firefly-iii.enableNginx` then this will + be used. + ''; + }; + + poolConfig = mkOption { + type = attrsOf (oneOf [ str int bool ]); + default = { + "pm" = "dynamic"; + "pm.max_children" = 32; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 2; + "pm.max_spare_servers" = 4; + "pm.max_requests" = 500; + }; + description = '' + Options for the Firefly III PHP pool. See the documentation on php-fpm.conf + for details on configuration directives. + ''; + }; + + settings = mkOption { + description = '' + Options for firefly-iii configuration. Refer to + for + details on supported values. All