diff --git a/third_party/nixpkgs/.github/CODEOWNERS b/third_party/nixpkgs/.github/CODEOWNERS
index c4662b044a..008d51b29a 100644
--- a/third_party/nixpkgs/.github/CODEOWNERS
+++ b/third_party/nixpkgs/.github/CODEOWNERS
@@ -10,9 +10,6 @@
# IMPORTANT NOTE: in order to actually get pinged, commit access is required.
# This also holds true for GitHub teams. Since almost none of our teams have write
# permissions, you need to list all members of the team with commit access individually.
-# We still add the team to the list next to its members, this helps keeping things
-# in sync. (Put non team members before the team to distinguish them.)
-# See https://github.com/NixOS/nixpkgs/issues/124085 for more details
# This file
/.github/CODEOWNERS @edolstra
@@ -39,10 +36,10 @@
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
-/pkgs/stdenv/generic @Ericson2314 @matthewbauer @cab404
+/pkgs/stdenv/generic @Ericson2314 @matthewbauer
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
-/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
-/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
+/pkgs/build-support/cc-wrapper @Ericson2314
+/pkgs/build-support/bintools-wrapper @Ericson2314
/pkgs/build-support/setup-hooks @Ericson2314
/pkgs/build-support/setup-hooks/auto-patchelf.sh @aszlig
@@ -77,6 +74,12 @@
# NixOS integration test driver
/nixos/lib/test-driver @tfc
+# Systemd
+/nixos/modules/system/boot/systemd.nix @NixOS/systemd
+/nixos/modules/system/boot/systemd @NixOS/systemd
+/nixos/lib/systemd-*.nix @NixOS/systemd
+/pkgs/os-specific/linux/systemd @NixOS/systemd
+
# Updaters
## update.nix
/maintainers/scripts/update.nix @jtojnar
@@ -91,8 +94,7 @@
/pkgs/development/python-modules @FRidh @jonringer
/doc/languages-frameworks/python.section.md @FRidh
/pkgs/development/tools/poetry2nix @adisbladis
-/pkgs/development/interpreters/python/hooks @FRidh @jonringer @DavHau
-/pkgs/development/interpreters/python/conda @DavHau
+/pkgs/development/interpreters/python/hooks @FRidh @jonringer
# Haskell
/doc/languages-frameworks/haskell.section.md @cdepillabout @sternenseemann @maralorn @expipiplus1
@@ -109,8 +111,8 @@
/pkgs/development/perl-modules @stigtsp @zakame
# R
-/pkgs/applications/science/math/R @jbedo @bcdarwin
-/pkgs/development/r-modules @jbedo @bcdarwin
+/pkgs/applications/science/math/R @jbedo
+/pkgs/development/r-modules @jbedo
# Ruby
/pkgs/development/interpreters/ruby @marsam
@@ -121,10 +123,6 @@
/pkgs/build-support/rust @zowoq
/doc/languages-frameworks/rust.section.md @zowoq
-# Darwin-related
-/pkgs/stdenv/darwin @NixOS/darwin-maintainers
-/pkgs/os-specific/darwin @NixOS/darwin-maintainers
-
# C compilers
/pkgs/development/compilers/gcc @matthewbauer
/pkgs/development/compilers/llvm @matthewbauer
@@ -133,15 +131,6 @@
/pkgs/top-level/unix-tools.nix @matthewbauer
/pkgs/development/tools/xcbuild @matthewbauer
-# Beam-related (Erlang, Elixir, LFE, etc)
-/pkgs/development/beam-modules @gleber
-/pkgs/development/interpreters/erlang @gleber
-/pkgs/development/interpreters/lfe @gleber
-/pkgs/development/interpreters/elixir @gleber
-/pkgs/development/tools/build-managers/rebar @gleber
-/pkgs/development/tools/build-managers/rebar3 @gleber
-/pkgs/development/tools/erlang @gleber
-
# Audio
/nixos/modules/services/audio/botamusique.nix @mweinelt
/nixos/modules/services/audio/snapserver.nix @mweinelt
@@ -209,7 +198,7 @@
/pkgs/development/idris-modules @Infinisil
# Bazel
-/pkgs/development/tools/build-managers/bazel @mboes @Profpatsch
+/pkgs/development/tools/build-managers/bazel @Profpatsch
# NixOS modules for e-mail and dns services
/nixos/modules/services/mail/mailman.nix @peti
@@ -237,22 +226,22 @@
/nixos/tests/prometheus-exporters.nix @WilliButz
# PHP interpreter, packages, extensions, tests and documentation
-/doc/languages-frameworks/php.section.md @NixOS/php @aanderse @etu @globin @ma27 @talyz
-/nixos/tests/php @NixOS/php @aanderse @etu @globin @ma27 @talyz
-/pkgs/build-support/build-pecl.nix @NixOS/php @aanderse @etu @globin @ma27 @talyz
-/pkgs/development/interpreters/php @jtojnar @NixOS/php @aanderse @etu @globin @ma27 @talyz
-/pkgs/development/php-packages @NixOS/php @aanderse @etu @globin @ma27 @talyz
-/pkgs/top-level/php-packages.nix @jtojnar @NixOS/php @aanderse @etu @globin @ma27 @talyz
+/doc/languages-frameworks/php.section.md @aanderse @etu @globin @ma27 @talyz
+/nixos/tests/php @aanderse @etu @globin @ma27 @talyz
+/pkgs/build-support/build-pecl.nix @aanderse @etu @globin @ma27 @talyz
+/pkgs/development/interpreters/php @jtojnar @aanderse @etu @globin @ma27 @talyz
+/pkgs/development/php-packages @aanderse @etu @globin @ma27 @talyz
+/pkgs/top-level/php-packages.nix @jtojnar @aanderse @etu @globin @ma27 @talyz
# Podman, CRI-O modules and related
-/nixos/modules/virtualisation/containers.nix @NixOS/podman @zowoq @adisbladis
-/nixos/modules/virtualisation/cri-o.nix @NixOS/podman @zowoq @adisbladis
-/nixos/modules/virtualisation/podman @NixOS/podman @zowoq @adisbladis
-/nixos/tests/cri-o.nix @NixOS/podman @zowoq @adisbladis
-/nixos/tests/podman @NixOS/podman @zowoq @adisbladis
+/nixos/modules/virtualisation/containers.nix @zowoq @adisbladis
+/nixos/modules/virtualisation/cri-o.nix @zowoq @adisbladis
+/nixos/modules/virtualisation/podman @zowoq @adisbladis
+/nixos/tests/cri-o.nix @zowoq @adisbladis
+/nixos/tests/podman @zowoq @adisbladis
# Docker tools
-/pkgs/build-support/docker @roberth @utdemir
+/pkgs/build-support/docker @roberth
/nixos/tests/docker-tools-overlay.nix @roberth
/nixos/tests/docker-tools.nix @roberth
/doc/builders/images/dockertools.xml @roberth
@@ -267,8 +256,8 @@
/pkgs/development/go-packages @kalbasit @Mic92 @zowoq
# GNOME
-/pkgs/desktops/gnome @NixOS/GNOME @jtojnar @hedning
-/pkgs/desktops/gnome/extensions @piegamesde @NixOS/GNOME @jtojnar @hedning
+/pkgs/desktops/gnome @jtojnar @hedning
+/pkgs/desktops/gnome/extensions @piegamesde @jtojnar @hedning
# Cinnamon
/pkgs/desktops/cinnamon @mkg20001
@@ -289,10 +278,10 @@
# Matrix
/pkgs/servers/heisenbridge @piegamesde
-/pkgs/servers/matrix-conduit @piegamesde @pstn
+/pkgs/servers/matrix-conduit @piegamesde
/pkgs/servers/matrix-synapse/matrix-appservice-irc @piegamesde
/nixos/modules/services/misc/heisenbridge.nix @piegamesde
/nixos/modules/services/misc/matrix-appservice-irc.nix @piegamesde
-/nixos/modules/services/misc/matrix-conduit.nix @piegamesde @pstn
+/nixos/modules/services/misc/matrix-conduit.nix @piegamesde
/nixos/tests/matrix-appservice-irc.nix @piegamesde
-/nixos/tests/matrix-conduit.nix @piegamesde @pstn
+/nixos/tests/matrix-conduit.nix @piegamesde
diff --git a/third_party/nixpkgs/.github/labeler.yml b/third_party/nixpkgs/.github/labeler.yml
index c5c10d3e4b..a48f60e776 100644
--- a/third_party/nixpkgs/.github/labeler.yml
+++ b/third_party/nixpkgs/.github/labeler.yml
@@ -5,10 +5,6 @@
- pkgs/development/libraries/agda/**/*
- pkgs/top-level/agda-packages.nix
-"6.topic: bsd":
- - pkgs/os-specific/bsd/**/*
- - pkgs/stdenv/freebsd/**/*
-
"6.topic: cinnamon":
- pkgs/desktops/cinnamon/**/*
diff --git a/third_party/nixpkgs/.github/workflows/backport.yml b/third_party/nixpkgs/.github/workflows/backport.yml
index bcb164a04e..4ee5adfaac 100644
--- a/third_party/nixpkgs/.github/workflows/backport.yml
+++ b/third_party/nixpkgs/.github/workflows/backport.yml
@@ -2,6 +2,12 @@ name: Backport
on:
pull_request_target:
types: [closed, labeled]
+
+# WARNING:
+# When extending this action, be aware that $GITHUB_TOKEN allows write access to
+# the GitHub repository. This means that it should not evaluate user input in a
+# way that allows code injection.
+
jobs:
backport:
name: Backport Pull Request
diff --git a/third_party/nixpkgs/.github/workflows/basic-eval.yml b/third_party/nixpkgs/.github/workflows/basic-eval.yml
index c48b04d8c1..51429ae40b 100644
--- a/third_party/nixpkgs/.github/workflows/basic-eval.yml
+++ b/third_party/nixpkgs/.github/workflows/basic-eval.yml
@@ -16,5 +16,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v16
+ - uses: cachix/cachix-action@v10
+ with:
+ # This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
+ 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" ]'
diff --git a/third_party/nixpkgs/.github/workflows/direct-push.yml b/third_party/nixpkgs/.github/workflows/direct-push.yml
index 459475c3c6..082a4806e6 100644
--- a/third_party/nixpkgs/.github/workflows/direct-push.yml
+++ b/third_party/nixpkgs/.github/workflows/direct-push.yml
@@ -22,7 +22,7 @@ jobs:
if: steps.ismerge.outputs.ismerge != 'true'
- name: Warn if the commit was a direct push
if: steps.ismerge.outputs.ismerge != 'true'
- uses: peter-evans/commit-comment@v1
+ uses: peter-evans/commit-comment@v2
with:
body: |
@${{ github.actor }}, you pushed a commit directly to master/release branch
diff --git a/third_party/nixpkgs/.github/workflows/labels.yml b/third_party/nixpkgs/.github/workflows/labels.yml
index c464f8bf58..5f949ddc56 100644
--- a/third_party/nixpkgs/.github/workflows/labels.yml
+++ b/third_party/nixpkgs/.github/workflows/labels.yml
@@ -4,6 +4,11 @@ on:
pull_request_target:
types: [edited, opened, synchronize, reopened]
+# WARNING:
+# When extending this action, be aware that $GITHUB_TOKEN allows some write
+# access to the GitHub API. This means that it should not evaluate user input in
+# a way that allows code injection.
+
permissions:
contents: read
pull-requests: write
diff --git a/third_party/nixpkgs/.github/workflows/manual-nixos.yml b/third_party/nixpkgs/.github/workflows/manual-nixos.yml
index 787f553529..61a8a21765 100644
--- a/third_party/nixpkgs/.github/workflows/manual-nixos.yml
+++ b/third_party/nixpkgs/.github/workflows/manual-nixos.yml
@@ -24,7 +24,7 @@ jobs:
extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v10
with:
- # This cache is for the nixos/nixpkgs manual builds and should not be trusted or used elsewhere.
+ # This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
name: nixpkgs-ci
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- name: Building NixOS manual
diff --git a/third_party/nixpkgs/.github/workflows/manual-nixpkgs.yml b/third_party/nixpkgs/.github/workflows/manual-nixpkgs.yml
index 7d9273ef13..70d9aab698 100644
--- a/third_party/nixpkgs/.github/workflows/manual-nixpkgs.yml
+++ b/third_party/nixpkgs/.github/workflows/manual-nixpkgs.yml
@@ -24,7 +24,7 @@ jobs:
extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v10
with:
- # This cache is for the nixos/nixpkgs manual builds and should not be trusted or used elsewhere.
+ # This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
name: nixpkgs-ci
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- name: Building Nixpkgs manual
diff --git a/third_party/nixpkgs/.github/workflows/pending-set.yml b/third_party/nixpkgs/.github/workflows/pending-set.yml
index 944d1deefb..b15e4847e6 100644
--- a/third_party/nixpkgs/.github/workflows/pending-set.yml
+++ b/third_party/nixpkgs/.github/workflows/pending-set.yml
@@ -3,6 +3,11 @@ name: "set pending status"
on:
pull_request_target:
+# WARNING:
+# When extending this action, be aware that $GITHUB_TOKEN allows write access to
+# the GitHub repository. This means that it should not evaluate user input in a
+# way that allows code injection.
+
jobs:
action:
runs-on: ubuntu-latest
diff --git a/third_party/nixpkgs/.github/workflows/periodic-merge-24h.yml b/third_party/nixpkgs/.github/workflows/periodic-merge-24h.yml
index 5ad0db1db5..027c63aad9 100644
--- a/third_party/nixpkgs/.github/workflows/periodic-merge-24h.yml
+++ b/third_party/nixpkgs/.github/workflows/periodic-merge-24h.yml
@@ -49,7 +49,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Comment on failure
- uses: peter-evans/create-or-update-comment@v1
+ uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }}
with:
issue-number: 105153
diff --git a/third_party/nixpkgs/.github/workflows/periodic-merge-6h.yml b/third_party/nixpkgs/.github/workflows/periodic-merge-6h.yml
index a8af04b78b..5588d216ea 100644
--- a/third_party/nixpkgs/.github/workflows/periodic-merge-6h.yml
+++ b/third_party/nixpkgs/.github/workflows/periodic-merge-6h.yml
@@ -43,7 +43,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Comment on failure
- uses: peter-evans/create-or-update-comment@v1
+ uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }}
with:
issue-number: 105153
diff --git a/third_party/nixpkgs/.github/workflows/update-terraform-providers.yml b/third_party/nixpkgs/.github/workflows/update-terraform-providers.yml
index 09d208a621..0c775cb6e4 100644
--- a/third_party/nixpkgs/.github/workflows/update-terraform-providers.yml
+++ b/third_party/nixpkgs/.github/workflows/update-terraform-providers.yml
@@ -39,7 +39,7 @@ jobs:
title: ${{ steps.setup.outputs.title }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: comment on failure
- uses: peter-evans/create-or-update-comment@v1
+ uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }}
with:
issue-number: 153416
diff --git a/third_party/nixpkgs/doc/builders/fetchers.chapter.md b/third_party/nixpkgs/doc/builders/fetchers.chapter.md
index 28388ba685..d9f22b0628 100644
--- a/third_party/nixpkgs/doc/builders/fetchers.chapter.md
+++ b/third_party/nixpkgs/doc/builders/fetchers.chapter.md
@@ -72,6 +72,10 @@ Used with Mercurial. Expects `url`, `rev`, and `sha256`.
A number of fetcher functions wrap part of `fetchurl` and `fetchzip`. They are mainly convenience functions intended for commonly used destinations of source code in Nixpkgs. These wrapper fetchers are listed below.
+## `fetchFromGitea` {#fetchfromgitea}
+
+`fetchFromGitea` expects five arguments. `domain` is the gitea server name. `owner` is a string corresponding to the Gitea user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every Gitea HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. Finally, `sha256` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available but `sha256` is currently preferred.
+
## `fetchFromGitHub` {#fetchfromgithub}
`fetchFromGitHub` expects four arguments. `owner` is a string corresponding to the GitHub user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every GitHub HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. Finally, `sha256` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available but `sha256` is currently preferred.
diff --git a/third_party/nixpkgs/doc/builders/special/fhs-environments.section.md b/third_party/nixpkgs/doc/builders/special/fhs-environments.section.md
index 43dc99b7c1..cacad261e2 100644
--- a/third_party/nixpkgs/doc/builders/special/fhs-environments.section.md
+++ b/third_party/nixpkgs/doc/builders/special/fhs-environments.section.md
@@ -45,3 +45,5 @@ One can create a simple environment using a `shell.nix` like that:
```
Running `nix-shell` would then drop you into a shell with these libraries and binaries available. You can use this to run closed-source applications which expect FHS structure without hassles: simply change `runScript` to the application path, e.g. `./bin/start.sh` -- relative paths are supported.
+
+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`.
diff --git a/third_party/nixpkgs/doc/contributing/coding-conventions.chapter.md b/third_party/nixpkgs/doc/contributing/coding-conventions.chapter.md
index cfe8582e51..dac6d828ac 100644
--- a/third_party/nixpkgs/doc/contributing/coding-conventions.chapter.md
+++ b/third_party/nixpkgs/doc/contributing/coding-conventions.chapter.md
@@ -540,10 +540,11 @@ If you do need to do create this sort of patch file, one way to do so is with gi
If a patch is available online but does not cleanly apply, it can be modified in some fixed ways by using additional optional arguments for `fetchpatch`:
+- `relative`: Similar to using `git-diff`'s `--relative` flag, only keep changes inside the specified directory, making paths relative to it.
- `stripLen`: Remove the first `stripLen` components of pathnames in the patch.
- `extraPrefix`: Prefix pathnames by this string.
-- `excludes`: Exclude files matching this pattern.
-- `includes`: Include only files matching this pattern.
+- `excludes`: Exclude files matching these patterns (applies after the above arguments).
+- `includes`: Include only files matching these patterns (applies after the above arguments).
- `revert`: Revert the patch.
Note that because the checksum is computed after applying these effects, using or modifying these arguments will have no effect unless the `sha256` argument is changed as well.
diff --git a/third_party/nixpkgs/doc/contributing/reviewing-contributions.chapter.md b/third_party/nixpkgs/doc/contributing/reviewing-contributions.chapter.md
index 0a90781d0c..3417854730 100644
--- a/third_party/nixpkgs/doc/contributing/reviewing-contributions.chapter.md
+++ b/third_party/nixpkgs/doc/contributing/reviewing-contributions.chapter.md
@@ -122,10 +122,10 @@ Reviewing process:
- [CODEOWNERS](https://help.github.com/articles/about-codeowners/) will make GitHub notify users based on the submitted changes, but it can happen that it misses some of the package maintainers.
- Ensure that the module tests, if any, are succeeding.
- Ensure that the introduced options are correct.
- - Type should be appropriate (string related types differs in their merging capabilities, `optionSet` and `string` types are deprecated).
+ - Type should be appropriate (string related types differs in their merging capabilities, `loaOf` and `string` types are deprecated).
- Description, default and example should be provided.
- Ensure that option changes are backward compatible.
- - `mkRenamedOptionModule` and `mkAliasOptionModule` functions provide way to make option changes backward compatible.
+ - `mkRenamedOptionModuleWith` provides a way to make option changes backward compatible.
- Ensure that removed options are declared with `mkRemovedOptionModule`
- Ensure that changes that are not backward compatible are mentioned in release notes.
- Ensure that documentations affected by the change is updated.
@@ -157,7 +157,7 @@ Reviewing process:
- Ensure that the module tests, if any, are succeeding.
- Ensure that the introduced options are correct.
- - Type should be appropriate (string related types differs in their merging capabilities, `optionSet` and `string` types are deprecated).
+ - Type should be appropriate (string related types differs in their merging capabilities, `loaOf` and `string` types are deprecated).
- Description, default and example should be provided.
- Ensure that module `meta` field is present
- Maintainers should be declared in `meta.maintainers`.
diff --git a/third_party/nixpkgs/doc/functions/library/attrsets.xml b/third_party/nixpkgs/doc/functions/library/attrsets.xml
index a30f4edf4c..052bfa1f6a 100644
--- a/third_party/nixpkgs/doc/functions/library/attrsets.xml
+++ b/third_party/nixpkgs/doc/functions/library/attrsets.xml
@@ -1474,7 +1474,7 @@ lib.attrsets.zipAttrsWith
lib.attrsets.zipAttrs
- zipAttrsWith :: [ AttrSet ] -> AttrSet
+ zipAttrs :: [ AttrSet ] -> AttrSet
diff --git a/third_party/nixpkgs/doc/languages-frameworks/javascript.section.md b/third_party/nixpkgs/doc/languages-frameworks/javascript.section.md
index bf5742d685..8173178049 100644
--- a/third_party/nixpkgs/doc/languages-frameworks/javascript.section.md
+++ b/third_party/nixpkgs/doc/languages-frameworks/javascript.section.md
@@ -85,7 +85,7 @@ you will still need to commit the modified version of the lock files, but at lea
each tool has an abstraction to just build the node_modules (dependencies) directory. you can always use the stdenv.mkDerivation with the node_modules to build the package (symlink the node_modules directory and then use the package build command). the node_modules abstraction can be also used to build some web framework frontends. For an example of this see how [plausible](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/web-apps/plausible/default.nix) is built. mkYarnModules to make the derivation containing node_modules. Then when building the frontend you can just symlink the node_modules directory
-## javascript packages inside nixpkgs {#javascript-packages-nixpkgs}
+## Javascript packages inside nixpkgs {#javascript-packages-nixpkgs}
The `pkgs/development/node-packages` folder contains a generated collection of
[NPM packages](https://npmjs.com/) that can be installed with the Nix package
@@ -121,12 +121,14 @@ requires `node-gyp-build`, so [we override](https://github.com/NixOS/nixpkgs/blo
};
```
+### Adding and Updating Javascript packages in nixpkgs
+
To add a package from NPM to nixpkgs:
1. Modify `pkgs/development/node-packages/node-packages.json` to add, update
or remove package entries to have it included in `nodePackages` and
`nodePackages_latest`.
-2. Run the script: `cd pkgs/development/node-packages && ./generate.sh`.
+2. Run the script: `./pkgs/development/node-packages/generate.sh`.
3. Build your new package to test your changes:
`cd /path/to/nixpkgs && nix-build -A nodePackages.`.
To build against the latest stable Current Node.js version (e.g. 14.x):
@@ -137,6 +139,26 @@ For more information about the generation process, consult the
[README.md](https://github.com/svanderburg/node2nix) file of the `node2nix`
tool.
+To update NPM packages in nixpkgs, run the same `generate.sh` script:
+
+```sh
+./pkgs/development/node-packages/generate.sh
+```
+
+#### Git protocol error
+
+Some packages may have Git dependencies from GitHub specified with `git://`.
+GitHub has
+[disabled unecrypted Git connections](https://github.blog/2021-09-01-improving-git-protocol-security-github/#no-more-unauthenticated-git),
+so you may see the following error when running the generate script:
+`The unauthenticated git protocol on port 9418 is no longer supported`.
+
+Use the following Git configuration to resolve the issue:
+
+```sh
+git config --global url."https://github.com/".insteadOf git://github.com/
+```
+
## Tool specific instructions {#javascript-tool-specific}
### node2nix {#javascript-node2nix}
diff --git a/third_party/nixpkgs/doc/languages-frameworks/ocaml.section.md b/third_party/nixpkgs/doc/languages-frameworks/ocaml.section.md
index 47035551d4..c6e40eaa20 100644
--- a/third_party/nixpkgs/doc/languages-frameworks/ocaml.section.md
+++ b/third_party/nixpkgs/doc/languages-frameworks/ocaml.section.md
@@ -38,8 +38,12 @@ Here is a simple package example.
- It uses the `fetchFromGitHub` fetcher to get its source.
-- `useDune2 = true` ensures that the latest version of Dune is used for the
- build (this may become the default value in a future release).
+- `duneVersion = "2"` ensures that Dune version 2 is used for the
+ build (this is the default; valid values are `"1"`, `"2"`, and `"3"`);
+ note that there is also a legacy `useDune2` boolean attribute:
+ set to `false` it corresponds to `duneVersion = "1"`; set to `true` it
+ corresponds to `duneVersion = "2"`. If both arguments (`duneVersion` and
+ `useDune2`) are given, the second one (`useDune2`) is silently ignored.
- It sets the optional `doCheck` attribute such that tests will be run with
`dune runtest -p angstrom` after the build (`dune build -p angstrom`) is
@@ -67,7 +71,7 @@ Here is a simple package example.
buildDunePackage rec {
pname = "angstrom";
version = "0.15.0";
- useDune2 = true;
+ duneVersion = "2";
minimalOCamlVersion = "4.04";
diff --git a/third_party/nixpkgs/doc/languages-frameworks/texlive.section.md b/third_party/nixpkgs/doc/languages-frameworks/texlive.section.md
index 6b505cefcc..060f5c647c 100644
--- a/third_party/nixpkgs/doc/languages-frameworks/texlive.section.md
+++ b/third_party/nixpkgs/doc/languages-frameworks/texlive.section.md
@@ -6,7 +6,7 @@ Since release 15.09 there is a new TeX Live packaging that lives entirely under
- For basic usage just pull `texlive.combined.scheme-basic` for an environment with basic LaTeX support.
-- It typically won't work to use separately installed packages together. Instead, you can build a custom set of packages like this:
+- It typically won't work to use separately installed packages together. Instead, you can build a custom set of packages like this. Most CTAN packages should be available:
```nix
texlive.combine {
diff --git a/third_party/nixpkgs/doc/languages-frameworks/vim.section.md b/third_party/nixpkgs/doc/languages-frameworks/vim.section.md
index a615d585b1..563fdf45a8 100644
--- a/third_party/nixpkgs/doc/languages-frameworks/vim.section.md
+++ b/third_party/nixpkgs/doc/languages-frameworks/vim.section.md
@@ -18,7 +18,7 @@ Adding custom .vimrc lines can be done using the following code:
```nix
vim_configurable.customize {
- # `name` specifies the name of the executable and package
+ # `name` optionally specifies the name of the executable and package
name = "vim-with-plugins";
vimrcConfig.customRC = ''
@@ -28,6 +28,9 @@ vim_configurable.customize {
```
This configuration is used when Vim is invoked with the command specified as name, in this case `vim-with-plugins`.
+You can also omit `name` to customize Vim itself. See the
+[definition of `vimUtils.makeCustomizable`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/vim-utils.nix#L408)
+for all supported options.
For Neovim the `configure` argument can be overridden to achieve the same:
@@ -286,7 +289,7 @@ Sample output1:
"reload" = buildVimPluginFrom2Nix { # created by nix#NixDerivation
name = "reload";
src = fetchgit {
- url = "git://github.com/xolox/vim-reload";
+ url = "https://github.com/xolox/vim-reload";
rev = "0a601a668727f5b675cb1ddc19f6861f3f7ab9e1";
sha256 = "0vb832l9yxj919f5hfg6qj6bn9ni57gnjd3bj7zpq7d4iv2s4wdh";
};
diff --git a/third_party/nixpkgs/doc/using/overlays.chapter.md b/third_party/nixpkgs/doc/using/overlays.chapter.md
index df152bc14e..a51aa9ee8f 100644
--- a/third_party/nixpkgs/doc/using/overlays.chapter.md
+++ b/third_party/nixpkgs/doc/using/overlays.chapter.md
@@ -77,7 +77,7 @@ In Nixpkgs, we have multiple implementations of the BLAS/LAPACK numerical linear
The Nixpkgs attribute is `openblas` for ILP64 (integer width = 64 bits) and `openblasCompat` for LP64 (integer width = 32 bits). `openblasCompat` is the default.
-- [LAPACK reference](http://www.netlib.org/lapack/) (also provides BLAS)
+- [LAPACK reference](http://www.netlib.org/lapack/) (also provides BLAS and CBLAS)
The Nixpkgs attribute is `lapack-reference`.
@@ -117,7 +117,23 @@ $ LD_LIBRARY_PATH=$(nix-build -A mkl)/lib${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH n
Intel MKL requires an `openmp` implementation when running with multiple processors. By default, `mkl` will use Intel's `iomp` implementation if no other is specified, but this is a runtime-only dependency and binary compatible with the LLVM implementation. To use that one instead, Intel recommends users set it with `LD_PRELOAD`. Note that `mkl` is only available on `x86_64-linux` and `x86_64-darwin`. Moreover, Hydra is not building and distributing pre-compiled binaries using it.
-For BLAS/LAPACK switching to work correctly, all packages must depend on `blas` or `lapack`. This ensures that only one BLAS/LAPACK library is used at one time. There are two versions of BLAS/LAPACK currently in the wild, `LP64` (integer size = 32 bits) and `ILP64` (integer size = 64 bits). Some software needs special flags or patches to work with `ILP64`. You can check if `ILP64` is used in Nixpkgs with `blas.isILP64` and `lapack.isILP64`. Some software does NOT work with `ILP64`, and derivations need to specify an assertion to prevent this. You can prevent `ILP64` from being used with the following:
+To override `blas` and `lapack` with its reference implementations (i.e. for development purposes), one can use the following overlay:
+
+```nix
+self: super:
+
+{
+ blas = super.blas.override {
+ blasProvider = self.lapack-reference;
+ };
+
+ lapack = super.lapack.override {
+ lapackProvider = self.lapack-reference;
+ };
+}
+```
+
+For BLAS/LAPACK switching to work correctly, all packages must depend on `blas` or `lapack`. This ensures that only one BLAS/LAPACK library is used at one time. There are two versions of BLAS/LAPACK currently in the wild, `LP64` (integer size = 32 bits) and `ILP64` (integer size = 64 bits). The attributes `blas` and `lapack` are `LP64` by default. Their `ILP64` version are provided through the attributes `blas-ilp64` and `lapack-ilp64`. Some software needs special flags or patches to work with `ILP64`. You can check if `ILP64` is used in Nixpkgs with `blas.isILP64` and `lapack.isILP64`. Some software does NOT work with `ILP64`, and derivations need to specify an assertion to prevent this. You can prevent `ILP64` from being used with the following:
```nix
{ stdenv, blas, lapack, ... }:
diff --git a/third_party/nixpkgs/lib/attrsets.nix b/third_party/nixpkgs/lib/attrsets.nix
index c0d3ede73d..516fdd8d33 100644
--- a/third_party/nixpkgs/lib/attrsets.nix
+++ b/third_party/nixpkgs/lib/attrsets.nix
@@ -4,8 +4,8 @@
let
inherit (builtins) head tail length;
inherit (lib.trivial) id;
- inherit (lib.strings) concatStringsSep sanitizeDerivationName;
- inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all;
+ inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName;
+ inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all partition groupBy take foldl;
in
rec {
@@ -78,6 +78,103 @@ rec {
in attrByPath attrPath (abort errorMsg);
+ /* Update or set specific paths of an attribute set.
+
+ Takes a list of updates to apply and an attribute set to apply them to,
+ and returns the attribute set with the updates applied. Updates are
+ represented as { path = ...; update = ...; } values, where `path` is a
+ list of strings representing the attribute path that should be updated,
+ and `update` is a function that takes the old value at that attribute path
+ as an argument and returns the new
+ value it should be.
+
+ Properties:
+ - Updates to deeper attribute paths are applied before updates to more
+ shallow attribute paths
+ - Multiple updates to the same attribute path are applied in the order
+ they appear in the update list
+ - If any but the last `path` element leads into a value that is not an
+ attribute set, an error is thrown
+ - If there is an update for an attribute path that doesn't exist,
+ accessing the argument in the update function causes an error, but
+ intermediate attribute sets are implicitly created as needed
+
+ Example:
+ updateManyAttrsByPath [
+ {
+ path = [ "a" "b" ];
+ update = old: { d = old.c; };
+ }
+ {
+ path = [ "a" "b" "c" ];
+ update = old: old + 1;
+ }
+ {
+ path = [ "x" "y" ];
+ update = old: "xy";
+ }
+ ] { a.b.c = 0; }
+ => { a = { b = { d = 1; }; }; x = { y = "xy"; }; }
+ */
+ updateManyAttrsByPath = let
+ # When recursing into attributes, instead of updating the `path` of each
+ # update using `tail`, which needs to allocate an entirely new list,
+ # we just pass a prefix length to use and make sure to only look at the
+ # path without the prefix length, so that we can reuse the original list
+ # entries.
+ go = prefixLength: hasValue: value: updates:
+ let
+ # Splits updates into ones on this level (split.right)
+ # And ones on levels further down (split.wrong)
+ split = partition (el: length el.path == prefixLength) updates;
+
+ # Groups updates on further down levels into the attributes they modify
+ nested = groupBy (el: elemAt el.path prefixLength) split.wrong;
+
+ # Applies only nested modification to the input value
+ withNestedMods =
+ # Return the value directly if we don't have any nested modifications
+ if split.wrong == [] then
+ if hasValue then value
+ else
+ # Throw an error if there is no value. This `head` call here is
+ # safe, but only in this branch since `go` could only be called
+ # with `hasValue == false` for nested updates, in which case
+ # it's also always called with at least one update
+ let updatePath = (head split.right).path; in
+ throw
+ ( "updateManyAttrsByPath: Path '${showAttrPath updatePath}' does "
+ + "not exist in the given value, but the first update to this "
+ + "path tries to access the existing value.")
+ else
+ # If there are nested modifications, try to apply them to the value
+ if ! hasValue then
+ # But if we don't have a value, just use an empty attribute set
+ # as the value, but simplify the code a bit
+ mapAttrs (name: go (prefixLength + 1) false null) nested
+ else if isAttrs value then
+ # If we do have a value and it's an attribute set, override it
+ # with the nested modifications
+ value //
+ mapAttrs (name: go (prefixLength + 1) (value ? ${name}) value.${name}) nested
+ else
+ # However if it's not an attribute set, we can't apply the nested
+ # modifications, throw an error
+ let updatePath = (head split.wrong).path; in
+ throw
+ ( "updateManyAttrsByPath: Path '${showAttrPath updatePath}' needs to "
+ + "be updated, but path '${showAttrPath (take prefixLength updatePath)}' "
+ + "of the given value is not an attribute set, so we can't "
+ + "update an attribute inside of it.");
+
+ # We get the final result by applying all the updates on this level
+ # after having applied all the nested updates
+ # We use foldl instead of foldl' so that in case of multiple updates,
+ # intermediate values aren't evaluated if not needed
+ in foldl (acc: el: el.update acc) withNestedMods split.right;
+
+ in updates: value: go 0 true value updates;
+
/* Return the specified attributes from a set.
Example:
@@ -477,6 +574,20 @@ rec {
overrideExisting = old: new:
mapAttrs (name: value: new.${name} or value) old;
+ /* Turns a list of strings into a human-readable description of those
+ strings represented as an attribute path. The result of this function is
+ not intended to be machine-readable.
+
+ Example:
+ showAttrPath [ "foo" "10" "bar" ]
+ => "foo.\"10\".bar"
+ showAttrPath []
+ => ""
+ */
+ showAttrPath = path:
+ if path == [] then ""
+ else concatMapStringsSep "." escapeNixIdentifier path;
+
/* Get a package output.
If no output is found, fallback to `.out` and then to the default.
diff --git a/third_party/nixpkgs/lib/default.nix b/third_party/nixpkgs/lib/default.nix
index 3fead03a46..1f06283790 100644
--- a/third_party/nixpkgs/lib/default.nix
+++ b/third_party/nixpkgs/lib/default.nix
@@ -66,9 +66,10 @@ let
stringLength sub substring tail trace;
inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor
bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max
- importJSON importTOML warn warnIf throwIfNot checkListOfEnum
- info showWarnings nixpkgsVersion version
- mod compare splitByAndCompare functionArgs setFunctionArgs isFunction
+ importJSON importTOML warn warnIf warnIfNot throwIf throwIfNot checkListOfEnum
+ info showWarnings nixpkgsVersion version isInOldestRelease
+ mod compare splitByAndCompare
+ functionArgs setFunctionArgs isFunction toFunction
toHexString toBaseDigits;
inherit (self.fixedPoints) fix fix' converge extends composeExtensions
composeManyExtensions makeExtensible makeExtensibleWithCustomName;
@@ -78,9 +79,10 @@ let
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
genAttrs isDerivation toDerivation optionalAttrs
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
- recursiveUpdate matchAttrs overrideExisting getOutput getBin
+ recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin
getLib getDev getMan chooseDevOutputs zipWithNames zip
- recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets;
+ recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets
+ updateManyAttrsByPath;
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists
@@ -112,14 +114,15 @@ let
commitIdFromGitRepo cleanSourceWith pathHasContext
canCleanSource pathIsRegularFile pathIsGitRepo;
inherit (self.modules) evalModules setDefaultModuleLocation
- unifyModuleSyntax applyIfFunction mergeModules
+ unifyModuleSyntax applyModuleArgsIfFunction mergeModules
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
pushDownProperties dischargeProperties filterOverrides
sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride
mkOptionDefault mkDefault mkImageMediaOverride mkForce mkVMOverride
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
- mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
+ mkRenamedOptionModule mkRenamedOptionModuleWith
+ mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule mkDerivedConfig doRename;
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
diff --git a/third_party/nixpkgs/lib/licenses.nix b/third_party/nixpkgs/lib/licenses.nix
index b9310ef6c5..2928d11d8b 100644
--- a/third_party/nixpkgs/lib/licenses.nix
+++ b/third_party/nixpkgs/lib/licenses.nix
@@ -389,6 +389,11 @@ in mkLicense lset) ({
free = false;
};
+ generaluser = {
+ fullName = "GeneralUser GS License v2.0";
+ url = "http://www.schristiancollins.com/generaluser.php"; # license included in sources
+ };
+
gpl1Only = {
spdxId = "GPL-1.0-only";
fullName = "GNU General Public License v1.0 only";
@@ -607,6 +612,11 @@ in mkLicense lset) ({
fullName = "Enlightenment License (e16)";
};
+ mit0 = {
+ spdxId = "MIT-0";
+ fullName = "MIT No Attribution";
+ };
+
mpl10 = {
spdxId = "MPL-1.0";
fullName = "Mozilla Public License 1.0";
diff --git a/third_party/nixpkgs/lib/lists.nix b/third_party/nixpkgs/lib/lists.nix
index 1dbff7668d..a030280c8d 100644
--- a/third_party/nixpkgs/lib/lists.nix
+++ b/third_party/nixpkgs/lib/lists.nix
@@ -4,6 +4,7 @@
let
inherit (lib.strings) toInt;
inherit (lib.trivial) compare min;
+ inherit (lib.attrsets) mapAttrs;
in
rec {
@@ -340,15 +341,15 @@ rec {
groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = 12; false = 3; }
*/
- groupBy' = op: nul: pred: lst:
- foldl' (r: e:
- let
- key = pred e;
- in
- r // { ${key} = op (r.${key} or nul) e; }
- ) {} lst;
+ groupBy' = op: nul: pred: lst: mapAttrs (name: foldl op nul) (groupBy pred lst);
- groupBy = groupBy' (sum: e: sum ++ [e]) [];
+ groupBy = builtins.groupBy or (
+ pred: foldl' (r: e:
+ let
+ key = pred e;
+ in
+ r // { ${key} = (r.${key} or []) ++ [e]; }
+ ) {});
/* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest. How both lists are merged is defined
diff --git a/third_party/nixpkgs/lib/modules.nix b/third_party/nixpkgs/lib/modules.nix
index 79d54e4a53..894104cc57 100644
--- a/third_party/nixpkgs/lib/modules.nix
+++ b/third_party/nixpkgs/lib/modules.nix
@@ -9,7 +9,7 @@ let
catAttrs
concatLists
concatMap
- count
+ concatStringsSep
elem
filter
findFirst
@@ -47,6 +47,20 @@ let
showOption
unknownModule
;
+
+ showDeclPrefix = loc: decl: prefix:
+ " - option(s) with prefix `${showOption (loc ++ [prefix])}' in module `${decl._file}'";
+ showRawDecls = loc: decls:
+ concatStringsSep "\n"
+ (sort (a: b: a < b)
+ (concatMap
+ (decl: map
+ (showDeclPrefix loc decl)
+ (attrNames decl.options)
+ )
+ decls
+ ));
+
in
rec {
@@ -268,11 +282,11 @@ rec {
# Like unifyModuleSyntax, but also imports paths and calls functions if necessary
loadModule = args: fallbackFile: fallbackKey: m:
if isFunction m || isAttrs m then
- unifyModuleSyntax fallbackFile fallbackKey (applyIfFunction fallbackKey m args)
+ unifyModuleSyntax fallbackFile fallbackKey (applyModuleArgsIfFunction fallbackKey m args)
else if isList m then
let defs = [{ file = fallbackFile; value = m; }]; in
throw "Module imports can't be nested lists. Perhaps you meant to remove one level of lists? Definitions: ${showDefs defs}"
- else unifyModuleSyntax (toString m) (toString m) (applyIfFunction (toString m) (import m) args);
+ else unifyModuleSyntax (toString m) (toString m) (applyModuleArgsIfFunction (toString m) (import m) args);
/*
Collects all modules recursively into the form
@@ -369,7 +383,7 @@ rec {
config = addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"]));
};
- applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
+ applyModuleArgsIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
let
# Module arguments are resolved in a strict manner when attribute set
# deconstruction is used. As the arguments are now defined with the
@@ -474,26 +488,61 @@ rec {
[{ inherit (module) file; inherit value; }]
) configs;
+ # Convert an option tree decl to a submodule option decl
+ optionTreeToOption = decl:
+ if isOption decl.options
+ then decl
+ else decl // {
+ options = mkOption {
+ type = types.submoduleWith {
+ modules = [ { options = decl.options; } ];
+ # `null` is not intended for use by modules. It is an internal
+ # value that means "whatever the user has declared elsewhere".
+ # This might become obsolete with https://github.com/NixOS/nixpkgs/issues/162398
+ shorthandOnlyDefinesConfig = null;
+ };
+ };
+ };
+
resultsByName = mapAttrs (name: decls:
# We're descending into attribute ‘name’.
let
loc = prefix ++ [name];
defns = defnsByName.${name} or [];
defns' = defnsByName'.${name} or [];
- nrOptions = count (m: isOption m.options) decls;
+ optionDecls = filter (m: isOption m.options) decls;
in
- if nrOptions == length decls then
+ if length optionDecls == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls);
in {
matchedOptions = evalOptionValue loc opt defns';
unmatchedDefns = [];
}
- else if nrOptions != 0 then
- let
- firstOption = findFirst (m: isOption m.options) "" decls;
- firstNonOption = findFirst (m: !isOption m.options) "" decls;
- in
- throw "The option `${showOption loc}' in `${firstOption._file}' is a prefix of options in `${firstNonOption._file}'."
+ else if optionDecls != [] then
+ if all (x: x.options.type.name == "submodule") optionDecls
+ # Raw options can only be merged into submodules. Merging into
+ # attrsets might be nice, but ambiguous. Suppose we have
+ # attrset as a `attrsOf submodule`. User declares option
+ # attrset.foo.bar, this could mean:
+ # a. option `bar` is only available in `attrset.foo`
+ # b. option `foo.bar` is available in all `attrset.*`
+ # c. reject and require "" as a reminder that it behaves like (b).
+ # d. magically combine (a) and (c).
+ # All of the above are merely syntax sugar though.
+ then
+ let opt = fixupOptionType loc (mergeOptionDecls loc (map optionTreeToOption decls));
+ in {
+ matchedOptions = evalOptionValue loc opt defns';
+ unmatchedDefns = [];
+ }
+ else
+ let
+ firstNonOption = findFirst (m: !isOption m.options) "" decls;
+ nonOptions = filter (m: !isOption m.options) decls;
+ in
+ throw "The option `${showOption loc}' in module `${(lib.head optionDecls)._file}' would be a parent of the following options, but its type `${(lib.head optionDecls).options.type.description or ""}' does not support nested options.\n${
+ showRawDecls loc nonOptions
+ }"
else
mergeModules' loc decls defns) declsByName;
@@ -560,17 +609,9 @@ rec {
throw "The option `${showOption loc}' in `${opt._file}' is already declared in ${showFiles res.declarations}."
else
let
- /* Add the modules of the current option to the list of modules
- already collected. The options attribute except either a list of
- submodules or a submodule. For each submodule, we add the file of the
- current option declaration as the file use for the submodule. If the
- submodule defines any filename, then we ignore the enclosing option file. */
- options' = toList opt.options.options;
-
getSubModules = opt.options.type.getSubModules or null;
submodules =
if getSubModules != null then map (setDefaultModuleLocation opt._file) getSubModules ++ res.options
- else if opt.options ? options then map (coerceOption opt._file) options' ++ res.options
else res.options;
in opt.options // res //
{ declarations = res.declarations ++ [opt._file];
@@ -753,26 +794,13 @@ rec {
compare = a: b: (a.priority or 1000) < (b.priority or 1000);
in sort compare defs';
- /* Hack for backward compatibility: convert options of type
- optionSet to options of type submodule. FIXME: remove
- eventually. */
+ # This calls substSubModules, whose entire purpose is only to ensure that
+ # option declarations in submodules have accurate position information.
+ # TODO: Merge this into mergeOptionDecls
fixupOptionType = loc: opt:
- let
- options = opt.options or
- (throw "Option `${showOption loc}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}.");
- f = tp:
- let optionSetIn = type: (tp.name == type) && (tp.functor.wrapped.name == "optionSet");
- in
- if tp.name == "option set" || tp.name == "submodule" then
- throw "The option ${showOption loc} uses submodules without a wrapping type, in ${showFiles opt.declarations}."
- else if optionSetIn "attrsOf" then types.attrsOf (types.submodule options)
- else if optionSetIn "listOf" then types.listOf (types.submodule options)
- else if optionSetIn "nullOr" then types.nullOr (types.submodule options)
- else tp;
- in
- if opt.type.getSubModules or null == null
- then opt // { type = f (opt.type or types.unspecified); }
- else opt // { type = opt.type.substSubModules opt.options; options = []; };
+ if opt.type.getSubModules or null == null
+ then opt // { type = opt.type or types.unspecified; }
+ else opt // { type = opt.type.substSubModules opt.options; options = []; };
/* Properties. */
@@ -904,6 +932,26 @@ rec {
use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
};
+ mkRenamedOptionModuleWith = {
+ /* Old option path as list of strings. */
+ from,
+ /* New option path as list of strings. */
+ to,
+
+ /*
+ Release number of the first release that contains the rename, ignoring backports.
+ Set it to the upcoming release, matching the nixpkgs/.version file.
+ */
+ sinceRelease,
+
+ }: doRename {
+ inherit from to;
+ visible = false;
+ warn = lib.isInOldestRelease sinceRelease;
+ use = lib.warnIf (lib.isInOldestRelease sinceRelease)
+ "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
+ };
+
/* Return a module that causes a warning to be shown if any of the "from"
option is defined; the defined values can be used in the "mergeFn" to set
the "to" value.
diff --git a/third_party/nixpkgs/lib/options.nix b/third_party/nixpkgs/lib/options.nix
index 627aac24d2..8d0801775c 100644
--- a/third_party/nixpkgs/lib/options.nix
+++ b/third_party/nixpkgs/lib/options.nix
@@ -79,8 +79,6 @@ rec {
visible ? null,
# Whether the option can be set only once
readOnly ? null,
- # Deprecated, used by types.optionSet.
- options ? null
} @ attrs:
attrs // { _type = "option"; };
@@ -231,7 +229,7 @@ rec {
then true
else opt.visible or true;
readOnly = opt.readOnly or false;
- type = opt.type.description or null;
+ type = opt.type.description or "unspecified";
}
// optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; }
// optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }
diff --git a/third_party/nixpkgs/lib/systems/default.nix b/third_party/nixpkgs/lib/systems/default.nix
index 529eeb6514..7ddd5b8a58 100644
--- a/third_party/nixpkgs/lib/systems/default.nix
+++ b/third_party/nixpkgs/lib/systems/default.nix
@@ -105,7 +105,8 @@ rec {
else if final.isAarch64 then "arm64"
else if final.isx86_32 then "i386"
else if final.isx86_64 then "x86_64"
- else if final.isMips then "mips"
+ else if final.isMips32 then "mips"
+ else if final.isMips64 then "mips" # linux kernel does not distinguish mips32/mips64
else if final.isPower then "powerpc"
else if final.isRiscV then "riscv"
else if final.isS390 then "s390"
diff --git a/third_party/nixpkgs/lib/systems/doubles.nix b/third_party/nixpkgs/lib/systems/doubles.nix
index 00e57339a3..27cdaf6a72 100644
--- a/third_party/nixpkgs/lib/systems/doubles.nix
+++ b/third_party/nixpkgs/lib/systems/doubles.nix
@@ -26,7 +26,7 @@ let
# Linux
"aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux"
- "armv7l-linux" "i686-linux" "m68k-linux" "mipsel-linux"
+ "armv7l-linux" "i686-linux" "m68k-linux" "mipsel-linux" "mips64el-linux"
"powerpc64-linux" "powerpc64le-linux" "riscv32-linux"
"riscv64-linux" "s390-linux" "s390x-linux" "x86_64-linux"
@@ -87,7 +87,11 @@ in {
darwin = filterDoubles predicates.isDarwin;
freebsd = filterDoubles predicates.isFreeBSD;
# Should be better, but MinGW is unclear.
- gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; }) ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; });
+ gnu = filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnu; })
+ ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabi; })
+ ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnueabihf; })
+ ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnuabin32; })
+ ++ filterDoubles (matchAttrs { kernel = parse.kernels.linux; abi = parse.abis.gnuabi64; });
illumos = filterDoubles predicates.isSunOS;
linux = filterDoubles predicates.isLinux;
netbsd = filterDoubles predicates.isNetBSD;
diff --git a/third_party/nixpkgs/lib/systems/examples.nix b/third_party/nixpkgs/lib/systems/examples.nix
index 9c0c91617e..997a7a8c27 100644
--- a/third_party/nixpkgs/lib/systems/examples.nix
+++ b/third_party/nixpkgs/lib/systems/examples.nix
@@ -93,6 +93,26 @@ rec {
config = "mipsel-unknown-linux-gnu";
} // platforms.fuloong2f_n32;
+ # MIPS ABI table transcribed from here: https://wiki.debian.org/Multiarch/Tuples
+
+ # can execute on 32bit chip
+ mips-linux-gnu = { config = "mips-linux-gnu"; } // platforms.gcc_mips32r2_o32;
+ mipsel-linux-gnu = { config = "mipsel-linux-gnu"; } // platforms.gcc_mips32r2_o32;
+ mipsisa32r6-linux-gnu = { config = "mipsisa32r6-linux-gnu"; } // platforms.gcc_mips32r6_o32;
+ mipsisa32r6el-linux-gnu = { config = "mipsisa32r6el-linux-gnu"; } // platforms.gcc_mips32r6_o32;
+
+ # require 64bit chip (for more registers, 64-bit floating point, 64-bit "long long") but use 32bit pointers
+ mips64-linux-gnuabin32 = { config = "mips64-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
+ mips64el-linux-gnuabin32 = { config = "mips64el-linux-gnuabin32"; } // platforms.gcc_mips64r2_n32;
+ mipsisa64r6-linux-gnuabin32 = { config = "mipsisa64r6-linux-gnuabin32"; } // platforms.gcc_mips64r6_n32;
+ mipsisa64r6el-linux-gnuabin32 = { config = "mipsisa64r6el-linux-gnuabin32"; } // platforms.gcc_mips64r6_n32;
+
+ # 64bit pointers
+ mips64-linux-gnuabi64 = { config = "mips64-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
+ mips64el-linux-gnuabi64 = { config = "mips64el-linux-gnuabi64"; } // platforms.gcc_mips64r2_64;
+ mipsisa64r6-linux-gnuabi64 = { config = "mipsisa64r6-linux-gnuabi64"; } // platforms.gcc_mips64r6_64;
+ mipsisa64r6el-linux-gnuabi64 = { config = "mipsisa64r6el-linux-gnuabi64"; } // platforms.gcc_mips64r6_64;
+
muslpi = raspberryPi // {
config = "armv6l-unknown-linux-musleabihf";
};
diff --git a/third_party/nixpkgs/lib/systems/inspect.nix b/third_party/nixpkgs/lib/systems/inspect.nix
index 718954e083..89cac575c6 100644
--- a/third_party/nixpkgs/lib/systems/inspect.nix
+++ b/third_party/nixpkgs/lib/systems/inspect.nix
@@ -17,6 +17,10 @@ rec {
isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
isMips = { cpu = { family = "mips"; }; };
+ isMips32 = { cpu = { family = "mips"; bits = 32; }; };
+ isMips64 = { cpu = { family = "mips"; bits = 64; }; };
+ isMips64n32 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "n32"; }; };
+ isMips64n64 = { cpu = { family = "mips"; bits = 64; }; abi = { abi = "64"; }; };
isMmix = { cpu = { family = "mmix"; }; };
isRiscV = { cpu = { family = "riscv"; }; };
isSparc = { cpu = { family = "sparc"; }; };
@@ -57,7 +61,7 @@ rec {
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
isGnu = with abis; map (a: { abi = a; }) [ gnuabi64 gnu gnueabi gnueabihf ];
- isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf ];
+ isMusl = with abis; map (a: { abi = a; }) [ musl musleabi musleabihf muslabin32 muslabi64 ];
isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
isEfi = map (family: { cpu.family = family; })
diff --git a/third_party/nixpkgs/lib/systems/parse.nix b/third_party/nixpkgs/lib/systems/parse.nix
index f0e87c30e4..3ceddbb599 100644
--- a/third_party/nixpkgs/lib/systems/parse.nix
+++ b/third_party/nixpkgs/lib/systems/parse.nix
@@ -359,6 +359,13 @@ rec {
];
};
gnuabi64 = { abi = "64"; };
+ muslabi64 = { abi = "64"; };
+
+ # NOTE: abi=n32 requires a 64-bit MIPS chip! That is not a typo.
+ # It is basically the 64-bit abi with 32-bit pointers. Details:
+ # https://www.linux-mips.org/pub/linux/mips/doc/ABI/MIPS-N32-ABI-Handbook.pdf
+ gnuabin32 = { abi = "n32"; };
+ muslabin32 = { abi = "n32"; };
musleabi = { float = "soft"; };
musleabihf = { float = "hard"; };
diff --git a/third_party/nixpkgs/lib/systems/platforms.nix b/third_party/nixpkgs/lib/systems/platforms.nix
index b2a8dbedef..04d5541624 100644
--- a/third_party/nixpkgs/lib/systems/platforms.nix
+++ b/third_party/nixpkgs/lib/systems/platforms.nix
@@ -1,3 +1,10 @@
+# Note: lib/systems/default.nix takes care of producing valid,
+# fully-formed "platform" values (e.g. hostPlatform, buildPlatform,
+# targetPlatform, etc) containing at least the minimal set of attrs
+# required (see types.parsedPlatform in lib/systems/parse.nix). This
+# file takes an already-valid platform and further elaborates it with
+# optional fields such as linux-kernel, gcc, etc.
+
{ lib }:
rec {
pc = {
@@ -482,6 +489,43 @@ rec {
};
};
+ # can execute on 32bit chip
+ gcc_mips32r2_o32 = { gcc = { arch = "mips32r2"; abi = "o32"; }; };
+ gcc_mips32r6_o32 = { gcc = { arch = "mips32r6"; abi = "o32"; }; };
+ gcc_mips64r2_n32 = { gcc = { arch = "mips64r2"; abi = "n32"; }; };
+ gcc_mips64r6_n32 = { gcc = { arch = "mips64r6"; abi = "n32"; }; };
+ gcc_mips64r2_64 = { gcc = { arch = "mips64r2"; abi = "64"; }; };
+ gcc_mips64r6_64 = { gcc = { arch = "mips64r6"; abi = "64"; }; };
+
+ # based on:
+ # https://www.mail-archive.com/qemu-discuss@nongnu.org/msg05179.html
+ # https://gmplib.org/~tege/qemu.html#mips64-debian
+ mips64el-qemu-linux-gnuabi64 = (import ./examples).mips64el-linux-gnuabi64 // {
+ linux-kernel = {
+ name = "mips64el";
+ baseConfig = "64r2el_defconfig";
+ target = "vmlinuz";
+ autoModules = false;
+ DTB = true;
+ # for qemu 9p passthrough filesystem
+ extraConfig = ''
+ MIPS_MALTA y
+ PAGE_SIZE_4KB y
+ CPU_LITTLE_ENDIAN y
+ CPU_MIPS64_R2 y
+ 64BIT y
+ CPU_MIPS64_R2 y
+
+ NET_9P y
+ NET_9P_VIRTIO y
+ 9P_FS y
+ 9P_FS_POSIX_ACL y
+ PCI y
+ VIRTIO_PCI y
+ '';
+ };
+ };
+
##
## Other
##
@@ -499,6 +543,9 @@ rec {
};
};
+ # This function takes a minimally-valid "platform" and returns an
+ # attrset containing zero or more additional attrs which should be
+ # included in the platform in order to further elaborate it.
select = platform:
# x86
/**/ if platform.isx86 then pc
diff --git a/third_party/nixpkgs/lib/tests/misc.nix b/third_party/nixpkgs/lib/tests/misc.nix
index 5fa95828df..2711190313 100644
--- a/third_party/nixpkgs/lib/tests/misc.nix
+++ b/third_party/nixpkgs/lib/tests/misc.nix
@@ -761,4 +761,156 @@ runTests {
{ a = 3; b = 30; c = 300; }
];
};
+
+ # The example from the showAttrPath documentation
+ testShowAttrPathExample = {
+ expr = showAttrPath [ "foo" "10" "bar" ];
+ expected = "foo.\"10\".bar";
+ };
+
+ testShowAttrPathEmpty = {
+ expr = showAttrPath [];
+ expected = "";
+ };
+
+ testShowAttrPathVarious = {
+ expr = showAttrPath [
+ "."
+ "foo"
+ "2"
+ "a2-b"
+ "_bc'de"
+ ];
+ expected = ''".".foo."2".a2-b._bc'de'';
+ };
+
+ testGroupBy = {
+ expr = groupBy (n: toString (mod n 5)) (range 0 16);
+ expected = {
+ "0" = [ 0 5 10 15 ];
+ "1" = [ 1 6 11 16 ];
+ "2" = [ 2 7 12 ];
+ "3" = [ 3 8 13 ];
+ "4" = [ 4 9 14 ];
+ };
+ };
+
+ testGroupBy' = {
+ expr = groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ];
+ expected = { false = 3; true = 12; };
+ };
+
+ # The example from the updateManyAttrsByPath documentation
+ testUpdateManyAttrsByPathExample = {
+ expr = updateManyAttrsByPath [
+ {
+ path = [ "a" "b" ];
+ update = old: { d = old.c; };
+ }
+ {
+ path = [ "a" "b" "c" ];
+ update = old: old + 1;
+ }
+ {
+ path = [ "x" "y" ];
+ update = old: "xy";
+ }
+ ] { a.b.c = 0; };
+ expected = { a = { b = { d = 1; }; }; x = { y = "xy"; }; };
+ };
+
+ # If there are no updates, the value is passed through
+ testUpdateManyAttrsByPathNone = {
+ expr = updateManyAttrsByPath [] "something";
+ expected = "something";
+ };
+
+ # A single update to the root path is just like applying the function directly
+ testUpdateManyAttrsByPathSingleIncrement = {
+ expr = updateManyAttrsByPath [
+ {
+ path = [ ];
+ update = old: old + 1;
+ }
+ ] 0;
+ expected = 1;
+ };
+
+ # Multiple updates can be applied are done in order
+ testUpdateManyAttrsByPathMultipleIncrements = {
+ expr = updateManyAttrsByPath [
+ {
+ path = [ ];
+ update = old: old + "a";
+ }
+ {
+ path = [ ];
+ update = old: old + "b";
+ }
+ {
+ path = [ ];
+ update = old: old + "c";
+ }
+ ] "";
+ expected = "abc";
+ };
+
+ # If an update doesn't use the value, all previous updates are not evaluated
+ testUpdateManyAttrsByPathLazy = {
+ expr = updateManyAttrsByPath [
+ {
+ path = [ ];
+ update = old: old + throw "nope";
+ }
+ {
+ path = [ ];
+ update = old: "untainted";
+ }
+ ] (throw "start");
+ expected = "untainted";
+ };
+
+ # Deeply nested attributes can be updated without affecting others
+ testUpdateManyAttrsByPathDeep = {
+ expr = updateManyAttrsByPath [
+ {
+ path = [ "a" "b" "c" ];
+ update = old: old + 1;
+ }
+ ] {
+ a.b.c = 0;
+
+ a.b.z = 0;
+ a.y.z = 0;
+ x.y.z = 0;
+ };
+ expected = {
+ a.b.c = 1;
+
+ a.b.z = 0;
+ a.y.z = 0;
+ x.y.z = 0;
+ };
+ };
+
+ # Nested attributes are updated first
+ testUpdateManyAttrsByPathNestedBeforehand = {
+ expr = updateManyAttrsByPath [
+ {
+ path = [ "a" ];
+ update = old: old // { x = old.b; };
+ }
+ {
+ path = [ "a" "b" ];
+ update = old: old + 1;
+ }
+ ] {
+ a.b = 0;
+ };
+ expected = {
+ a.b = 1;
+ a.x = 1;
+ };
+ };
+
}
diff --git a/third_party/nixpkgs/lib/tests/modules.sh b/third_party/nixpkgs/lib/tests/modules.sh
index e4bb7ad219..8050c6539f 100755
--- a/third_party/nixpkgs/lib/tests/modules.sh
+++ b/third_party/nixpkgs/lib/tests/modules.sh
@@ -62,6 +62,13 @@ checkConfigError() {
checkConfigOutput '^false$' config.enable ./declare-enable.nix
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*: true' config.enable ./define-enable.nix
+checkConfigOutput '^1$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix
+checkConfigOutput '^2$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix
+checkConfigOutput '^42$' config.bare-submodule.nested ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix ./declare-bare-submodule-deep-option.nix ./define-bare-submodule-values.nix
+checkConfigOutput '^420$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-nested-option.nix ./declare-bare-submodule-deep-option.nix ./define-bare-submodule-values.nix
+checkConfigOutput '^2$' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix ./define-shorthandOnlyDefinesConfig-true.nix
+checkConfigError 'The option .bare-submodule.deep. in .*/declare-bare-submodule-deep-option.nix. is already declared in .*/declare-bare-submodule-deep-option-duplicate.nix' config.bare-submodule.deep ./declare-bare-submodule.nix ./declare-bare-submodule-deep-option.nix ./declare-bare-submodule-deep-option-duplicate.nix
+
# Check integer types.
# unsigned
checkConfigOutput '^42$' config.value ./declare-int-unsigned-value.nix ./define-value-int-positive.nix
@@ -304,6 +311,12 @@ checkConfigOutput "10" config.processedToplevel ./raw.nix
checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix
checkConfigOutput "bar" config.priorities ./raw.nix
+## Option collision
+checkConfigError \
+ 'The option .set. in module .*/declare-set.nix. would be a parent of the following options, but its type .attribute set of signed integers. does not support nested options.\n\s*- option[(]s[)] with prefix .set.enable. in module .*/declare-enable-nested.nix.' \
+ config.set \
+ ./declare-set.nix ./declare-enable-nested.nix
+
# Test that types.optionType merges types correctly
checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix
checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix
@@ -311,6 +324,9 @@ checkConfigOutput '^"hello"$' config.theOption.str ./optionTypeMerging.nix
# Test that types.optionType correctly annotates option locations
checkConfigError 'The option .theOption.nested. in .other.nix. is already declared in .optionTypeFile.nix.' config.theOption.nested ./optionTypeFile.nix
+# Test that types.optionType leaves types untouched as long as they don't need to be merged
+checkConfigOutput 'ok' config.freeformItems.foo.bar ./adhoc-freeformType-survives-type-merge.nix
+
cat < string -> a -> a
*/
- warnIf = cond: msg: if cond then warn msg else id;
+ warnIf = cond: msg: if cond then warn msg else x: x;
+
+ /*
+ Like warnIf, but negated (warn if the first argument is `false`).
+
+ Type: bool -> string -> a -> a
+ */
+ warnIfNot = cond: msg: if cond then x: x else warn msg;
/*
Like the `assert b; e` expression, but with a custom error message and
@@ -347,6 +378,13 @@ rec {
*/
throwIfNot = cond: msg: if cond then x: x else throw msg;
+ /*
+ Like throwIfNot, but negated (throw if the first argument is `true`).
+
+ Type: bool -> string -> a -> a
+ */
+ throwIf = cond: msg: if cond then throw msg else x: x;
+
/* Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.
Example:
@@ -403,6 +441,25 @@ rec {
isFunction = f: builtins.isFunction f ||
(f ? __functor && isFunction (f.__functor f));
+ /*
+ Turns any non-callable values into constant functions.
+ Returns callable values as is.
+
+ Example:
+
+ nix-repl> lib.toFunction 1 2
+ 1
+
+ nix-repl> lib.toFunction (x: x + 1) 2
+ 3
+ */
+ toFunction =
+ # Any value
+ v:
+ if isFunction v
+ then v
+ else k: v;
+
/* Convert the given positive integer to a string of its hexadecimal
representation. For example:
diff --git a/third_party/nixpkgs/lib/types.nix b/third_party/nixpkgs/lib/types.nix
index 3fcac9c31b..5c4b963106 100644
--- a/third_party/nixpkgs/lib/types.nix
+++ b/third_party/nixpkgs/lib/types.nix
@@ -368,13 +368,21 @@ rec {
emptyValue = { value = {}; };
};
- # derivation is a reserved keyword.
+ # A package is a top-level store path (/nix/store/hash-name). This includes:
+ # - derivations
+ # - more generally, attribute sets with an `outPath` or `__toString` attribute
+ # pointing to a store path, e.g. flake inputs
+ # - strings with context, e.g. "${pkgs.foo}" or (toString pkgs.foo)
+ # - hardcoded store path literals (/nix/store/hash-foo) or strings without context
+ # ("/nix/store/hash-foo"). These get a context added to them using builtins.storePath.
package = mkOptionType {
name = "package";
check = x: isDerivation x || isStorePath x;
merge = loc: defs:
let res = mergeOneOption loc defs;
- in if isDerivation res then res else toDerivation res;
+ in if builtins.isPath res || (builtins.isString res && ! builtins.hasContext res)
+ then toDerivation res
+ else res;
};
shellPackage = package // {
@@ -535,7 +543,9 @@ rec {
description = "optionType";
check = value: value._type or null == "option-type";
merge = loc: defs:
- let
+ if length defs == 1
+ then (head defs).value
+ else let
# Prepares the type definitions for mergeOptionDecls, which
# annotates submodules types with file locations
optionModules = map ({ value, file }:
@@ -562,14 +572,18 @@ rec {
let
inherit (lib.modules) evalModules;
- coerce = unify: value: if isFunction value
- then setFunctionArgs (args: unify (value args)) (functionArgs value)
- else unify (if shorthandOnlyDefinesConfig then { config = value; } else value);
+ shorthandToModule = if shorthandOnlyDefinesConfig == false
+ then value: value
+ else value: { config = value; };
allModules = defs: imap1 (n: { value, file }:
- if isAttrs value || isFunction value then
- # Annotate the value with the location of its definition for better error messages
- coerce (lib.modules.unifyModuleSyntax file "${toString file}-${toString n}") value
+ if isFunction value
+ then setFunctionArgs
+ (args: lib.modules.unifyModuleSyntax file "${toString file}-${toString n}" (value args))
+ (functionArgs value)
+ else if isAttrs value
+ then
+ lib.modules.unifyModuleSyntax file "${toString file}-${toString n}" (shorthandToModule value)
else value
) defs;
@@ -637,7 +651,11 @@ rec {
then lhs.specialArgs // rhs.specialArgs
else throw "A submoduleWith option is declared multiple times with the same specialArgs \"${toString (attrNames intersecting)}\"";
shorthandOnlyDefinesConfig =
- if lhs.shorthandOnlyDefinesConfig == rhs.shorthandOnlyDefinesConfig
+ if lhs.shorthandOnlyDefinesConfig == null
+ then rhs.shorthandOnlyDefinesConfig
+ else if rhs.shorthandOnlyDefinesConfig == null
+ then lhs.shorthandOnlyDefinesConfig
+ else if lhs.shorthandOnlyDefinesConfig == rhs.shorthandOnlyDefinesConfig
then lhs.shorthandOnlyDefinesConfig
else throw "A submoduleWith option is declared multiple times with conflicting shorthandOnlyDefinesConfig values";
};
@@ -731,14 +749,6 @@ rec {
nestedTypes.finalType = finalType;
};
- # Obsolete alternative to configOf. It takes its option
- # declarations from the ‘options’ attribute of containing option
- # declaration.
- optionSet = mkOptionType {
- name = "optionSet";
- description = "option set";
- deprecationMessage = "Use `types.submodule' instead";
- };
# Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
diff --git a/third_party/nixpkgs/maintainers/maintainer-list.nix b/third_party/nixpkgs/maintainers/maintainer-list.nix
index 57d5157bd6..25c5bd078e 100644
--- a/third_party/nixpkgs/maintainers/maintainer-list.nix
+++ b/third_party/nixpkgs/maintainers/maintainer-list.nix
@@ -929,6 +929,12 @@
githubId = 1296771;
name = "Anders Riutta";
};
+ arjan-s = {
+ email = "github@anymore.nl";
+ github = "arjan-s";
+ githubId = 10400299;
+ name = "Arjan Schrijver";
+ };
arkivm = {
email = "vikram186@gmail.com";
github = "arkivm";
@@ -1295,6 +1301,12 @@
githubId = 127523;
name = "Herman Fries";
};
+ BarinovMaxim = {
+ name = "Barinov Maxim";
+ email = "barinov274@gmail.com";
+ github = "barinov274";
+ githubId = 54442153;
+ };
barrucadu = {
email = "mike@barrucadu.co.uk";
github = "barrucadu";
@@ -1688,6 +1700,12 @@
githubId = 355401;
name = "Brian Hicks";
};
+ brianmcgee = {
+ name = "Brian McGee";
+ email = "brian@41north.dev";
+ github = "brianmcgee";
+ githubId = 1173648;
+ };
Br1ght0ne = {
email = "brightone@protonmail.com";
github = "Br1ght0ne";
@@ -1895,6 +1913,12 @@
githubId = 82591;
name = "Carl Sverre";
};
+ carpinchomug = {
+ email = "aki.suda@protonmail.com";
+ github = "carpinchomug";
+ githubId = 101536256;
+ name = "Akiyoshi Suda";
+ };
cartr = {
email = "carter.sande@duodecima.technology";
github = "cartr";
@@ -2181,6 +2205,12 @@
githubId = 42220376;
name = "Charlotte Van Petegem";
};
+ cigrainger = {
+ name = "Christopher Grainger";
+ email = "chris@amplified.ai";
+ github = "cigrainger";
+ githubId = 3984794;
+ };
ciil = {
email = "simon@lackerbauer.com";
github = "ciil";
@@ -2800,6 +2830,12 @@
githubId = 49904992;
name = "Dawid Sowa";
};
+ dbeckwith = {
+ email = "djbsnx@gmail.com";
+ github = "dbeckwith";
+ githubId = 1279939;
+ name = "Daniel Beckwith";
+ };
dbirks = {
email = "david@birks.dev";
github = "dbirks";
@@ -4217,7 +4253,12 @@
githubId = 119691;
name = "Michael Gough";
};
-
+ freax13 = {
+ email = "erbse.13@gmx.de";
+ github = "freax13";
+ githubId = 14952658;
+ name = "Tom Dohrmann";
+ };
fredeb = {
email = "im@fredeb.dev";
github = "fredeeb";
@@ -5625,6 +5666,12 @@
github = "jduan";
githubId = 452450;
};
+ jdupak = {
+ name = "Jakub Dupak";
+ email = "dev@jakubdupak.com";
+ github = "jdupak";
+ githubId = 22683640;
+ };
jecaro = {
email = "jeancharles.quillet@gmail.com";
github = "jecaro";
@@ -5845,6 +5892,12 @@
githubId = 587870;
name = "Jonathan Mettes";
};
+ jmgilman = {
+ email = "joshuagilman@gmail.com";
+ github = "jmgilman";
+ githubId = 2308444;
+ name = "Joshua Gilman";
+ };
jo1gi = {
email = "joakimholm@protonmail.com";
github = "jo1gi";
@@ -7217,6 +7270,29 @@
githubId = 1267527;
name = "Daniel Firth";
};
+ lockejan = {
+ email = "git@smittie.de";
+ matrix = "@jan:smittie.de";
+ github = "lockejan";
+ githubId = 25434434;
+ name = "Jan Schmitt";
+ keys = [{
+ longkeyid = "dsa2048/0xA2BC3C6F14351991";
+ fingerprint = "1763 9903 2D7C 5B82 5D5A 0EAD A2BC 3C6F 1435 1991";
+ }];
+ };
+ lodi = {
+ email = "anthony.lodi@gmail.com";
+ github = "lodi";
+ githubId = 918448;
+ name = "Anthony Lodi";
+ };
+ loicreynier = {
+ email = "loic@loireynier.fr";
+ github = "loicreynier";
+ githubId = 88983487;
+ name = "Loïc Reynier";
+ };
lopsided98 = {
email = "benwolsieffer@gmail.com";
github = "lopsided98";
@@ -8686,6 +8762,12 @@
fingerprint = "4BFF 0614 03A2 47F0 AA0B 4BC4 916D 8B67 2418 92AE";
}];
};
+ nbr = {
+ email = "nbr@users.noreply.github.com";
+ github = "nbr";
+ githubId = 3819225;
+ name = "Nick Braga";
+ };
nbren12 = {
email = "nbren12@gmail.com";
github = "nbren12";
@@ -9260,6 +9342,12 @@
githubId = 23431373;
name = "Christoph Neidahl";
};
+ opeik = {
+ email = "sandro@stikic.com";
+ github = "opeik";
+ githubId = 11566773;
+ name = "Sandro Stikić";
+ };
orbekk = {
email = "kjetil.orbekk@gmail.com";
github = "orbekk";
@@ -9862,6 +9950,12 @@
fingerprint = "48AD DE10 F27B AFB4 7BB0 CCAF 2D25 95A0 0D08 ACE0";
}];
};
+ ppenguin = {
+ name = "Jeroen Versteeg";
+ email = "hieronymusv@gmail.com";
+ github = "ppenguin";
+ githubId = 17690377;
+ };
ppom = {
name = "Paco Pompeani";
email = "paco@ecomail.io";
@@ -10218,6 +10312,16 @@
githubId = 16487165;
name = "Rafael Basso";
};
+ rbreslow = {
+ name = "Rocky Breslow";
+ email = "1774125+rbreslow@users.noreply.github.com";
+ github = "rbreslow";
+ githubId = 1774125;
+ keys = [{
+ longkeyid = "ed25519/0xA0D32ACCA38B88ED";
+ fingerprint = "B5B7 BCA0 EE6F F31E 263A 69E3 A0D3 2ACC A38B 88ED";
+ }];
+ };
rbrewer = {
email = "rwb123@gmail.com";
github = "rbrewer123";
@@ -10344,6 +10448,18 @@
githubId = 22803888;
name = "Lu Hongxu";
};
+ rgnns = {
+ email = "jglievano@gmail.com";
+ github = "rgnns";
+ githubId = 811827;
+ name = "Gabriel Lievano";
+ };
+ rgrinberg = {
+ name = "Rudi Grinberg";
+ email = "me@rgrinberg.com";
+ github = "rgrinberg";
+ githubId = 139003;
+ };
rgrunbla = {
email = "remy@grunblatt.org";
github = "rgrunbla";
@@ -11195,6 +11311,12 @@
githubId = 293035;
name = "Shawn Dellysse";
};
+ shawn8901 = {
+ email = "shawn8901@googlemail.com";
+ github = "shawn8901";
+ githubId = 12239057;
+ name = "Shawn8901";
+ };
shazow = {
email = "andrey.petrov@shazow.net";
github = "shazow";
@@ -11670,6 +11792,17 @@
githubId = 55607356;
name = "Stephan Heßelmann";
};
+ steinybot = {
+ name = "Jason Pickens";
+ email = "jasonpickensnz@gmail.com";
+ matrix = "@steinybot:matrix.org";
+ github = "steinybot";
+ githubId = 4659562;
+ keys = [{
+ longkeyid = "ed25519/0x21DE1CAE59762A0F";
+ fingerprint = "2709 1DEC CC42 4635 4299 569C 21DE 1CAE 5976 2A0F";
+ }];
+ };
stelcodes = {
email = "stel@stel.codes";
github = "stelcodes";
@@ -12677,6 +12810,12 @@
githubId = 1983821;
name = "Eric Wolf";
};
+ uakci = {
+ name = "uakci";
+ email = "uakci@uakci.pl";
+ github = "uakci";
+ githubId = 6961268;
+ };
udono = {
email = "udono@virtual-things.biz";
github = "udono";
@@ -13104,6 +13243,12 @@
githubId = 34962284;
name = "wchresta";
};
+ wdavidw = {
+ name = "David Worms";
+ email = "david@adaltas.com";
+ github = "wdavidw";
+ githubId = 46896;
+ };
wedens = {
email = "kirill.wedens@gmail.com";
name = "wedens";
diff --git a/third_party/nixpkgs/maintainers/scripts/haskell/regenerate-hackage-packages.sh b/third_party/nixpkgs/maintainers/scripts/haskell/regenerate-hackage-packages.sh
index 285f6ed7cf..9d51eb4ca4 100755
--- a/third_party/nixpkgs/maintainers/scripts/haskell/regenerate-hackage-packages.sh
+++ b/third_party/nixpkgs/maintainers/scripts/haskell/regenerate-hackage-packages.sh
@@ -20,7 +20,7 @@ HACKAGE2NIX="${HACKAGE2NIX:-hackage2nix}"
# See: https://github.com/NixOS/nixpkgs/pull/122023
export LC_ALL=C.UTF-8
-extraction_derivation='with import ./. {}; runCommand "unpacked-cabal-hashes" { } "tar xf ${all-cabal-hashes} --strip-components=1 --one-top-level=$out"'
+extraction_derivation='with import ./. {}; runCommandLocal "unpacked-cabal-hashes" { } "tar xf ${all-cabal-hashes} --strip-components=1 --one-top-level=$out"'
unpacked_hackage="$(nix-build -E "$extraction_derivation" --no-out-link)"
config_dir=pkgs/development/haskell-modules/configuration-hackage2nix
diff --git a/third_party/nixpkgs/maintainers/scripts/luarocks-packages.csv b/third_party/nixpkgs/maintainers/scripts/luarocks-packages.csv
index d69546cdf0..bdda8020a3 100644
--- a/third_party/nixpkgs/maintainers/scripts/luarocks-packages.csv
+++ b/third_party/nixpkgs/maintainers/scripts/luarocks-packages.csv
@@ -81,6 +81,6 @@ rapidjson,https://github.com/xpol/lua-rapidjson.git,,,,,
readline,,,,,,
say,https://github.com/Olivine-Labs/say.git,,,,,
std._debug,https://github.com/lua-stdlib/_debug.git,,,,,
-std.normalize,git://github.com/lua-stdlib/normalize.git,,,,,
+std.normalize,https://github.com/lua-stdlib/normalize.git,,,,,
stdlib,,,,41.2.2,,vyp
vstruct,https://github.com/ToxicFrog/vstruct.git,,,,,
diff --git a/third_party/nixpkgs/maintainers/scripts/remove-old-aliases.py b/third_party/nixpkgs/maintainers/scripts/remove-old-aliases.py
index 5d9398feaa..c5629c8295 100755
--- a/third_party/nixpkgs/maintainers/scripts/remove-old-aliases.py
+++ b/third_party/nixpkgs/maintainers/scripts/remove-old-aliases.py
@@ -28,6 +28,11 @@ def process_args() -> argparse.Namespace:
default=1,
help="operate on aliases older than $year-$month",
)
+ arg_parser.add_argument(
+ "--only-throws",
+ action="store_true",
+ help="only operate on throws. e.g remove throws older than $date",
+ )
arg_parser.add_argument("--file", required=True, type=Path, help="alias file")
arg_parser.add_argument(
"--dry-run", action="store_true", help="don't modify files, only print results"
@@ -36,7 +41,7 @@ def process_args() -> argparse.Namespace:
def get_date_lists(
- txt: list[str], cutoffdate: datetimedate
+ txt: list[str], cutoffdate: datetimedate, only_throws: bool
) -> tuple[list[str], list[str], list[str]]:
"""get a list of lines in which the date is older than $cutoffdate"""
date_older_list: list[str] = []
@@ -57,7 +62,11 @@ def get_date_lists(
except ValueError:
continue
- if my_date is None or my_date > cutoffdate:
+ if (
+ my_date is None
+ or my_date > cutoffdate
+ or "preserve, reason:" in line.lower()
+ ):
continue
if "=" not in line:
@@ -67,7 +76,7 @@ def get_date_lists(
print(f"RESOLVE MANUALLY {line}")
elif "throw" in line:
date_older_throw_list.append(line)
- else:
+ elif not only_throws:
date_older_list.append(line)
return (
@@ -160,6 +169,7 @@ def main() -> None:
"""main"""
args = process_args()
+ only_throws = args.only_throws
aliasfile = Path(args.file).absolute()
cutoffdate = (datetime.strptime(f"{args.year}-{args.month}-01", "%Y-%m-%d")).date()
@@ -170,13 +180,12 @@ def main() -> None:
date_older_throw_list: list[str] = []
date_older_list, date_sep_line_list, date_older_throw_list = get_date_lists(
- txt, cutoffdate
+ txt, cutoffdate, only_throws
)
converted_to_throw: list[tuple[str, str]] = []
- converted_to_throw = convert_to_throw(date_older_list)
-
if date_older_list:
+ converted_to_throw = convert_to_throw(date_older_list)
print(" Will be converted to throws. ".center(100, "-"))
for l_n in date_older_list:
print(l_n)
diff --git a/third_party/nixpkgs/maintainers/team-list.nix b/third_party/nixpkgs/maintainers/team-list.nix
index bf4fcc6a4a..66cba166f2 100644
--- a/third_party/nixpkgs/maintainers/team-list.nix
+++ b/third_party/nixpkgs/maintainers/team-list.nix
@@ -117,6 +117,7 @@ with lib.maintainers; {
gnome = {
members = [
+ bobby285271
hedning
jtojnar
dasj19
diff --git a/third_party/nixpkgs/nixos/doc/manual/development/option-declarations.section.md b/third_party/nixpkgs/nixos/doc/manual/development/option-declarations.section.md
index 819fc6d891..53ecb9b3a6 100644
--- a/third_party/nixpkgs/nixos/doc/manual/development/option-declarations.section.md
+++ b/third_party/nixpkgs/nixos/doc/manual/development/option-declarations.section.md
@@ -27,9 +27,10 @@ The function `mkOption` accepts the following arguments.
`type`
-: The type of the option (see [](#sec-option-types)). It may be
- omitted, but that's not advisable since it may lead to errors that
- are hard to diagnose.
+: The type of the option (see [](#sec-option-types)). This
+ argument is mandatory for nixpkgs modules. Setting this is highly
+ recommended for the sake of documentation and type checking. In case it is
+ not set, a fallback type with unspecified behavior is used.
`default`
diff --git a/third_party/nixpkgs/nixos/doc/manual/development/option-types.section.md b/third_party/nixpkgs/nixos/doc/manual/development/option-types.section.md
index c34ac0367c..00f1d85bdb 100644
--- a/third_party/nixpkgs/nixos/doc/manual/development/option-types.section.md
+++ b/third_party/nixpkgs/nixos/doc/manual/development/option-types.section.md
@@ -22,7 +22,8 @@ merging is handled.
`types.package`
-: A derivation or a store path.
+: A top-level store path. This can be an attribute set pointing
+ to a store path, like a derivation or a flake input.
`types.anything`
diff --git a/third_party/nixpkgs/nixos/doc/manual/development/unit-handling.section.md b/third_party/nixpkgs/nixos/doc/manual/development/unit-handling.section.md
index bd4fe9e670..a7ccb3dbd0 100644
--- a/third_party/nixpkgs/nixos/doc/manual/development/unit-handling.section.md
+++ b/third_party/nixpkgs/nixos/doc/manual/development/unit-handling.section.md
@@ -17,7 +17,8 @@ checks:
them and comparing their contents. If they are different but only
`X-Reload-Triggers` in the `[Unit]` section is changed, **reload** the unit.
The NixOS module system allows setting these triggers with the option
- [systemd.services.\.reloadTriggers](#opt-systemd.services). If the
+ [systemd.services.\.reloadTriggers](#opt-systemd.services). There are
+ some additional keys in the `[Unit]` section that are ignored as well. If the
unit files differ in any way, the following actions are performed:
- `.path` and `.slice` units are ignored. There is no need to restart them
@@ -33,6 +34,9 @@ checks:
- The rest of the units (mostly `.service` units) are then **reload**ed if
`X-ReloadIfChanged` in the `[Service]` section is set to `true` (exposed
via [systemd.services.\.reloadIfChanged](#opt-systemd.services)).
+ A little exception is done for units that were deactivated in the meantime,
+ for example because they require a unit that got stopped before. These
+ are **start**ed instead of reloaded.
- If the reload flag is not set, some more flags decide if the unit is
skipped. These flags are `X-RestartIfChanged` in the `[Service]` section
diff --git a/third_party/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md b/third_party/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md
index 2e3c6b34f1..0c41cbd3cb 100644
--- a/third_party/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md
+++ b/third_party/nixpkgs/nixos/doc/manual/development/writing-modules.chapter.md
@@ -90,6 +90,17 @@ modules: `systemd.services` (the set of all systemd services) and
`systemd.timers` (the list of commands to be executed periodically by
`systemd`).
+Care must be taken when writing systemd services using `Exec*` directives. By
+default systemd performs substitution on `%` specifiers in these
+directives, expands environment variables from `$FOO` and `${FOO}`, splits
+arguments on whitespace, and splits commands on `;`. All of these must be escaped
+to avoid unexpected substitution or splitting when interpolating into an `Exec*`
+directive, e.g. when using an `extraArgs` option to pass additional arguments to
+the service. The functions `utils.escapeSystemdExecArg` and
+`utils.escapeSystemdExecArgs` are provided for this, see [Example: Escaping in
+Exec directives](#exec-escaping-example) for an example. When using these
+functions system environment substitution should *not* be disabled explicitly.
+
::: {#locate-example .example}
::: {.title}
**Example: NixOS Module for the "locate" Service**
@@ -153,6 +164,37 @@ in {
```
:::
+::: {#exec-escaping-example .example}
+::: {.title}
+**Example: Escaping in Exec directives**
+:::
+```nix
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+let
+ cfg = config.services.echo;
+ echoAll = pkgs.writeScript "echo-all" ''
+ #! ${pkgs.runtimeShell}
+ for s in "$@"; do
+ printf '%s\n' "$s"
+ done
+ '';
+ args = [ "a%Nything" "lang=\${LANG}" ";" "/bin/sh -c date" ];
+in {
+ systemd.services.echo =
+ { description = "Echo to the journal";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.ExecStart = ''
+ ${echoAll} ${utils.escapeSystemdExecArgs args}
+ '';
+ };
+}
+```
+:::
+
```{=docbook}
diff --git a/third_party/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.section.md b/third_party/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.section.md
index 7de57d0d2a..433e1906f7 100644
--- a/third_party/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.section.md
+++ b/third_party/nixpkgs/nixos/doc/manual/development/writing-nixos-tests.section.md
@@ -158,6 +158,12 @@ The following methods are available on machine objects:
e.g., `send_chars("foobar\n")` will type the string `foobar`
followed by the Enter key.
+`send_console`
+
+: Send keys to the kernel console. This allows interaction with the systemd
+ emergency mode, for example. Takes a string that is sent, e.g.,
+ `send_console("\n\nsystemctl default\n")`.
+
`execute`
: Execute a shell command, returning a list `(status, stdout)`.
@@ -272,6 +278,13 @@ The following methods are available on machine objects:
Killing the interactive session with `Ctrl-d` or `Ctrl-c` also ends
the guest session.
+`console_interact`
+
+: Allows you to directly interact with QEMU's stdin. This should
+ only be used during test development, not in production tests.
+ Output from QEMU is only read line-wise. `Ctrl-c` kills QEMU and
+ `Ctrl-d` closes console and returns to the test runner.
+
To test user units declared by `systemd.user.services` the optional
`user` argument can be used:
diff --git a/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-declarations.section.xml b/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-declarations.section.xml
index 554705e2e4..0ac5e0eeca 100644
--- a/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-declarations.section.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-declarations.section.xml
@@ -38,9 +38,11 @@ options = {
The type of the option (see
- ). It may be omitted, but
- that’s not advisable since it may lead to errors that are hard
- to diagnose.
+ ). This argument is
+ mandatory for nixpkgs modules. Setting this is highly
+ recommended for the sake of documentation and type checking.
+ In case it is not set, a fallback type with unspecified
+ behavior is used.
diff --git a/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-types.section.xml b/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-types.section.xml
index e16453df51..4447292927 100644
--- a/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-types.section.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/from_md/development/option-types.section.xml
@@ -43,7 +43,9 @@
- A derivation or a store path.
+ A top-level store path. This can be an attribute set
+ pointing to a store path, like a derivation or a flake
+ input.
diff --git a/third_party/nixpkgs/nixos/doc/manual/from_md/development/unit-handling.section.xml b/third_party/nixpkgs/nixos/doc/manual/from_md/development/unit-handling.section.xml
index 57c4754c00..4c980e1213 100644
--- a/third_party/nixpkgs/nixos/doc/manual/from_md/development/unit-handling.section.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/from_md/development/unit-handling.section.xml
@@ -38,8 +38,9 @@
reload the unit. The NixOS
module system allows setting these triggers with the option
systemd.services.<name>.reloadTriggers.
- If the unit files differ in any way, the following actions are
- performed:
+ There are some additional keys in the [Unit]
+ section that are ignored as well. If the unit files differ in
+ any way, the following actions are performed:
@@ -71,6 +72,11 @@
[Service] section is set to
true (exposed via
systemd.services.<name>.reloadIfChanged).
+ A little exception is done for units that were deactivated
+ in the meantime, for example because they require a unit
+ that got stopped before. These are
+ started instead of
+ reloaded.
diff --git a/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml b/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml
index e33c24f4f1..367731eda0 100644
--- a/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-modules.chapter.xml
@@ -122,6 +122,25 @@
services) and systemd.timers (the list of
commands to be executed periodically by systemd).
+
+ Care must be taken when writing systemd services using
+ Exec* directives. By default systemd performs
+ substitution on %<char> specifiers in these
+ directives, expands environment variables from
+ $FOO and ${FOO}, splits
+ arguments on whitespace, and splits commands on
+ ;. All of these must be escaped to avoid
+ unexpected substitution or splitting when interpolating into an
+ Exec* directive, e.g. when using an
+ extraArgs option to pass additional arguments to
+ the service. The functions
+ utils.escapeSystemdExecArg and
+ utils.escapeSystemdExecArgs are provided for
+ this, see Example: Escaping in
+ Exec directives for an example. When using these functions
+ system environment substitution should not be
+ disabled explicitly.
+
Example: NixOS Module for the
@@ -183,6 +202,36 @@ in {
};
};
}
+
+
+
+ Example: Escaping in Exec
+ directives
+
+
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+let
+ cfg = config.services.echo;
+ echoAll = pkgs.writeScript "echo-all" ''
+ #! ${pkgs.runtimeShell}
+ for s in "$@"; do
+ printf '%s\n' "$s"
+ done
+ '';
+ args = [ "a%Nything" "lang=\${LANG}" ";" "/bin/sh -c date" ];
+in {
+ systemd.services.echo =
+ { description = "Echo to the journal";
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig.Type = "oneshot";
+ serviceConfig.ExecStart = ''
+ ${echoAll} ${utils.escapeSystemdExecArgs args}
+ '';
+ };
+}
diff --git a/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml b/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml
index 45c9c40c60..4f856f98f2 100644
--- a/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml
@@ -261,6 +261,19 @@ start_all()
+
+
+ send_console
+
+
+
+ Send keys to the kernel console. This allows interaction
+ with the systemd emergency mode, for example. Takes a string
+ that is sent, e.g.,
+ send_console("\n\nsystemctl default\n").
+
+
+
execute
@@ -502,6 +515,21 @@ machine.systemctl("list-jobs --no-pager", "any-user") # spaw
+
+
+ console_interact
+
+
+
+ Allows you to directly interact with QEMU’s stdin. This
+ should only be used during test development, not in
+ production tests. Output from QEMU is only read line-wise.
+ Ctrl-c kills QEMU and
+ Ctrl-d closes console and returns to the
+ test runner.
+
+
+
To test user units declared by
diff --git a/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml b/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
index a11baa91de..b61a0268de 100644
--- a/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
@@ -35,7 +35,17 @@
This means, ip[6]tables,
arptables and ebtables
commands will actually show rules from some specific tables in
- the nf_tables kernel subsystem.
+ the nf_tables kernel subsystem. In case
+ you’re migrating from an older release without rebooting,
+ there might be cases where you end up with iptable rules
+ configured both in the legacy iptables
+ kernel backend, as well as in the nf_tables
+ backend. This can lead to confusing firewall behaviour. An
+ iptables-save after switching will complain
+ about iptables-legacy tables present
. It’s
+ probably best to reboot after the upgrade, or manually
+ removing all legacy iptables rules (via the
+ iptables-legacy package).
diff --git a/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml b/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
index b20aabd859..0c5b3b4fec 100644
--- a/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
@@ -15,6 +15,14 @@
Highlights
+
+
+ The firefox browser on
+ x86_64-linux is now making use of
+ profile-guided optimization resulting in a much more
+ responsive browsing experience.
+
+
security.acme.defaults has been added to
@@ -25,6 +33,16 @@
services.nginx.virtualHosts.*.enableACME).
+
+
+ GNOME has been upgraded to 42. Please take a look at their
+ Release
+ Notes for details. Notably, it replaces gedit with
+ GNOME Text Editor, GNOME Terminal with GNOME Console (formerly
+ King’s Cross), and GNOME Screenshot with a tool built into the
+ Shell.
+
+
PHP 8.1 is now available
@@ -62,6 +80,14 @@
notes for details.
+
+
+ Module authors can use
+ mkRenamedOptionModuleWith to automate the
+ deprecation cycle without annoying out-of-tree module authors
+ and their users.
+
+
@@ -109,7 +135,7 @@
FRRouting, a
popular suite of Internet routing protocol daemons (BGP, BFD,
- OSPF, IS-IS, VVRP and others). Available as
+ OSPF, IS-IS, VRRP and others). Available as
services.frr
@@ -187,6 +213,14 @@
services.mtr-exporter.
+
+
+ prometheus-pve-exporter,
+ a tool that exposes information from the Proxmox VE API for
+ use by Prometheus. Available as
+ services.prometheus.exporters.pve.
+
+
tetrd, share your
@@ -241,6 +275,17 @@
services.prosody-filer.
+
+
+ systembus-notify,
+ allow system level notifications to reach the users. Available
+ as
+ services.systembus-notify.
+ Please keep in mind that this service should only be enabled
+ on machines with fully trusted users, as any local user is
+ able to DoS user sessions by spamming notifications.
+
+
ethercalc,
@@ -248,6 +293,20 @@
services.ethercalc.
+
+
+ nbd, a
+ Network Block Device server. Available as
+ services.nbd.
+
+
+
+
+ nix-ld,
+ Run unpatched dynamic binaries on NixOS. Available as
+ programs.nix-ld.
+
+
timetagger,
@@ -280,6 +339,12 @@
with many features.
+
+
+ pacemaker
+ cluster resource manager
+
+
@@ -378,6 +443,24 @@
in your configuration.
+
+
+ fonts.fonts no longer includes ancient
+ bitmap fonts when both
+ config.services.xserver.enable and
+ config.nixpkgs.config.allowUnfree are
+ enabled. If you still want these fonts, use:
+
+
+{
+ fonts.fonts = [
+ pkgs.xorg.fontbhlucidatypewriter100dpi
+ pkgs.xorg.fontbhlucidatypewriter75dpi
+ pkgs.xorg.fontbh100dpi
+ ];
+}
+
+
The DHCP server (services.dhcpd4,
@@ -402,6 +485,15 @@
its reliance on python2.
+
+
+ services.ipfs.extraFlags is now escaped
+ with utils.escapeSystemdExecArgs. If you
+ rely on systemd interpolating extraFlags in
+ the service ExecStart, this will no longer
+ work.
+
+
The matrix-synapse service
@@ -417,6 +509,12 @@
still supported, because you can set arbitrary values in this
freeform type.
+
+ The listeners.*.bind_address option was
+ renamed to bind_addresses in order to match
+ the upstream homeserver.yaml option name.
+ It is now also a list of strings instead of a string.
+
An example to make the required migration clearer:
@@ -478,7 +576,7 @@
listeners = [ {
port = 8448;
- bind_address = [
+ bind_addresses = [
"::"
"0.0.0.0"
];
@@ -509,7 +607,14 @@
Additionally a few option defaults have been synced up with
upstream default values, for example the
max_upload_size grew from
- 10M to 50M.
+ 10M to 50M. For the same
+ reason, the default media_store_path was
+ changed from ${dataDir}/media to
+ ${dataDir}/media_store if
+ system.stateVersion is at least
+ 22.05. Files will need to be manually moved
+ to the new location if the stateVersion is
+ updated.
@@ -519,6 +624,25 @@
because Python 2 is being retired from nixpkgs.
+
+
+ Services in the hadoop module previously
+ set openFirewall to true by default. This
+ has now been changed to false. Node definitions for multi-node
+ clusters would need openFirewall = true; to
+ be added to to hadoop services when upgrading from NixOS
+ 21.11.
+
+
+
+
+ services.hadoop.yarn.nodemanager now uses
+ cgroup-based CPU limit enforcement by default. Additionally,
+ the option useCGroups was added to
+ nodemanagers as an easy way to switch back to the old
+ behavior.
+
+
The wafHook hook now honors
@@ -564,6 +688,23 @@
6.x and renamed to gnome-secrets.
+
+
+ services.gnome.experimental-features.realtime-scheduling
+ option has been removed, as GNOME Shell now
+ uses
+ rtkit. Use
+ security.rtkit.enable = true; instead. As
+ before, you will need to have it enabled using GSettings.
+
+
+
+
+ services.telepathy will no longer be
+ enabled by default for GNOME desktops, one should enable it in
+ their configs if using Empathy or Polari.
+
+
If you previously used
@@ -691,6 +832,60 @@
unmaintained
+
+
+ pkgs._7zz is now correctly licensed as
+ LGPL3+ and BSD3 with optional unfree unRAR licensed code
+
+
+
+
+ The vim.customize function produced by
+ vimUtils.makeCustomizable now has a
+ slightly different interface:
+
+
+
+
+ The wrapper now includes everything in the given Vim
+ derivation if name is
+ "vim" (the default). This
+ makes the wrapManual argument obsolete,
+ but this behavior can be overriden by setting the
+ standalone argument.
+
+
+
+
+ All the executables present in the given derivation (or,
+ in standalone mode, only the
+ *vim ones) are wrapped. This makes the
+ wrapGui argument obsolete.
+
+
+
+
+ The vimExecutableName and
+ gvimExecutableName arguments were
+ replaced by a single executableName
+ argument in which the shell variable
+ $exe can be used to refer to the
+ wrapped executable’s name.
+
+
+
+
+ See the comments in
+ pkgs/applications/editors/vim/plugins/vim-utils.nix
+ for more details.
+
+
+ vimUtils.vimWithRC was removed. You should
+ instead use customize on a Vim derivation,
+ which now accepts vimrcFile and
+ gvimrcFile arguments.
+
+
tilp2 was removed together with its module
@@ -723,6 +918,16 @@
true.
+
+
+ The miller package has been upgraded from
+ 5.10.3 to
+ 6.2.0.
+ See
+ What’s
+ new in Miller 6.
+
+
MultiMC has been replaced with the fork PolyMC due to upstream
@@ -748,6 +953,16 @@
systemd.nspawn.<name>.execConfig.PrivateUsers = false
+
+
+ The Tor SOCKS proxy is now actually disabled if
+ services.tor.client.enable is set to
+ false (the default). If you are using this
+ functionality but didn’t change the setting or set it to
+ false, you now need to set it to
+ true.
+
+
The terraform 0.12 compatibility has been removed and the
@@ -811,6 +1026,58 @@
include serif fonts.
+
+
+ pkgs.epgstation has been upgraded from v1
+ to v2, resulting in incompatible changes in the database
+ scheme and configuration format.
+
+
+
+
+ Some top-level settings under
+ services.epgstation
+ is now deprecated because it was redudant due to the same
+ options being present in
+ services.epgstation.settings.
+
+
+
+
+ The option services.epgstation.basicAuth
+ was removed because basic authentication support was dropped
+ by upstream.
+
+
+
+
+ The option
+ services.epgstation.database.passwordFile
+ no longer has a default value. Make sure to set this option
+ explicitly before upgrading. Change the database password if
+ necessary.
+
+
+
+
+ The
+ services.epgstation.settings
+ option now expects options for config.yml
+ in EPGStation v2.
+
+
+
+
+ Existing data for the
+ services.epgstation
+ module would have to be backed up prior to the upgrade. To
+ back up exising data to
+ /tmp/epgstation.bak, run
+ sudo -u epgstation epgstation run backup /tmp/epgstation.bak.
+ To import that data after to the upgrade, run
+ sudo -u epgstation epgstation run v1migrate /tmp/epgstation.bak
+
+
switch-to-configuration (the script that is
@@ -1050,7 +1317,8 @@
Legacy options have been mapped to the corresponding
options under under
nix.settings
- but may be deprecated in the future.
+ and will be deprecated when NixOS 21.11 reaches end of
+ life.
@@ -1071,6 +1339,33 @@
using the PyPy interpreter were added.
+
+
+ Some improvements have been made to the
+ hadoop module:
+
+
+
+
+ A gatewayRole option has been added,
+ for deploying hadoop cluster configuration files to a node
+ that does not have any active services
+
+
+
+
+ Support for older versions of hadoop have been added to
+ the module
+
+
+
+
+ Overriding and extending site XML files has been made
+ easier
+
+
+
+
If you are using Wayland you can choose to use the Ozone
@@ -1094,6 +1389,14 @@
compatibilty, but will be removed at a later date.
+
+
+ The unifi package was switched from
+ unifi6 to unifi7. Direct
+ downgrades from Unifi 7 to Unifi 6 are not possible and
+ require restoring from a backup made by Unifi 6.
+
+
programs.zsh.autosuggestions.strategy now
@@ -1108,6 +1411,15 @@
using this default will print a warning when rebuilt.
+
+
+ The services.unifi-video.openPorts option
+ default value of true is now deprecated and
+ will be changed to false in 22.11.
+ Configurations using this default will print a warning when
+ rebuilt.
+
+
security.acme certificates will now
@@ -1171,10 +1483,10 @@
- A new option
- boot.initrd.extraModprobeConfig has been
- added which can be used to configure kernel modules that are
- loaded in the initrd.
+ The options boot.extraModprobeConfig and
+ boot.blacklistedKernelModules now also take
+ effect in the initrd by copying the file
+ /etc/modprobe.d/nixos.conf into the initrd.
@@ -1184,6 +1496,52 @@
instead of configuration.nix.
+
+
+ ORY Kratos was updated to version 0.8.3-alpha.1.pre.0, which
+ introduces some breaking changes:
+
+
+
+
+ If you are relying on the SQLite images, update your
+ Docker Pull commands as follows:
+
+
+
+
+ docker pull oryd/kratos:{version}
+
+
+
+
+
+
+ Additionally, all passwords now have to be at least 8
+ characters long.
+
+
+
+
+ For more details, see:
+
+
+
+
+ Release
+ Notes for v0.8.1-alpha-1
+
+
+
+
+ Release
+ Notes for v0.8.2-alpha-1
+
+
+
+
+
+
fetchFromSourcehut now allows fetching
@@ -1212,6 +1570,15 @@
pkgs.theLoungePlugins.themes.
+
+
+ The option
+ services.xserver.videoDriver = [ "nvidia" ];
+ will now also install
+ nvidia
+ VA-API drivers by default.
+
+
The firmwareLinuxNonfree package has been
@@ -1271,15 +1638,6 @@
been added by default.
-
-
- security.pam.ussh has been added, which
- allows authorizing PAM sessions based on SSH
- certificates held within an SSH agent,
- using
- pam-ussh.
-
-
The zrepl package has been updated from
@@ -1316,6 +1674,12 @@
warning.
+
+
+ services.autorandr now allows for adding
+ hooks and profiles declaratively.
+
+
The pomerium-cli command has been moved out
@@ -1354,6 +1718,52 @@
desktop environments as needed.
+
+
+ The hadoop package has added support for
+ aarch64-linux and
+ aarch64-darwin as of 3.3.1
+ (#158613).
+
+
+
+
+ The R package now builds again on
+ aarch64-darwin
+ (#158992).
+
+
+
+
+ The spark3 package has been updated from
+ 3.1.2 to 3.2.1
+ (#160075):
+
+
+
+
+ Testing has been enabled for
+ aarch64-linux in addition to
+ x86_64-linux.
+
+
+
+
+ The spark3 package is now usable on
+ aarch64-darwin as a result of
+ #158613
+ and
+ #158992.
+
+
+
+
+
+
+ The programs.nncp options were added for
+ generating host-global NNCP configuration.
+
+
diff --git a/third_party/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml b/third_party/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
index ab2a5d83a0..b2ca9f457a 100644
--- a/third_party/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
+++ b/third_party/nixpkgs/nixos/doc/manual/man-nixos-rebuild.xml
@@ -91,6 +91,10 @@
flake-uri
+
+
+
+
input-name flake-uri
@@ -594,6 +598,20 @@
+
+
+
+
+
+
+ Do not imply if
+ /etc/nixos/flake.nix exists. With this
+ option, it is possible to build non-flake NixOS configurations
+ even if the current NixOS systems uses flakes.
+
+
+
+
diff --git a/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2111.section.md b/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2111.section.md
index f3644c3283..310d32cfdd 100644
--- a/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2111.section.md
+++ b/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2111.section.md
@@ -13,6 +13,13 @@ In addition to numerous new and upgraded packages, this release has the followin
[Fedora](https://fedoraproject.org/wiki/Changes/iptables-nft-default).
This means, `ip[6]tables`, `arptables` and `ebtables` commands will actually
show rules from some specific tables in the `nf_tables` kernel subsystem.
+ In case you're migrating from an older release without rebooting, there might
+ be cases where you end up with iptable rules configured both in the legacy
+ `iptables` kernel backend, as well as in the `nf_tables` backend.
+ This can lead to confusing firewall behaviour. An `iptables-save` after
+ switching will complain about "iptables-legacy tables present".
+ It's probably best to reboot after the upgrade, or manually removing all
+ legacy iptables rules (via the `iptables-legacy` package).
- systemd got an `nftables` backend, and configures (networkd) rules in their
own `io.systemd.*` tables. Check `nft list ruleset` to see these rules, not
diff --git a/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md b/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md
index 88c1dd5729..7cafdcabba 100644
--- a/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md
+++ b/third_party/nixpkgs/nixos/doc/manual/release-notes/rl-2205.section.md
@@ -6,11 +6,17 @@ In addition to numerous new and upgraded packages, this release has the followin
## Highlights {#sec-release-22.05-highlights}
+- The `firefox` browser on `x86_64-linux` is now making use of
+ profile-guided optimization resulting in a much more responsive
+ browsing experience.
+
- `security.acme.defaults` has been added to simplify configuring
settings for many certificates at once. This also opens up the
the option to use DNS-01 validation when using `enableACME` on
web server virtual hosts (e.g. `services.nginx.virtualHosts.*.enableACME`).
+- GNOME has been upgraded to 42. Please take a look at their [Release Notes](https://release.gnome.org/42/) for details. Notably, it replaces gedit with GNOME Text Editor, GNOME Terminal with GNOME Console (formerly King’s Cross), and GNOME Screenshot with a tool built into the Shell.
+
- PHP 8.1 is now available
- Mattermost has been updated to extended support release 6.3, as the previously packaged extended support release 5.37 is [reaching its end of life](https://docs.mattermost.com/upgrade/extended-support-release.html).
@@ -21,6 +27,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [`kops`](https://kops.sigs.k8s.io) defaults to 1.22.4, which will enable [Instance Metadata Service Version 2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) and require tokens on new clusters with Kubernetes 1.22. This will increase security by default, but may break some types of workloads. See the [release notes](https://kops.sigs.k8s.io/releases/1.22-notes/) for details.
+- Module authors can use `mkRenamedOptionModuleWith` to automate the deprecation cycle without annoying out-of-tree module authors and their users.
+
## New Services {#sec-release-22.05-new-services}
- [aesmd](https://github.com/intel/linux-sgx#install-the-intelr-sgx-psw), the Intel SGX Architectural Enclave Service Manager. Available as [services.aesmd](#opt-services.aesmd.enable).
@@ -33,7 +41,7 @@ In addition to numerous new and upgraded packages, this release has the followin
- [apfs](https://github.com/linux-apfs/linux-apfs-rw), a kernel module for mounting the Apple File System (APFS).
-- [FRRouting](https://frrouting.org/), a popular suite of Internet routing protocol daemons (BGP, BFD, OSPF, IS-IS, VVRP and others). Available as [services.frr](#opt-services.frr.babel.enable)
+- [FRRouting](https://frrouting.org/), a popular suite of Internet routing protocol daemons (BGP, BFD, OSPF, IS-IS, VRRP and others). Available as [services.frr](#opt-services.frr.babel.enable)
- [heisenbridge](https://github.com/hifi/heisenbridge), a bouncer-style Matrix IRC bridge. Available as [services.heisenbridge](options.html#opt-services.heisenbridge.enable).
@@ -55,6 +63,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [mtr-exporter](https://github.com/mgumz/mtr-exporter), a Prometheus exporter for mtr metrics. Available as [services.mtr-exporter](options.html#opt-services.mtr-exporter.enable).
+- [prometheus-pve-exporter](https://github.com/prometheus-pve/prometheus-pve-exporter), a tool that exposes information from the Proxmox VE API for use by Prometheus. Available as [services.prometheus.exporters.pve](options.html#opt-services.prometheus.exporters.pve).
+
- [tetrd](https://tetrd.app), share your internet connection from your device to your PC and vice versa through a USB cable. Available at [services.tetrd](#opt-services.tetrd.enable).
- [agate](https://github.com/mbrubeck/agate), a very simple server for the Gemini hypertext protocol. Available as [services.agate](options.html#opt-services.agate.enable).
@@ -70,9 +80,15 @@ In addition to numerous new and upgraded packages, this release has the followin
- [prosody-filer](https://github.com/ThomasLeister/prosody-filer), a server for handling XMPP HTTP Upload requests. Available at [services.prosody-filer](#opt-services.prosody-filer.enable).
+- [systembus-notify](https://github.com/rfjakob/systembus-notify), allow system level notifications to reach the users. Available as [services.systembus-notify](opt-services.systembus-notify.enable). Please keep in mind that this service should only be enabled on machines with fully trusted users, as any local user is able to DoS user sessions by spamming notifications.
+
- [ethercalc](https://github.com/audreyt/ethercalc), an online collaborative
spreadsheet. Available as [services.ethercalc](options.html#opt-services.ethercalc.enable).
+- [nbd](https://nbd.sourceforge.io/), a Network Block Device server. Available as [services.nbd](options.html#opt-services.nbd.server.enable).
+
+- [nix-ld](https://github.com/Mic92/nix-ld), Run unpatched dynamic binaries on NixOS. Available as [programs.nix-ld](options.html#opt-programs.nix-ld.enable).
+
- [timetagger](https://timetagger.app), an open source time-tracker with an intuitive user experience and powerful reporting. [services.timetagger](options.html#opt-services.timetagger.enable).
- [rstudio-server](https://www.rstudio.com/products/rstudio/#rstudio-server), a browser-based version of the RStudio IDE for the R programming language. Available as [services.rstudio-server](options.html#opt-services.rstudio-server.enable).
@@ -81,6 +97,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [blocky](https://0xerr0r.github.io/blocky/), fast and lightweight DNS proxy as ad-blocker for local network with many features.
+- [pacemaker](https://clusterlabs.org/pacemaker/) cluster resource manager
+
## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
@@ -125,6 +143,19 @@ In addition to numerous new and upgraded packages, this release has the followin
This change may require a reboot to take effect, and k3s may not be able to run if the boot cgroup hierarchy does not match its configuration.
The previous behavior may be retained by explicitly setting `systemd.enableUnifiedCgroupHierarchy = false` in your configuration.
+- `fonts.fonts` no longer includes ancient bitmap fonts when both `config.services.xserver.enable` and `config.nixpkgs.config.allowUnfree` are enabled.
+ If you still want these fonts, use:
+
+ ```nix
+ {
+ fonts.fonts = [
+ pkgs.xorg.fontbhlucidatypewriter100dpi
+ pkgs.xorg.fontbhlucidatypewriter75dpi
+ pkgs.xorg.fontbh100dpi
+ ];
+ }
+ ```
+
- The DHCP server (`services.dhcpd4`, `services.dhcpd6`) has been hardened.
The service is now using the systemd's `DynamicUser` mechanism to run as an unprivileged dynamically-allocated user with limited capabilities.
The dhcpd state files are now always stored in `/var/lib/dhcpd{4,6}` and the `services.dhcpd4.stateDir` and `service.dhcpd6.stateDir` options have been removed.
@@ -132,11 +163,16 @@ In addition to numerous new and upgraded packages, this release has the followin
- The `mailpile` email webclient (`services.mailpile`) has been removed due to its reliance on python2.
+- `services.ipfs.extraFlags` is now escaped with `utils.escapeSystemdExecArgs`. If you rely on systemd interpolating `extraFlags` in the service `ExecStart`, this will no longer work.
+
- The `matrix-synapse` service (`services.matrix-synapse`) has been converted to use the `settings` option defined in RFC42.
This means that options that are part of your `homeserver.yaml` configuration, and that were specified at the top-level of the
module (`services.matrix-synapse`) now need to be moved into `services.matrix-synapse.settings`. And while not all options you
may use are defined in there, they are still supported, because you can set arbitrary values in this freeform type.
+ The `listeners.*.bind_address` option was renamed to `bind_addresses` in order to match the upstream `homeserver.yaml` option
+ name. It is now also a list of strings instead of a string.
+
An example to make the required migration clearer:
Before:
@@ -194,7 +230,7 @@ In addition to numerous new and upgraded packages, this release has the followin
listeners = [ {
port = 8448;
- bind_address = [
+ bind_addresses = [
"::"
"0.0.0.0"
];
@@ -219,10 +255,20 @@ In addition to numerous new and upgraded packages, this release has the followin
The secrets in your original config should be migrated into a YAML file that is included via `extraConfigFiles`.
- Additionally a few option defaults have been synced up with upstream default values, for example the `max_upload_size` grew from `10M` to `50M`.
+ Additionally a few option defaults have been synced up with upstream default values, for example the `max_upload_size` grew from `10M` to `50M`. For the same reason, the default
+ `media_store_path` was changed from `${dataDir}/media` to `${dataDir}/media_store` if `system.stateVersion` is at least `22.05`. Files will need to be manually moved to the new
+ location if the `stateVersion` is updated.
- The MoinMoin wiki engine (`services.moinmoin`) has been removed, because Python 2 is being retired from nixpkgs.
+- Services in the `hadoop` module previously set `openFirewall` to true by default.
+ This has now been changed to false. Node definitions for multi-node clusters would need
+ `openFirewall = true;` to be added to to hadoop services when upgrading from NixOS 21.11.
+
+- `services.hadoop.yarn.nodemanager` now uses cgroup-based CPU limit enforcement by default.
+ Additionally, the option `useCGroups` was added to nodemanagers as an easy way to switch
+ back to the old behavior.
+
- The `wafHook` hook now honors `NIX_BUILD_CORES` when `enableParallelBuilding` is not set explicitly. Packages can restore the old behaviour by setting `enableParallelBuilding=false`.
- `pkgs.claws-mail-gtk2`, representing Claws Mail's older release version three, was removed in order to get rid of Python 2.
@@ -235,6 +281,10 @@ In addition to numerous new and upgraded packages, this release has the followin
- The `gnome-passwordsafe` package updated to [version 6.x](https://gitlab.gnome.org/World/secrets/-/tags/6.0) and renamed to `gnome-secrets`.
+- `services.gnome.experimental-features.realtime-scheduling` option has been removed, as GNOME Shell now [uses rtkit](https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2060). Use `security.rtkit.enable = true;` instead. As before, you will need to have it enabled using GSettings.
+
+- `services.telepathy` will no longer be enabled by default for GNOME desktops, one should enable it in their configs if using Empathy or Polari.
+
- If you previously used `/etc/docker/daemon.json`, you need to incorporate the changes into the new option `virtualisation.docker.daemon.settings`.
- Ntopng (`services.ntopng`) is updated to 5.2.1 and uses a separate Redis instance if `system.stateVersion` is at least `22.05`. Existing setups shouldn't be affected.
@@ -275,6 +325,17 @@ In addition to numerous new and upgraded packages, this release has the followin
- `pkgs.docbookrx` was removed since it's unmaintained
+- `pkgs._7zz` is now correctly licensed as LGPL3+ and BSD3 with optional unfree unRAR licensed code
+
+- The `vim.customize` function produced by `vimUtils.makeCustomizable` now has a slightly different interface:
+ * The wrapper now includes everything in the given Vim derivation if `name` is `"vim"` (the default). This makes the `wrapManual` argument obsolete, but this behavior can be overriden by setting the `standalone` argument.
+ * All the executables present in the given derivation (or, in `standalone` mode, only the `*vim` ones) are wrapped. This makes the `wrapGui` argument obsolete.
+ * The `vimExecutableName` and `gvimExecutableName` arguments were replaced by a single `executableName` argument in which the shell variable `$exe` can be used to refer to the wrapped executable's name.
+
+ See the comments in `pkgs/applications/editors/vim/plugins/vim-utils.nix` for more details.
+
+ `vimUtils.vimWithRC` was removed. You should instead use `customize` on a Vim derivation, which now accepts `vimrcFile` and `gvimrcFile` arguments.
+
- `tilp2` was removed together with its module
- The F-PROT antivirus (`fprot` package) and its service module were removed because it
@@ -284,10 +345,14 @@ In addition to numerous new and upgraded packages, this release has the followin
- The options `networking.interfaces..ipv4.routes` and `networking.interfaces..ipv6.routes` are no longer ignored when using networkd instead of the default scripted network backend by setting `networking.useNetworkd` to `true`.
+- The `miller` package has been upgraded from 5.10.3 to [6.2.0](https://github.com/johnkerl/miller/releases/tag/v6.2.0). See [What's new in Miller 6](https://miller.readthedocs.io/en/latest/new-in-miller-6).
+
- MultiMC has been replaced with the fork PolyMC due to upstream developers being hostile to 3rd party package maintainers. PolyMC removes all MultiMC branding and is aimed at providing proper 3rd party packages like the one contained in Nixpkgs. This change affects the data folder where game instances and other save and configuration files are stored. Users with existing installations should rename `~/.local/share/multimc` to `~/.local/share/polymc`. The main config file's path has also moved from `~/.local/share/multimc/multimc.cfg` to `~/.local/share/polymc/polymc.cfg`.
- `systemd-nspawn@.service` settings have been reverted to the default systemd behaviour. User namespaces are now activated by default. If you want to keep running nspawn containers without user namespaces you need to set `systemd.nspawn..execConfig.PrivateUsers = false`
+- The Tor SOCKS proxy is now actually disabled if `services.tor.client.enable` is set to `false` (the default). If you are using this functionality but didn't change the setting or set it to `false`, you now need to set it to `true`.
+
- The terraform 0.12 compatibility has been removed and the `terraform.withPlugins` and `terraform-providers.mkProvider` implementations simplified. Providers now need to be stored under
`$out/libexec/terraform-providers/////_/terraform-provider-_v` (which mkProvider does).
@@ -317,6 +382,30 @@ In addition to numerous new and upgraded packages, this release has the followin
`pkgs.noto-fonts-cjk` is currently an alias of `pkgs.noto-fonts-cjk-sans` and
doesn't include serif fonts.
+- `pkgs.epgstation` has been upgraded from v1 to v2, resulting in incompatible
+ changes in the database scheme and configuration format.
+
+- Some top-level settings under [services.epgstation](#opt-services.epgstation.enable)
+ is now deprecated because it was redudant due to the same options being
+ present in [services.epgstation.settings](#opt-services.epgstation.settings).
+
+- The option `services.epgstation.basicAuth` was removed because basic
+ authentication support was dropped by upstream.
+
+- The option [services.epgstation.database.passwordFile](#opt-services.epgstation.database.passwordFile)
+ no longer has a default value. Make sure to set this option explicitly before
+ upgrading. Change the database password if necessary.
+
+- The [services.epgstation.settings](#opt-services.epgstation.settings)
+ option now expects options for `config.yml` in EPGStation v2.
+
+- Existing data for the [services.epgstation](#opt-services.epgstation.enable)
+ module would have to be backed up prior to the upgrade. To back up exising
+ data to `/tmp/epgstation.bak`, run
+ `sudo -u epgstation epgstation run backup /tmp/epgstation.bak`.
+ To import that data after to the upgrade, run
+ `sudo -u epgstation epgstation run v1migrate /tmp/epgstation.bak`
+
- `switch-to-configuration` (the script that is run when running `nixos-rebuild switch` for example) has been reworked
* The interface that allows activation scripts to restart units has been streamlined. Restarting and reloading is now done by a single file `/run/nixos/activation-restart-list` that honors `restartIfChanged` and `reloadIfChanged` of the units.
* Preferring to reload instead of restarting can still be achieved using `/run/nixos/activation-reload-list`.
@@ -386,11 +475,16 @@ In addition to numerous new and upgraded packages, this release has the followin
Similarly [virtualisation.vmVariantWithBootloader](#opt-virtualisation.vmVariantWithBootLoader) was added.
- The configuration portion of the `nix-daemon` module has been reworked and exposed as [nix.settings](options.html#opt-nix-settings):
- * Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) but may be deprecated in the future.
+ * Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) and will be deprecated when NixOS 21.11 reaches end of life.
* [nix.buildMachines.publicHostKey](options.html#opt-nix.buildMachines.publicHostKey) has been added.
- The `writers.writePyPy2`/`writers.writePyPy3` and corresponding `writers.writePyPy2Bin`/`writers.writePyPy3Bin` convenience functions to create executable Python 2/3 scripts using the PyPy interpreter were added.
+- Some improvements have been made to the `hadoop` module:
+ - A `gatewayRole` option has been added, for deploying hadoop cluster configuration files to a node that does not have any active services
+ - Support for older versions of hadoop have been added to the module
+ - Overriding and extending site XML files has been made easier
+
- If you are using Wayland you can choose to use the Ozone Wayland support
in Chrome and several Electron apps by setting the environment variable
`NIXOS_OZONE_WL=1` (for example via
@@ -404,11 +498,17 @@ In addition to numerous new and upgraded packages, this release has the followin
combined `influxdb2` package is still provided in this release for
backwards compatibilty, but will be removed at a later date.
+- The `unifi` package was switched from `unifi6` to `unifi7`.
+ Direct downgrades from Unifi 7 to Unifi 6 are not possible and require restoring from a backup made by Unifi 6.
+
- `programs.zsh.autosuggestions.strategy` now takes a list of strings instead of a string.
- The `services.unifi.openPorts` option default value of `true` is now deprecated and will be changed to `false` in 22.11.
Configurations using this default will print a warning when rebuilt.
+- The `services.unifi-video.openPorts` option default value of `true` is now deprecated and will be changed to `false` in 22.11.
+ Configurations using this default will print a warning when rebuilt.
+
- `security.acme` certificates will now correctly check for CA
revokation before reaching their minimum age.
@@ -433,10 +533,18 @@ In addition to numerous new and upgraded packages, this release has the followin
- The option `services.duplicati.dataDir` has been added to allow changing the location of duplicati's files.
-- A new option `boot.initrd.extraModprobeConfig` has been added which can be used to configure kernel modules that are loaded in the initrd.
+- The options `boot.extraModprobeConfig` and `boot.blacklistedKernelModules` now also take effect in the initrd by copying the file `/etc/modprobe.d/nixos.conf` into the initrd.
- `nixos-generate-config` now puts the dhcp configuration in `hardware-configuration.nix` instead of `configuration.nix`.
+- ORY Kratos was updated to version 0.8.3-alpha.1.pre.0, which introduces some breaking changes:
+ - If you are relying on the SQLite images, update your Docker Pull commands as follows:
+ - `docker pull oryd/kratos:{version}`
+ - Additionally, all passwords now have to be at least 8 characters long.
+ - For more details, see:
+ - [Release Notes for v0.8.1-alpha-1](https://github.com/ory/kratos/releases/tag/v0.8.1-alpha.1)
+ - [Release Notes for v0.8.2-alpha-1](https://github.com/ory/kratos/releases/tag/v0.8.2-alpha.1)
+
- `fetchFromSourcehut` now allows fetching repositories recursively
using `fetchgit` or `fetchhg` if the argument `fetchSubmodules`
is set to `true`.
@@ -447,6 +555,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- The option `services.thelounge.plugins` has been added to allow installing plugins for The Lounge. Plugins can be found in `pkgs.theLoungePlugins.plugins` and `pkgs.theLoungePlugins.themes`.
+- The option `services.xserver.videoDriver = [ "nvidia" ];` will now also install [nvidia VA-API drivers](https://github.com/elFarto/nvidia-vaapi-driver) by default.
+
- The `firmwareLinuxNonfree` package has been renamed to `linux-firmware`.
- It is now possible to specify wordlists to include as handy to access environment variables using the `config.environment.wordlist` configuration options.
@@ -466,8 +576,6 @@ In addition to numerous new and upgraded packages, this release has the followin
- `services.logrotate.enable` now defaults to true if any rotate path has
been defined, and some paths have been added by default.
-- `security.pam.ussh` has been added, which allows authorizing PAM sessions based on SSH _certificates_ held within an SSH agent, using [pam-ussh](https://github.com/uber/pam-ussh).
-
- The `zrepl` package has been updated from 0.4.0 to 0.5:
- The RPC protocol version was bumped; all zrepl daemons in a setup must be updated and restarted before replication can resume.
@@ -477,6 +585,8 @@ In addition to numerous new and upgraded packages, this release has the followin
Reason is that the old name has been deprecated upstream.
Using the old option name will still work, but produce a warning.
+- `services.autorandr` now allows for adding hooks and profiles declaratively.
+
- The `pomerium-cli` command has been moved out of the `pomerium` package into
the `pomerium-cli` package, following upstream's repository split. If you are
using the `pomerium-cli` command, you should now install the `pomerium-cli`
@@ -492,4 +602,15 @@ In addition to numerous new and upgraded packages, this release has the followin
- The polkit service, available at `security.polkit.enable`, is now disabled by default. It will automatically be enabled through services and desktop environments as needed.
+- The `hadoop` package has added support for `aarch64-linux` and `aarch64-darwin` as of 3.3.1 ([#158613](https://github.com/NixOS/nixpkgs/pull/158613)).
+
+- The `R` package now builds again on `aarch64-darwin` ([#158992](https://github.com/NixOS/nixpkgs/pull/158992)).
+
+- The `spark3` package has been updated from 3.1.2 to 3.2.1 ([#160075](https://github.com/NixOS/nixpkgs/pull/160075)):
+
+ - Testing has been enabled for `aarch64-linux` in addition to `x86_64-linux`.
+ - The `spark3` package is now usable on `aarch64-darwin` as a result of [#158613](https://github.com/NixOS/nixpkgs/pull/158613) and [#158992](https://github.com/NixOS/nixpkgs/pull/158992).
+
+- The `programs.nncp` options were added for generating host-global NNCP configuration.
+
diff --git a/third_party/nixpkgs/nixos/lib/make-options-doc/mergeJSON.py b/third_party/nixpkgs/nixos/lib/make-options-doc/mergeJSON.py
index 029787a315..8e2ea322dc 100644
--- a/third_party/nixpkgs/nixos/lib/make-options-doc/mergeJSON.py
+++ b/third_party/nixpkgs/nixos/lib/make-options-doc/mergeJSON.py
@@ -66,14 +66,21 @@ for (k, v) in overrides.items():
elif ov is not None or cur.get(ok, None) is None:
cur[ok] = ov
+severity = "error" if warningsAreErrors else "warning"
+
# check that every option has a description
hasWarnings = False
for (k, v) in options.items():
if v.value.get('description', None) is None:
- severity = "error" if warningsAreErrors else "warning"
hasWarnings = True
print(f"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys.stderr)
v.value['description'] = "This option has no description."
+ if v.value.get('type', "unspecified") == "unspecified":
+ hasWarnings = True
+ print(
+ f"\x1b[1;31m{severity}: option {v.name} has no type. Please specify a valid type, see " +
+ "https://nixos.org/manual/nixos/stable/index.html#sec-option-types\x1b[0m", file=sys.stderr)
+
if hasWarnings and warningsAreErrors:
print(
"\x1b[1;31m" +
diff --git a/third_party/nixpkgs/nixos/lib/systemd-lib.nix b/third_party/nixpkgs/nixos/lib/systemd-lib.nix
index ab166d7327..37900b0b16 100644
--- a/third_party/nixpkgs/nixos/lib/systemd-lib.nix
+++ b/third_party/nixpkgs/nixos/lib/systemd-lib.nix
@@ -5,6 +5,7 @@ with lib;
let
cfg = config.systemd;
lndir = "${pkgs.buildPackages.xorg.lndir}/bin/lndir";
+ systemd = cfg.package;
in rec {
shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s);
@@ -22,8 +23,9 @@ in rec {
inherit (unit) text;
}
''
- mkdir -p $out
- echo -n "$text" > $out/${shellEscape name}
+ name=${shellEscape name}
+ mkdir -p "$out/$(dirname "$name")"
+ echo -n "$text" > "$out/$name"
''
else
pkgs.runCommand "unit-${mkPathSafeName name}-disabled"
@@ -31,8 +33,9 @@ in rec {
allowSubstitutes = false;
}
''
- mkdir -p $out
- ln -s /dev/null $out/${shellEscape name}
+ name=${shellEscape name}
+ mkdir -p "$out/$(dirname "$name")"
+ ln -s /dev/null "$out/$name"
'';
boolValues = [true false "yes" "no"];
@@ -235,4 +238,205 @@ in rec {
''}
''; # */
+ makeJobScript = name: text:
+ let
+ scriptName = replaceChars [ "\\" "@" ] [ "-" "_" ] (shellEscape name);
+ out = (pkgs.writeShellScriptBin scriptName ''
+ set -e
+ ${text}
+ '').overrideAttrs (_: {
+ # The derivation name is different from the script file name
+ # to keep the script file name short to avoid cluttering logs.
+ name = "unit-script-${scriptName}";
+ });
+ in "${out}/bin/${scriptName}";
+
+ unitConfig = { config, options, ... }: {
+ config = {
+ unitConfig =
+ optionalAttrs (config.requires != [])
+ { Requires = toString config.requires; }
+ // optionalAttrs (config.wants != [])
+ { Wants = toString config.wants; }
+ // optionalAttrs (config.after != [])
+ { After = toString config.after; }
+ // optionalAttrs (config.before != [])
+ { Before = toString config.before; }
+ // optionalAttrs (config.bindsTo != [])
+ { BindsTo = toString config.bindsTo; }
+ // optionalAttrs (config.partOf != [])
+ { PartOf = toString config.partOf; }
+ // optionalAttrs (config.conflicts != [])
+ { Conflicts = toString config.conflicts; }
+ // optionalAttrs (config.requisite != [])
+ { Requisite = toString config.requisite; }
+ // optionalAttrs (config.restartTriggers != [])
+ { X-Restart-Triggers = toString config.restartTriggers; }
+ // optionalAttrs (config.reloadTriggers != [])
+ { X-Reload-Triggers = toString config.reloadTriggers; }
+ // optionalAttrs (config.description != "") {
+ Description = config.description; }
+ // optionalAttrs (config.documentation != []) {
+ Documentation = toString config.documentation; }
+ // optionalAttrs (config.onFailure != []) {
+ OnFailure = toString config.onFailure; }
+ // optionalAttrs (options.startLimitIntervalSec.isDefined) {
+ StartLimitIntervalSec = toString config.startLimitIntervalSec;
+ } // optionalAttrs (options.startLimitBurst.isDefined) {
+ StartLimitBurst = toString config.startLimitBurst;
+ };
+ };
+ };
+
+ serviceConfig = { name, config, ... }: {
+ config = mkMerge
+ [ { # Default path for systemd services. Should be quite minimal.
+ path = mkAfter
+ [ pkgs.coreutils
+ pkgs.findutils
+ pkgs.gnugrep
+ pkgs.gnused
+ systemd
+ ];
+ environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
+ }
+ (mkIf (config.preStart != "")
+ { serviceConfig.ExecStartPre =
+ [ (makeJobScript "${name}-pre-start" config.preStart) ];
+ })
+ (mkIf (config.script != "")
+ { serviceConfig.ExecStart =
+ makeJobScript "${name}-start" config.script + " " + config.scriptArgs;
+ })
+ (mkIf (config.postStart != "")
+ { serviceConfig.ExecStartPost =
+ [ (makeJobScript "${name}-post-start" config.postStart) ];
+ })
+ (mkIf (config.reload != "")
+ { serviceConfig.ExecReload =
+ makeJobScript "${name}-reload" config.reload;
+ })
+ (mkIf (config.preStop != "")
+ { serviceConfig.ExecStop =
+ makeJobScript "${name}-pre-stop" config.preStop;
+ })
+ (mkIf (config.postStop != "")
+ { serviceConfig.ExecStopPost =
+ makeJobScript "${name}-post-stop" config.postStop;
+ })
+ ];
+ };
+
+ mountConfig = { config, ... }: {
+ config = {
+ mountConfig =
+ { What = config.what;
+ Where = config.where;
+ } // optionalAttrs (config.type != "") {
+ Type = config.type;
+ } // optionalAttrs (config.options != "") {
+ Options = config.options;
+ };
+ };
+ };
+
+ automountConfig = { config, ... }: {
+ config = {
+ automountConfig =
+ { Where = config.where;
+ };
+ };
+ };
+
+ commonUnitText = def: ''
+ [Unit]
+ ${attrsToSection def.unitConfig}
+ '';
+
+ targetToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text =
+ ''
+ [Unit]
+ ${attrsToSection def.unitConfig}
+ '';
+ };
+
+ serviceToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text = commonUnitText def +
+ ''
+ [Service]
+ ${let env = cfg.globalEnvironment // def.environment;
+ in concatMapStrings (n:
+ let s = optionalString (env.${n} != null)
+ "Environment=${builtins.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)}
+ ${if def.reloadIfChanged then ''
+ X-ReloadIfChanged=true
+ '' else if !def.restartIfChanged then ''
+ X-RestartIfChanged=false
+ '' else ""}
+ ${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
+ ${attrsToSection def.serviceConfig}
+ '';
+ };
+
+ socketToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text = commonUnitText def +
+ ''
+ [Socket]
+ ${attrsToSection def.socketConfig}
+ ${concatStringsSep "\n" (map (s: "ListenStream=${s}") def.listenStreams)}
+ ${concatStringsSep "\n" (map (s: "ListenDatagram=${s}") def.listenDatagrams)}
+ '';
+ };
+
+ timerToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text = commonUnitText def +
+ ''
+ [Timer]
+ ${attrsToSection def.timerConfig}
+ '';
+ };
+
+ pathToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text = commonUnitText def +
+ ''
+ [Path]
+ ${attrsToSection def.pathConfig}
+ '';
+ };
+
+ mountToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text = commonUnitText def +
+ ''
+ [Mount]
+ ${attrsToSection def.mountConfig}
+ '';
+ };
+
+ automountToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text = commonUnitText def +
+ ''
+ [Automount]
+ ${attrsToSection def.automountConfig}
+ '';
+ };
+
+ sliceToUnit = name: def:
+ { inherit (def) aliases wantedBy requiredBy enable;
+ text = commonUnitText def +
+ ''
+ [Slice]
+ ${attrsToSection def.sliceConfig}
+ '';
+ };
}
diff --git a/third_party/nixpkgs/nixos/lib/test-driver/test_driver/driver.py b/third_party/nixpkgs/nixos/lib/test-driver/test_driver/driver.py
index 880b1c5fde..0e5f013193 100644
--- a/third_party/nixpkgs/nixos/lib/test-driver/test_driver/driver.py
+++ b/third_party/nixpkgs/nixos/lib/test-driver/test_driver/driver.py
@@ -55,6 +55,7 @@ class Driver:
tmp_dir = get_tmp_dir()
with rootlog.nested("start all VLans"):
+ vlans = list(set(vlans))
self.vlans = [VLan(nr, tmp_dir) for nr in vlans]
def cmd(scripts: List[str]) -> Iterator[NixStartScript]:
diff --git a/third_party/nixpkgs/nixos/lib/test-driver/test_driver/machine.py b/third_party/nixpkgs/nixos/lib/test-driver/test_driver/machine.py
index 569a0f3c61..f3e615fe5b 100644
--- a/third_party/nixpkgs/nixos/lib/test-driver/test_driver/machine.py
+++ b/third_party/nixpkgs/nixos/lib/test-driver/test_driver/machine.py
@@ -198,7 +198,7 @@ class StartCommand:
) -> subprocess.Popen:
return subprocess.Popen(
self.cmd(monitor_socket_path, shell_socket_path),
- stdin=subprocess.DEVNULL,
+ stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
@@ -558,6 +558,28 @@ class Machine:
pass_fds=[self.shell.fileno()],
)
+ def console_interact(self) -> None:
+ """Allows you to interact with QEMU's stdin
+
+ The shell can be exited with Ctrl+D. Note that Ctrl+C is not allowed to be used.
+ QEMU's stdout is read line-wise.
+
+ Should only be used during test development, not in the production test."""
+ self.log("Terminal is ready (there is no prompt):")
+
+ assert self.process
+ assert self.process.stdin
+
+ while True:
+ try:
+ char = sys.stdin.buffer.read(1)
+ except KeyboardInterrupt:
+ break
+ if char == b"": # ctrl+d
+ self.log("Closing connection to the console")
+ break
+ self.send_console(char.decode())
+
def succeed(self, *commands: str, timeout: Optional[int] = None) -> str:
"""Execute each command and check that it succeeds."""
output = ""
@@ -834,6 +856,12 @@ class Machine:
self.send_monitor_command("sendkey {}".format(key))
time.sleep(0.01)
+ def send_console(self, chars: str) -> None:
+ assert self.process
+ assert self.process.stdin
+ self.process.stdin.write(chars.encode())
+ self.process.stdin.flush()
+
def start(self) -> None:
if self.booted:
return
diff --git a/third_party/nixpkgs/nixos/lib/testing-python.nix b/third_party/nixpkgs/nixos/lib/testing-python.nix
index 0d3c3a89e7..facc7a253a 100644
--- a/third_party/nixpkgs/nixos/lib/testing-python.nix
+++ b/third_party/nixpkgs/nixos/lib/testing-python.nix
@@ -146,26 +146,28 @@ rec {
# Make a full-blown test
makeTest =
- { testScript
+ { machine ? null
+ , nodes ? {}
+ , testScript
, enableOCR ? false
, name ? "unnamed"
# Skip linting (mainly intended for faster dev cycles)
, skipLint ? false
, passthru ? {}
+ , meta ? {}
, # For meta.position
pos ? # position used in error messages and for meta.position
- (if t.meta.description or null != null
- then builtins.unsafeGetAttrPos "description" t.meta
+ (if meta.description or null != null
+ then builtins.unsafeGetAttrPos "description" meta
else builtins.unsafeGetAttrPos "testScript" t)
- , ...
} @ t:
let
- nodes = qemu_pkg:
+ mkNodes = qemu_pkg:
let
testScript' =
# Call the test script with the computed nodes.
if lib.isFunction testScript
- then testScript { nodes = nodes qemu_pkg; }
+ then testScript { nodes = mkNodes qemu_pkg; }
else testScript;
build-vms = import ./build-vms.nix {
@@ -205,33 +207,29 @@ rec {
};
in
build-vms.buildVirtualNetwork (
- t.nodes or (if t ? machine then { machine = t.machine; } else { })
+ nodes // lib.optionalAttrs (machine != null) { inherit machine; }
);
driver = setupDriverForTest {
inherit testScript enableOCR skipLint passthru;
testName = name;
qemu_pkg = pkgs.qemu_test;
- nodes = nodes pkgs.qemu_test;
+ nodes = mkNodes pkgs.qemu_test;
};
driverInteractive = setupDriverForTest {
inherit testScript enableOCR skipLint passthru;
testName = name;
qemu_pkg = pkgs.qemu;
- nodes = nodes pkgs.qemu;
+ nodes = mkNodes pkgs.qemu;
interactive = true;
};
- test =
- let
- passMeta = drv: drv // lib.optionalAttrs (t ? meta) {
- meta = (drv.meta or { }) // t.meta;
- };
- in passMeta (runTests { inherit driver pos driverInteractive; });
+ test = lib.addMetaAttrs meta (runTests { inherit driver pos driverInteractive; });
in
test // {
- inherit test driver driverInteractive nodes;
+ inherit test driver driverInteractive;
+ inherit (driver) nodes;
};
abortForFunction = functionName: abort ''The ${functionName} function was
diff --git a/third_party/nixpkgs/nixos/lib/utils.nix b/third_party/nixpkgs/nixos/lib/utils.nix
index 733f9ca522..ae68c3920c 100644
--- a/third_party/nixpkgs/nixos/lib/utils.nix
+++ b/third_party/nixpkgs/nixos/lib/utils.nix
@@ -45,6 +45,26 @@ rec {
replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"]
(removePrefix "/" s);
+ # Quotes an argument for use in Exec* service lines.
+ # systemd accepts "-quoted strings with escape sequences, toJSON produces
+ # a subset of these.
+ # Additionally we escape % to disallow expansion of % specifiers. Any lone ;
+ # in the input will be turned it ";" and thus lose its special meaning.
+ # Every $ is escaped to $$, this makes it unnecessary to disable environment
+ # substitution for the directive.
+ escapeSystemdExecArg = arg:
+ let
+ s = if builtins.isPath arg then "${arg}"
+ else if builtins.isString arg then arg
+ else if builtins.isInt arg || builtins.isFloat arg then toString arg
+ else throw "escapeSystemdExecArg only allows strings, paths and numbers";
+ in
+ replaceChars [ "%" "$" ] [ "%%" "$$" ] (builtins.toJSON s);
+
+ # Quotes a list of arguments into a single string for use in a Exec*
+ # line.
+ escapeSystemdExecArgs = concatMapStringsSep " " escapeSystemdExecArg;
+
# Returns a system path for a given shell package
toShellPath = shell:
if types.shellPackage.check shell then
diff --git a/third_party/nixpkgs/nixos/modules/config/fonts/fonts.nix b/third_party/nixpkgs/nixos/modules/config/fonts/fonts.nix
index 04952898cb..adc6654afc 100644
--- a/third_party/nixpkgs/nixos/modules/config/fonts/fonts.nix
+++ b/third_party/nixpkgs/nixos/modules/config/fonts/fonts.nix
@@ -39,11 +39,6 @@ let
defaultXFonts =
[ (if hasHidpi then fontcursormisc_hidpi else pkgs.xorg.fontcursormisc)
pkgs.xorg.fontmiscmisc
- ] ++ optionals (config.nixpkgs.config.allowUnfree or false)
- [ # these are unfree, and will make usage with xserver fail
- pkgs.xorg.fontbhlucidatypewriter100dpi
- pkgs.xorg.fontbhlucidatypewriter75dpi
- pkgs.xorg.fontbh100dpi
];
in
diff --git a/third_party/nixpkgs/nixos/modules/config/resolvconf.nix b/third_party/nixpkgs/nixos/modules/config/resolvconf.nix
index cd0ed49138..4499481811 100644
--- a/third_party/nixpkgs/nixos/modules/config/resolvconf.nix
+++ b/third_party/nixpkgs/nixos/modules/config/resolvconf.nix
@@ -47,8 +47,8 @@ in
enable = mkOption {
type = types.bool;
- default = false;
- internal = true;
+ default = !(config.environment.etc ? "resolv.conf");
+ defaultText = literalExpression ''!(config.environment.etc ? "resolv.conf")'';
description = ''
DNS configuration is managed by resolvconf.
'';
@@ -110,8 +110,6 @@ in
config = mkMerge [
{
- networking.resolvconf.enable = !(config.environment.etc ? "resolv.conf");
-
environment.etc."resolvconf.conf".text =
if !cfg.enable then
# Force-stop any attempts to use resolvconf
diff --git a/third_party/nixpkgs/nixos/modules/hardware/video/nvidia.nix b/third_party/nixpkgs/nixos/modules/hardware/video/nvidia.nix
index b19ea614c8..8ebbbc634e 100644
--- a/third_party/nixpkgs/nixos/modules/hardware/video/nvidia.nix
+++ b/third_party/nixpkgs/nixos/modules/hardware/video/nvidia.nix
@@ -244,7 +244,7 @@ in
modules = optional (igpuDriver == "amdgpu") [ pkgs.xorg.xf86videoamdgpu ];
deviceSection = ''
BusID "${igpuBusId}"
- ${optionalString syncCfg.enable ''Option "AccelMethod" "none"''}
+ ${optionalString (syncCfg.enable && igpuDriver != "amdgpu") ''Option "AccelMethod" "none"''}
'';
} ++ singleton {
name = "nvidia";
@@ -270,9 +270,15 @@ in
Option "AllowNVIDIAGPUScreens"
'';
- services.xserver.displayManager.setupCommands = optionalString syncCfg.enable ''
+ services.xserver.displayManager.setupCommands = let
+ sinkGpuProviderName = if igpuDriver == "amdgpu" then
+ # find the name of the provider if amdgpu
+ "`${pkgs.xorg.xrandr}/bin/xrandr --listproviders | ${pkgs.gnugrep}/bin/grep -i AMD | ${pkgs.gnused}/bin/sed -n 's/^.*name://p'`"
+ else
+ igpuDriver;
+ in optionalString syncCfg.enable ''
# Added by nvidia configuration module for Optimus/PRIME.
- ${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource ${igpuDriver} NVIDIA-0
+ ${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource "${sinkGpuProviderName}" NVIDIA-0
${pkgs.xorg.xrandr}/bin/xrandr --auto
'';
@@ -284,10 +290,14 @@ in
environment.etc."egl/egl_external_platform.d".source =
"/run/opengl-driver/share/egl/egl_external_platform.d/";
- hardware.opengl.package = mkIf (!offloadCfg.enable) nvidia_x11.out;
- hardware.opengl.package32 = mkIf (!offloadCfg.enable) nvidia_x11.lib32;
- hardware.opengl.extraPackages = optional offloadCfg.enable nvidia_x11.out;
- hardware.opengl.extraPackages32 = optional offloadCfg.enable nvidia_x11.lib32;
+ hardware.opengl.extraPackages = [
+ nvidia_x11.out
+ pkgs.nvidia-vaapi-driver
+ ];
+ hardware.opengl.extraPackages32 = [
+ nvidia_x11.lib32
+ pkgs.pkgsi686Linux.nvidia-vaapi-driver
+ ];
environment.systemPackages = [ nvidia_x11.bin ]
++ optionals cfg.nvidiaSettings [ nvidia_x11.settings ]
diff --git a/third_party/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix b/third_party/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
index 3ff1b3d670..860e240b43 100644
--- a/third_party/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
+++ b/third_party/nixpkgs/nixos/modules/installer/cd-dvd/iso-image.nix
@@ -91,29 +91,9 @@ let
SERIAL 0 115200
TIMEOUT ${builtins.toString syslinuxTimeout}
UI vesamenu.c32
- MENU TITLE NixOS
MENU BACKGROUND /isolinux/background.png
- MENU RESOLUTION 800 600
- MENU CLEAR
- MENU ROWS 6
- MENU CMDLINEROW -4
- MENU TIMEOUTROW -3
- MENU TABMSGROW -2
- MENU HELPMSGROW -1
- MENU HELPMSGENDROW -1
- MENU MARGIN 0
- # FG:AARRGGBB BG:AARRGGBB shadow
- MENU COLOR BORDER 30;44 #00000000 #00000000 none
- MENU COLOR SCREEN 37;40 #FF000000 #00E2E8FF none
- MENU COLOR TABMSG 31;40 #80000000 #00000000 none
- MENU COLOR TIMEOUT 1;37;40 #FF000000 #00000000 none
- MENU COLOR TIMEOUT_MSG 37;40 #FF000000 #00000000 none
- MENU COLOR CMDMARK 1;36;40 #FF000000 #00000000 none
- MENU COLOR CMDLINE 37;40 #FF000000 #00000000 none
- MENU COLOR TITLE 1;36;44 #00000000 #00000000 none
- MENU COLOR UNSEL 37;44 #FF000000 #00000000 none
- MENU COLOR SEL 7;37;40 #FFFFFFFF #FF5277C3 std
+ ${config.isoImage.syslinuxTheme}
DEFAULT boot
@@ -601,6 +581,37 @@ in
'';
};
+ isoImage.syslinuxTheme = mkOption {
+ default = ''
+ MENU TITLE NixOS
+ MENU RESOLUTION 800 600
+ MENU CLEAR
+ MENU ROWS 6
+ MENU CMDLINEROW -4
+ MENU TIMEOUTROW -3
+ MENU TABMSGROW -2
+ MENU HELPMSGROW -1
+ MENU HELPMSGENDROW -1
+ MENU MARGIN 0
+
+ # FG:AARRGGBB BG:AARRGGBB shadow
+ MENU COLOR BORDER 30;44 #00000000 #00000000 none
+ MENU COLOR SCREEN 37;40 #FF000000 #00E2E8FF none
+ MENU COLOR TABMSG 31;40 #80000000 #00000000 none
+ MENU COLOR TIMEOUT 1;37;40 #FF000000 #00000000 none
+ MENU COLOR TIMEOUT_MSG 37;40 #FF000000 #00000000 none
+ MENU COLOR CMDMARK 1;36;40 #FF000000 #00000000 none
+ MENU COLOR CMDLINE 37;40 #FF000000 #00000000 none
+ MENU COLOR TITLE 1;36;44 #00000000 #00000000 none
+ MENU COLOR UNSEL 37;44 #FF000000 #00000000 none
+ MENU COLOR SEL 7;37;40 #FFFFFFFF #FF5277C3 std
+ '';
+ type = types.str;
+ description = ''
+ The syslinux theme used for BIOS boot.
+ '';
+ };
+
isoImage.appendToMenuLabel = mkOption {
default = " Installer";
example = " Live System";
diff --git a/third_party/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh b/third_party/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
index 115b3d7a7c..89beeee7cf 100644
--- a/third_party/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
+++ b/third_party/nixpkgs/nixos/modules/installer/tools/nixos-enter.sh
@@ -63,32 +63,32 @@ mount --rbind /sys "$mountPoint/sys"
# modified from https://github.com/archlinux/arch-install-scripts/blob/bb04ab435a5a89cd5e5ee821783477bc80db797f/arch-chroot.in#L26-L52
chroot_add_resolv_conf() {
- local chrootdir=$1 resolv_conf=$1/etc/resolv.conf
+ local chrootDir="$1" resolvConf="$1/etc/resolv.conf"
[[ -e /etc/resolv.conf ]] || return 0
# Handle resolv.conf as a symlink to somewhere else.
- if [[ -L $chrootdir/etc/resolv.conf ]]; then
+ if [[ -L "$resolvConf" ]]; then
# readlink(1) should always give us *something* since we know at this point
# it's a symlink. For simplicity, ignore the case of nested symlinks.
- # We also ignore the possibility if `../`s escaping the root.
- resolv_conf=$(readlink "$chrootdir/etc/resolv.conf")
- if [[ $resolv_conf = /* ]]; then
- resolv_conf=$chrootdir$resolv_conf
+ # We also ignore the possibility of `../`s escaping the root.
+ resolvConf="$(readlink "$resolvConf")"
+ if [[ "$resolvConf" = /* ]]; then
+ resolvConf="$chrootDir$resolvConf"
else
- resolv_conf=$chrootdir/etc/$resolv_conf
+ resolvConf="$chrootDir/etc/$resolvConf"
fi
fi
# ensure file exists to bind mount over
- if [[ ! -f $resolv_conf ]]; then
- install -Dm644 /dev/null "$resolv_conf" || return 1
+ if [[ ! -f "$resolvConf" ]]; then
+ install -Dm644 /dev/null "$resolvConf" || return 1
fi
- mount --bind /etc/resolv.conf "$resolv_conf"
+ mount --bind /etc/resolv.conf "$resolvConf"
}
-chroot_add_resolv_conf "$mountPoint" || print "ERROR: failed to set up resolv.conf"
+chroot_add_resolv_conf "$mountPoint" || echo "$0: failed to set up resolv.conf" >&2
(
# If silent, write both stdout and stderr of activation script to /dev/null
diff --git a/third_party/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl b/third_party/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
index 57aef50a0f..fb5d3ba473 100644
--- a/third_party/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
+++ b/third_party/nixpkgs/nixos/modules/installer/tools/nixos-generate-config.pl
@@ -51,7 +51,9 @@ for (my $n = 0; $n < scalar @ARGV; $n++) {
$n++;
$rootDir = $ARGV[$n];
die "$0: ‘--root’ requires an argument\n" unless defined $rootDir;
+ die "$0: no need to specify `/` with `--root`, it is the default\n" if $rootDir eq "/";
$rootDir =~ s/\/*$//; # remove trailing slashes
+ $rootDir = File::Spec->rel2abs($rootDir); # resolve absolute path
}
elsif ($arg eq "--force") {
$force = 1;
@@ -616,7 +618,12 @@ EOF
if ($showHardwareConfig) {
print STDOUT $hwConfig;
} else {
- $outDir = "$rootDir$outDir";
+ if ($outDir eq "/etc/nixos") {
+ $outDir = "$rootDir$outDir";
+ } else {
+ $outDir = File::Spec->rel2abs($outDir);
+ $outDir =~ s/\/*$//; # remove trailing slashes
+ }
my $fn = "$outDir/hardware-configuration.nix";
print STDERR "writing $fn...\n";
diff --git a/third_party/nixpkgs/nixos/modules/installer/tools/tools.nix b/third_party/nixpkgs/nixos/modules/installer/tools/tools.nix
index 71aaf7f253..2e088b9777 100644
--- a/third_party/nixpkgs/nixos/modules/installer/tools/tools.nix
+++ b/third_party/nixpkgs/nixos/modules/installer/tools/tools.nix
@@ -117,7 +117,7 @@ in
'';
};
- config = lib.mkIf (!config.system.disableInstallerTools) {
+ config = lib.mkIf (config.nix.enable && !config.system.disableInstallerTools) {
system.nixos-generate-config.configuration = mkDefault ''
# Edit this configuration file to define what should be installed on
diff --git a/third_party/nixpkgs/nixos/modules/misc/locate.nix b/third_party/nixpkgs/nixos/modules/misc/locate.nix
index 66a49b0b88..204a891430 100644
--- a/third_party/nixpkgs/nixos/modules/misc/locate.nix
+++ b/third_party/nixpkgs/nixos/modules/misc/locate.nix
@@ -183,7 +183,11 @@ in
pruneNames = mkOption {
type = listOf str;
- default = [ ".bzr" ".cache" ".git" ".hg" ".svn" ];
+ default = lib.optionals (!isFindutils) [ ".bzr" ".cache" ".git" ".hg" ".svn" ];
+ defaultText = literalDocBook ''
+ [ ".bzr" ".cache" ".git" ".hg" ".svn" ], if
+ supported by the locate implementation (i.e. mlocate or plocate).
+ '';
description = ''
Directory components which should exclude paths containing them from indexing
'';
diff --git a/third_party/nixpkgs/nixos/modules/misc/version.nix b/third_party/nixpkgs/nixos/modules/misc/version.nix
index 6c072021ed..d825f4beb3 100644
--- a/third_party/nixpkgs/nixos/modules/misc/version.nix
+++ b/third_party/nixpkgs/nixos/modules/misc/version.nix
@@ -8,8 +8,12 @@ let
concatStringsSep mapAttrsToList toLower
literalExpression mkRenamedOptionModule mkDefault mkOption trivial types;
+ needsEscaping = s: null != builtins.match "[a-zA-Z0-9]+" s;
+ escapeIfNeccessary = s: if needsEscaping s then s else ''"${lib.escape [ "\$" "\"" "\\" "\`" ] s}"'';
attrsToText = attrs:
- concatStringsSep "\n" (mapAttrsToList (n: v: ''${n}="${toString v}"'') attrs);
+ concatStringsSep "\n" (
+ mapAttrsToList (n: v: ''${n}=${escapeIfNeccessary (toString v)}'') attrs
+ );
in
{
diff --git a/third_party/nixpkgs/nixos/modules/module-list.nix b/third_party/nixpkgs/nixos/modules/module-list.nix
index 6430993d5c..adeddbf139 100644
--- a/third_party/nixpkgs/nixos/modules/module-list.nix
+++ b/third_party/nixpkgs/nixos/modules/module-list.nix
@@ -118,6 +118,8 @@
./misc/version.nix
./misc/wordlist.nix
./misc/nixops-autoluks.nix
+ ./programs/_1password.nix
+ ./programs/_1password-gui.nix
./programs/adb.nix
./programs/appgate-sdp.nix
./programs/atop.nix
@@ -180,8 +182,11 @@
./programs/msmtp.nix
./programs/mtr.nix
./programs/nano.nix
+ ./programs/nbd.nix
+ ./programs/nix-ld.nix
./programs/neovim.nix
./programs/nm-applet.nix
+ ./programs/nncp.nix
./programs/npm.nix
./programs/noisetorch.nix
./programs/oblogout.nix
@@ -301,6 +306,7 @@
./services/backup/znapzend.nix
./services/blockchain/ethereum/geth.nix
./services/backup/zrepl.nix
+ ./services/cluster/corosync/default.nix
./services/cluster/hadoop/default.nix
./services/cluster/k3s/default.nix
./services/cluster/kubernetes/addons/dns.nix
@@ -313,6 +319,7 @@
./services/cluster/kubernetes/pki.nix
./services/cluster/kubernetes/proxy.nix
./services/cluster/kubernetes/scheduler.nix
+ ./services/cluster/pacemaker/default.nix
./services/cluster/spark/default.nix
./services/computing/boinc/client.nix
./services/computing/foldingathome/client.nix
@@ -773,6 +780,7 @@
./services/networking/headscale.nix
./services/networking/hostapd.nix
./services/networking/htpdate.nix
+ ./services/networking/https-dns-proxy.nix
./services/networking/hylafax/default.nix
./services/networking/i2pd.nix
./services/networking/i2p.nix
@@ -819,6 +827,7 @@
./services/networking/nar-serve.nix
./services/networking/nat.nix
./services/networking/nats.nix
+ ./services/networking/nbd.nix
./services/networking/ndppd.nix
./services/networking/nebula.nix
./services/networking/networkmanager.nix
@@ -985,6 +994,7 @@
./services/system/nscd.nix
./services/system/saslauthd.nix
./services/system/self-deploy.nix
+ ./services/system/systembus-notify.nix
./services/system/uptimed.nix
./services/torrent/deluge.nix
./services/torrent/flexget.nix
@@ -1163,7 +1173,12 @@
./system/boot/stage-1.nix
./system/boot/stage-2.nix
./system/boot/systemd.nix
- ./system/boot/systemd-nspawn.nix
+ ./system/boot/systemd/coredump.nix
+ ./system/boot/systemd/journald.nix
+ ./system/boot/systemd/logind.nix
+ ./system/boot/systemd/nspawn.nix
+ ./system/boot/systemd/tmpfiles.nix
+ ./system/boot/systemd/user.nix
./system/boot/timesyncd.nix
./system/boot/tmp.nix
./system/etc/etc-activation.nix
diff --git a/third_party/nixpkgs/nixos/modules/programs/_1password-gui.nix b/third_party/nixpkgs/nixos/modules/programs/_1password-gui.nix
new file mode 100644
index 0000000000..f57de44bb9
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/programs/_1password-gui.nix
@@ -0,0 +1,69 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.programs._1password-gui;
+
+in {
+ options = {
+ programs._1password-gui = {
+ enable = mkEnableOption "The 1Password Desktop application with browser integration";
+
+ groupId = mkOption {
+ type = types.int;
+ example = literalExpression "5000";
+ description = ''
+ The GroupID to assign to the onepassword group, which is needed for browser integration. The group ID must be 1000 or greater.
+ '';
+ };
+
+ polkitPolicyOwners = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = literalExpression "[\"user1\" \"user2\" \"user3\"]";
+ description = ''
+ A list of users who should be able to integrate 1Password with polkit-based authentication mechanisms. By default, no users will have such access.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs._1password-gui;
+ defaultText = literalExpression "pkgs._1password-gui";
+ example = literalExpression "pkgs._1password-gui";
+ description = ''
+ The 1Password derivation to use. This can be used to upgrade from the stable release that we keep in nixpkgs to the betas.
+ '';
+ };
+ };
+ };
+
+ config = let
+ package = cfg.package.override {
+ polkitPolicyOwners = cfg.polkitPolicyOwners;
+ };
+ in mkIf cfg.enable {
+ environment.systemPackages = [ package ];
+ users.groups.onepassword.gid = cfg.groupId;
+
+ security.wrappers = {
+ "1Password-BrowserSupport" =
+ { source = "${cfg.package}/share/1password/1Password-BrowserSupport";
+ owner = "root";
+ group = "onepassword";
+ setuid = false;
+ setgid = true;
+ };
+
+ "1Password-KeyringHelper" =
+ { source = "${cfg.package}/share/1password/1Password-KeyringHelper";
+ owner = "root";
+ group = "onepassword";
+ setuid = true;
+ setgid = true;
+ };
+ };
+
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/programs/_1password.nix b/third_party/nixpkgs/nixos/modules/programs/_1password.nix
new file mode 100644
index 0000000000..eae518e61c
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/programs/_1password.nix
@@ -0,0 +1,46 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+ cfg = config.programs._1password;
+in {
+ options = {
+ programs._1password = {
+ enable = mkEnableOption "The 1Password CLI tool with biometric unlock and integration with the 1Password GUI.";
+
+ groupId = mkOption {
+ type = types.int;
+ example = literalExpression "5001";
+ description = ''
+ The GroupID to assign to the onepassword-cli group, which is needed for integration with the 1Password GUI. The group ID must be 1000 or greater.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs._1password;
+ defaultText = literalExpression "pkgs._1password";
+ example = literalExpression "pkgs._1password";
+ description = ''
+ The 1Password CLI derivation to use.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ cfg.package ];
+ users.groups.onepassword-cli.gid = cfg.groupId;
+
+ security.wrappers = {
+ "op" = {
+ source = "${cfg.package}/bin/op";
+ owner = "root";
+ group = "onepassword-cli";
+ setuid = false;
+ setgid = true;
+ };
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/programs/captive-browser.nix b/third_party/nixpkgs/nixos/modules/programs/captive-browser.nix
index dc054504ea..aad554c2bd 100644
--- a/third_party/nixpkgs/nixos/modules/programs/captive-browser.nix
+++ b/third_party/nixpkgs/nixos/modules/programs/captive-browser.nix
@@ -1,8 +1,12 @@
{ config, lib, pkgs, ... }:
-with lib;
let
cfg = config.programs.captive-browser;
+
+ inherit (lib)
+ concatStringsSep escapeShellArgs optionalString
+ literalExpression mkEnableOption mkIf mkOption mkOptionDefault types;
+
browserDefault = chromium: concatStringsSep " " [
''env XDG_CONFIG_HOME="$PREV_CONFIG_HOME"''
''${chromium}/bin/chromium''
@@ -15,6 +19,15 @@ let
''-no-default-browser-check''
''http://cache.nixos.org/''
];
+
+ desktopItem = pkgs.makeDesktopItem {
+ name = "captive-browser";
+ desktopName = "Captive Portal Browser";
+ exec = "/run/wrappers/bin/captive-browser";
+ icon = "nix-snowflake";
+ categories = [ "Network" ];
+ };
+
in
{
###### interface
@@ -84,6 +97,11 @@ in
###### implementation
config = mkIf cfg.enable {
+ environment.systemPackages = [
+ (pkgs.runCommandNoCC "captive-browser-desktop-item" { } ''
+ install -Dm444 -t $out/share/applications ${desktopItem}/share/applications/*.desktop
+ '')
+ ];
programs.captive-browser.dhcp-dns =
let
diff --git a/third_party/nixpkgs/nixos/modules/programs/environment.nix b/third_party/nixpkgs/nixos/modules/programs/environment.nix
index d552c751af..a448727be7 100644
--- a/third_party/nixpkgs/nixos/modules/programs/environment.nix
+++ b/third_party/nixpkgs/nixos/modules/programs/environment.nix
@@ -40,13 +40,15 @@ in
KDEDIRS = [ "" ];
QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/plugins/" ];
- GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" ];
+ GTK_PATH = [ "/lib/gtk-2.0" "/lib/gtk-3.0" "/lib/gtk-4.0" ];
XDG_CONFIG_DIRS = [ "/etc/xdg" ];
XDG_DATA_DIRS = [ "/share" ];
MOZ_PLUGIN_PATH = [ "/lib/mozilla/plugins" ];
LIBEXEC_PATH = [ "/lib/libexec" ];
};
+ environment.pathsToLink = [ "/lib/gtk-2.0" "/lib/gtk-3.0" "/lib/gtk-4.0" ];
+
environment.extraInit =
''
unset ASPELL_CONF
diff --git a/third_party/nixpkgs/nixos/modules/programs/nbd.nix b/third_party/nixpkgs/nixos/modules/programs/nbd.nix
new file mode 100644
index 0000000000..fea9bc1ff7
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/programs/nbd.nix
@@ -0,0 +1,19 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.programs.nbd;
+in
+{
+ options = {
+ programs.nbd = {
+ enable = mkEnableOption "Network Block Device (nbd) support";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = with pkgs; [ nbd ];
+ boot.kernelModules = [ "nbd" ];
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/programs/nix-ld.nix b/third_party/nixpkgs/nixos/modules/programs/nix-ld.nix
new file mode 100644
index 0000000000..810a74ab50
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/programs/nix-ld.nix
@@ -0,0 +1,12 @@
+{ pkgs, lib, config, ... }:
+{
+ meta.maintainers = [ lib.maintainers.mic92 ];
+ options = {
+ programs.nix-ld.enable = lib.mkEnableOption ''nix-ld, Documentation: '';
+ };
+ config = lib.mkIf config.programs.nix-ld.enable {
+ systemd.tmpfiles.rules = [
+ "L+ ${pkgs.nix-ld.ldPath} - - - - ${pkgs.nix-ld}/libexec/nix-ld"
+ ];
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/programs/nncp.nix b/third_party/nixpkgs/nixos/modules/programs/nncp.nix
new file mode 100644
index 0000000000..29a703eadf
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/programs/nncp.nix
@@ -0,0 +1,101 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ nncpCfgFile = "/run/nncp.hjson";
+ programCfg = config.programs.nncp;
+ settingsFormat = pkgs.formats.json { };
+ jsonCfgFile = settingsFormat.generate "nncp.json" programCfg.settings;
+ pkg = programCfg.package;
+in {
+ options.programs.nncp = {
+
+ enable =
+ mkEnableOption "NNCP (Node to Node copy) utilities and configuration";
+
+ group = mkOption {
+ type = types.str;
+ default = "uucp";
+ description = ''
+ The group under which NNCP files shall be owned.
+ Any member of this group may access the secret keys
+ of this NNCP node.
+ '';
+ };
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.nncp;
+ defaultText = literalExpression "pkgs.nncp";
+ description = "The NNCP package to use system-wide.";
+ };
+
+ secrets = mkOption {
+ type = with types; listOf str;
+ example = [ "/run/keys/nncp.hjson" ];
+ description = ''
+ A list of paths to NNCP configuration files that should not be
+ in the Nix store. These files are layered on top of the values at
+ .
+ '';
+ };
+
+ settings = mkOption {
+ type = settingsFormat.type;
+ description = ''
+ NNCP configuration, see
+ .
+ At runtime these settings will be overlayed by the contents of
+ into the file
+ ${nncpCfgFile}. Node keypairs go in
+ secrets, do not specify them in
+ settings as they will be leaked into
+ /nix/store!
+ '';
+ default = { };
+ };
+
+ };
+
+ config = mkIf programCfg.enable {
+
+ environment = {
+ systemPackages = [ pkg ];
+ etc."nncp.hjson".source = nncpCfgFile;
+ };
+
+ programs.nncp.settings = {
+ spool = mkDefault "/var/spool/nncp";
+ log = mkDefault "/var/spool/nncp/log";
+ };
+
+ systemd.tmpfiles.rules = [
+ "d ${programCfg.settings.spool} 0770 root ${programCfg.group}"
+ "f ${programCfg.settings.log} 0770 root ${programCfg.group}"
+ ];
+
+ systemd.services.nncp-config = {
+ path = [ pkg ];
+ description = "Generate NNCP configuration";
+ wantedBy = [ "basic.target" ];
+ serviceConfig.Type = "oneshot";
+ script = ''
+ umask u=rw
+ nncpCfgDir=$(mktemp --directory nncp.XXX)
+ for f in ${jsonCfgFile} ${toString config.programs.nncp.secrets}; do
+ tmpdir=$(mktemp --directory nncp.XXX)
+ nncp-cfgdir -cfg $f -dump $tmpdir
+ find $tmpdir -size 1c -delete
+ cp -a $tmpdir/* $nncpCfgDir/
+ rm -rf $tmpdir
+ done
+ nncp-cfgdir -load $nncpCfgDir > ${nncpCfgFile}
+ rm -rf $nncpCfgDir
+ chgrp ${programCfg.group} ${nncpCfgFile}
+ chmod g+r ${nncpCfgFile}
+ '';
+ };
+ };
+
+ meta.maintainers = with lib.maintainers; [ ehmry ];
+}
diff --git a/third_party/nixpkgs/nixos/modules/security/pam.nix b/third_party/nixpkgs/nixos/modules/security/pam.nix
index f9697d61f1..c0ef8b5f30 100644
--- a/third_party/nixpkgs/nixos/modules/security/pam.nix
+++ b/third_party/nixpkgs/nixos/modules/security/pam.nix
@@ -61,19 +61,6 @@ let
'';
};
- usshAuth = mkOption {
- default = false;
- type = types.bool;
- description = ''
- If set, users with an SSH certificate containing an authorized principal
- in their SSH agent are able to log in. Specific options are controlled
- using the options.
-
- Note that the must also be
- set for this option to take effect.
- '';
- };
-
yubicoAuth = mkOption {
default = config.security.pam.yubico.enable;
defaultText = literalExpression "config.security.pam.yubico.enable";
@@ -488,9 +475,6 @@ let
optionalString cfg.usbAuth ''
auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so
'' +
- (let ussh = config.security.pam.ussh; in optionalString (config.security.pam.ussh.enable && cfg.usshAuth) ''
- auth ${ussh.control} ${pkgs.pam_ussh}/lib/security/pam_ussh.so ${optionalString (ussh.caFile != null) "ca_file=${ussh.caFile}"} ${optionalString (ussh.authorizedPrincipals != null) "authorized_principals=${ussh.authorizedPrincipals}"} ${optionalString (ussh.authorizedPrincipalsFile != null) "authorized_principals_file=${ussh.authorizedPrincipalsFile}"} ${optionalString (ussh.group != null) "group=${ussh.group}"}
- '') +
(let oath = config.security.pam.oath; in optionalString cfg.oathAuth ''
auth requisite ${pkgs.oathToolkit}/lib/security/pam_oath.so window=${toString oath.window} usersfile=${toString oath.usersFile} digits=${toString oath.digits}
'') +
@@ -942,96 +926,6 @@ in
};
};
- security.pam.ussh = {
- enable = mkOption {
- default = false;
- type = types.bool;
- description = ''
- Enables Uber's USSH PAM (pam-ussh) module.
-
- This is similar to pam-ssh-agent, except that
- the presence of a CA-signed SSH key with a valid principal is checked
- instead.
-
- Note that this module must both be enabled using this option and on a
- per-PAM-service level as well (using usshAuth).
-
- More information can be found here.
- '';
- };
-
- caFile = mkOption {
- default = null;
- type = with types; nullOr path;
- description = ''
- By default pam-ussh reads the trusted user CA keys
- from /etc/ssh/trusted_user_ca.
-
- This should be set the same as your TrustedUserCAKeys
- option for sshd.
- '';
- };
-
- authorizedPrincipals = mkOption {
- default = null;
- type = with types; nullOr commas;
- description = ''
- Comma-separated list of authorized principals to permit; if the user
- presents a certificate with one of these principals, then they will be
- authorized.
-
- Note that pam-ussh also requires that the certificate
- contain a principal matching the user's username. The principals from
- this list are in addition to those principals.
-
- Mutually exclusive with authorizedPrincipalsFile.
- '';
- };
-
- authorizedPrincipalsFile = mkOption {
- default = null;
- type = with types; nullOr path;
- description = ''
- Path to a list of principals; if the user presents a certificate with
- one of these principals, then they will be authorized.
-
- Note that pam-ussh also requires that the certificate
- contain a principal matching the user's username. The principals from
- this file are in addition to those principals.
-
- Mutually exclusive with authorizedPrincipals.
- '';
- };
-
- group = mkOption {
- default = null;
- type = with types; nullOr str;
- description = ''
- If set, then the authenticating user must be a member of this group
- to use this module.
- '';
- };
-
- control = mkOption {
- default = "sufficient";
- type = types.enum [ "required" "requisite" "sufficient" "optional" ];
- description = ''
- This option sets pam "control".
- If you want to have multi factor authentication, use "required".
- If you want to use the SSH certificate instead of the regular password,
- use "sufficient".
-
- Read
-
- pam.conf
- 5
-
- for better understanding of this option.
- '';
- };
- };
-
security.pam.yubico = {
enable = mkOption {
default = false;
@@ -1216,9 +1110,6 @@ in
optionalString (isEnabled (cfg: cfg.usbAuth)) ''
mr ${pkgs.pam_usb}/lib/security/pam_usb.so,
'' +
- optionalString (isEnabled (cfg: cfg.usshAuth)) ''
- mr ${pkgs.pam_ussh}/lib/security/pam_ussh.so,
- '' +
optionalString (isEnabled (cfg: cfg.oathAuth)) ''
"mr ${pkgs.oathToolkit}/lib/security/pam_oath.so,
'' +
diff --git a/third_party/nixpkgs/nixos/modules/security/sudo.nix b/third_party/nixpkgs/nixos/modules/security/sudo.nix
index 4bf239fca8..99e578f8ad 100644
--- a/third_party/nixpkgs/nixos/modules/security/sudo.nix
+++ b/third_party/nixpkgs/nixos/modules/security/sudo.nix
@@ -245,7 +245,7 @@ in
environment.systemPackages = [ sudo ];
- security.pam.services.sudo = { sshAgentAuth = true; usshAuth = true; };
+ security.pam.services.sudo = { sshAgentAuth = true; };
environment.etc.sudoers =
{ source =
diff --git a/third_party/nixpkgs/nixos/modules/services/audio/squeezelite.nix b/third_party/nixpkgs/nixos/modules/services/audio/squeezelite.nix
index 05506f5bcc..36295e21c6 100644
--- a/third_party/nixpkgs/nixos/modules/services/audio/squeezelite.nix
+++ b/third_party/nixpkgs/nixos/modules/services/audio/squeezelite.nix
@@ -1,50 +1,46 @@
{ config, lib, pkgs, ... }:
-with lib;
-
let
+ inherit (lib) mkEnableOption mkIf mkOption optionalString types;
+
dataDir = "/var/lib/squeezelite";
cfg = config.services.squeezelite;
+ pkg = if cfg.pulseAudio then pkgs.squeezelite-pulse else pkgs.squeezelite;
+ bin = "${pkg}/bin/${pkg.pname}";
-in {
+in
+{
###### interface
- options = {
+ options.services.squeezelite = {
+ enable = mkEnableOption "Squeezelite, a software Squeezebox emulator";
- services.squeezelite= {
-
- enable = mkEnableOption "Squeezelite, a software Squeezebox emulator";
-
- extraArguments = mkOption {
- default = "";
- type = types.str;
- description = ''
- Additional command line arguments to pass to Squeezelite.
- '';
- };
+ pulseAudio = mkEnableOption "pulseaudio support";
+ extraArguments = mkOption {
+ default = "";
+ type = types.str;
+ description = ''
+ Additional command line arguments to pass to Squeezelite.
+ '';
};
-
};
###### implementation
config = mkIf cfg.enable {
-
- systemd.services.squeezelite= {
+ systemd.services.squeezelite = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "sound.target" ];
description = "Software Squeezebox emulator";
serviceConfig = {
DynamicUser = true;
- ExecStart = "${pkgs.squeezelite}/bin/squeezelite -N ${dataDir}/player-name ${cfg.extraArguments}";
+ ExecStart = "${bin} -N ${dataDir}/player-name ${cfg.extraArguments}";
StateDirectory = builtins.baseNameOf dataDir;
SupplementaryGroups = "audio";
};
};
-
};
-
}
diff --git a/third_party/nixpkgs/nixos/modules/services/cluster/corosync/default.nix b/third_party/nixpkgs/nixos/modules/services/cluster/corosync/default.nix
new file mode 100644
index 0000000000..b4144917fe
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/cluster/corosync/default.nix
@@ -0,0 +1,112 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.services.corosync;
+in
+{
+ # interface
+ options.services.corosync = {
+ enable = mkEnableOption "corosync";
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.corosync;
+ defaultText = literalExpression "pkgs.corosync";
+ description = "Package that should be used for corosync.";
+ };
+
+ clusterName = mkOption {
+ type = types.str;
+ default = "nixcluster";
+ description = "Name of the corosync cluster.";
+ };
+
+ extraOptions = mkOption {
+ type = with types; listOf str;
+ default = [];
+ description = "Additional options with which to start corosync.";
+ };
+
+ nodelist = mkOption {
+ description = "Corosync nodelist: all cluster members.";
+ default = [];
+ type = with types; listOf (submodule {
+ options = {
+ nodeid = mkOption {
+ type = int;
+ description = "Node ID number";
+ };
+ name = mkOption {
+ type = str;
+ description = "Node name";
+ };
+ ring_addrs = mkOption {
+ type = listOf str;
+ description = "List of addresses, one for each ring.";
+ };
+ };
+ });
+ };
+ };
+
+ # implementation
+ config = mkIf cfg.enable {
+ environment.systemPackages = [ cfg.package ];
+
+ environment.etc."corosync/corosync.conf".text = ''
+ totem {
+ version: 2
+ secauth: on
+ cluster_name: ${cfg.clusterName}
+ transport: knet
+ }
+
+ nodelist {
+ ${concatMapStrings ({ nodeid, name, ring_addrs }: ''
+ node {
+ nodeid: ${toString nodeid}
+ name: ${name}
+ ${concatStrings (imap0 (i: addr: ''
+ ring${toString i}_addr: ${addr}
+ '') ring_addrs)}
+ }
+ '') cfg.nodelist}
+ }
+
+ quorum {
+ # only corosync_votequorum is supported
+ provider: corosync_votequorum
+ wait_for_all: 0
+ ${optionalString (builtins.length cfg.nodelist < 3) ''
+ two_node: 1
+ ''}
+ }
+
+ logging {
+ to_syslog: yes
+ }
+ '';
+
+ environment.etc."corosync/uidgid.d/root".text = ''
+ # allow pacemaker connection by root
+ uidgid {
+ uid: 0
+ gid: 0
+ }
+ '';
+
+ systemd.packages = [ cfg.package ];
+ systemd.services.corosync = {
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ StateDirectory = "corosync";
+ StateDirectoryMode = "0700";
+ };
+ };
+
+ environment.etc."sysconfig/corosync".text = lib.optionalString (cfg.extraOptions != []) ''
+ COROSYNC_OPTIONS="${lib.escapeShellArgs cfg.extraOptions}"
+ '';
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/conf.nix b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/conf.nix
index 0caec5cfc2..e3c26a0d55 100644
--- a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/conf.nix
+++ b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/conf.nix
@@ -1,6 +1,6 @@
{ cfg, pkgs, lib }:
let
- propertyXml = name: value: ''
+ propertyXml = name: value: lib.optionalString (value != null) ''
${name}
${builtins.toString value}
@@ -29,16 +29,16 @@ let
export HADOOP_LOG_DIR=/tmp/hadoop/$USER
'';
in
-pkgs.runCommand "hadoop-conf" {} ''
+pkgs.runCommand "hadoop-conf" {} (with cfg; ''
mkdir -p $out/
- cp ${siteXml "core-site.xml" cfg.coreSite}/* $out/
- cp ${siteXml "hdfs-site.xml" cfg.hdfsSite}/* $out/
- cp ${siteXml "mapred-site.xml" cfg.mapredSite}/* $out/
- cp ${siteXml "yarn-site.xml" cfg.yarnSite}/* $out/
- cp ${siteXml "httpfs-site.xml" cfg.httpfsSite}/* $out/
- cp ${cfgFile "container-executor.cfg" cfg.containerExecutorCfg}/* $out/
+ cp ${siteXml "core-site.xml" (coreSite // coreSiteInternal)}/* $out/
+ cp ${siteXml "hdfs-site.xml" (hdfsSiteDefault // hdfsSite // hdfsSiteInternal)}/* $out/
+ cp ${siteXml "mapred-site.xml" (mapredSiteDefault // mapredSite)}/* $out/
+ cp ${siteXml "yarn-site.xml" (yarnSiteDefault // yarnSite // yarnSiteInternal)}/* $out/
+ cp ${siteXml "httpfs-site.xml" httpfsSite}/* $out/
+ cp ${cfgFile "container-executor.cfg" containerExecutorCfg}/* $out/
cp ${pkgs.writeTextDir "hadoop-user-functions.sh" userFunctions}/* $out/
cp ${pkgs.writeTextDir "hadoop-env.sh" hadoopEnv}/* $out/
- cp ${cfg.log4jProperties} $out/log4j.properties
- ${lib.concatMapStringsSep "\n" (dir: "cp -r ${dir}/* $out/") cfg.extraConfDirs}
-''
+ cp ${log4jProperties} $out/log4j.properties
+ ${lib.concatMapStringsSep "\n" (dir: "cp -r ${dir}/* $out/") extraConfDirs}
+'')
diff --git a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/default.nix b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/default.nix
index a1a95fe31c..a4fdea8103 100644
--- a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/default.nix
+++ b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/default.nix
@@ -21,24 +21,50 @@ with lib;
'';
};
+ coreSiteInternal = mkOption {
+ default = {};
+ type = types.attrsOf types.anything;
+ internal = true;
+ description = ''
+ Internal option to add configs to core-site.xml based on module options
+ '';
+ };
- hdfsSite = mkOption {
+ hdfsSiteDefault = mkOption {
default = {
"dfs.namenode.rpc-bind-host" = "0.0.0.0";
+ "dfs.namenode.http-address" = "0.0.0.0:9870";
+ "dfs.namenode.servicerpc-bind-host" = "0.0.0.0";
+ "dfs.namenode.http-bind-host" = "0.0.0.0";
};
type = types.attrsOf types.anything;
+ description = ''
+ Default options for hdfs-site.xml
+ '';
+ };
+ hdfsSite = mkOption {
+ default = {};
+ type = types.attrsOf types.anything;
example = literalExpression ''
{
"dfs.nameservices" = "namenode1";
}
'';
description = ''
- Hadoop hdfs-site.xml definition
+ Additional options and overrides for hdfs-site.xml
'';
};
+ hdfsSiteInternal = mkOption {
+ default = {};
+ type = types.attrsOf types.anything;
+ internal = true;
+ description = ''
+ Internal option to add configs to hdfs-site.xml based on module options
+ '';
+ };
- mapredSite = mkOption {
+ mapredSiteDefault = mkOption {
default = {
"mapreduce.framework.name" = "yarn";
"yarn.app.mapreduce.am.env" = "HADOOP_MAPRED_HOME=${cfg.package}/lib/${cfg.package.untarDir}";
@@ -54,18 +80,25 @@ with lib;
}
'';
type = types.attrsOf types.anything;
+ description = ''
+ Default options for mapred-site.xml
+ '';
+ };
+ mapredSite = mkOption {
+ default = {};
+ type = types.attrsOf types.anything;
example = literalExpression ''
- options.services.hadoop.mapredSite.default // {
+ {
"mapreduce.map.java.opts" = "-Xmx900m -XX:+UseParallelGC";
}
'';
description = ''
- Hadoop mapred-site.xml definition
+ Additional options and overrides for mapred-site.xml
'';
};
- yarnSite = mkOption {
+ yarnSiteDefault = mkOption {
default = {
"yarn.nodemanager.admin-env" = "PATH=$PATH";
"yarn.nodemanager.aux-services" = "mapreduce_shuffle";
@@ -77,19 +110,34 @@ with lib;
"yarn.nodemanager.linux-container-executor.path" = "/run/wrappers/yarn-nodemanager/bin/container-executor";
"yarn.nodemanager.log-dirs" = "/var/log/hadoop/yarn/nodemanager";
"yarn.resourcemanager.bind-host" = "0.0.0.0";
- "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler";
+ "yarn.resourcemanager.scheduler.class" = "org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler";
};
type = types.attrsOf types.anything;
+ description = ''
+ Default options for yarn-site.xml
+ '';
+ };
+ yarnSite = mkOption {
+ default = {};
+ type = types.attrsOf types.anything;
example = literalExpression ''
- options.services.hadoop.yarnSite.default // {
+ {
"yarn.resourcemanager.hostname" = "''${config.networking.hostName}";
}
'';
description = ''
- Hadoop yarn-site.xml definition
+ Additional options and overrides for yarn-site.xml
'';
};
+ yarnSiteInternal = mkOption {
+ default = {};
+ type = types.attrsOf types.anything;
+ internal = true;
+ description = ''
+ Internal option to add configs to yarn-site.xml based on module options
+ '';
+ };
httpfsSite = mkOption {
default = { };
@@ -123,6 +171,7 @@ with lib;
"yarn.nodemanager.linux-container-executor.group"="hadoop";
"min.user.id"=1000;
"feature.terminal.enabled"=1;
+ "feature.mount-cgroup.enabled" = 1;
};
type = types.attrsOf types.anything;
example = literalExpression ''
@@ -148,6 +197,8 @@ with lib;
description = "Directories containing additional config files to be added to HADOOP_CONF_DIR";
};
+ gatewayRole.enable = mkEnableOption "gateway role for deploying hadoop configs";
+
package = mkOption {
type = types.package;
default = pkgs.hadoop;
@@ -157,20 +208,16 @@ with lib;
};
- config = mkMerge [
- (mkIf (builtins.hasAttr "yarn" config.users.users ||
- builtins.hasAttr "hdfs" config.users.users ||
- builtins.hasAttr "httpfs" config.users.users) {
- users.groups.hadoop = {
- gid = config.ids.gids.hadoop;
- };
- environment = {
- systemPackages = [ cfg.package ];
- etc."hadoop-conf".source = let
- hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
- in "${hadoopConf}";
- };
- })
-
- ];
+ config = mkIf cfg.gatewayRole.enable {
+ users.groups.hadoop = {
+ gid = config.ids.gids.hadoop;
+ };
+ environment = {
+ systemPackages = [ cfg.package ];
+ etc."hadoop-conf".source = let
+ hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
+ in "${hadoopConf}";
+ variables.HADOOP_CONF_DIR = "/etc/hadoop-conf/";
+ };
+ };
}
diff --git a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/hdfs.nix b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/hdfs.nix
index be667aa82d..325a002ad3 100644
--- a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/hdfs.nix
+++ b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/hdfs.nix
@@ -1,191 +1,191 @@
-{ config, lib, pkgs, ...}:
+{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.hadoop;
+
+ # Config files for hadoop services
hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
- restartIfChanged = mkOption {
- type = types.bool;
- description = ''
- Automatically restart the service on config change.
- This can be set to false to defer restarts on clusters running critical applications.
- Please consider the security implications of inadvertently running an older version,
- and the possibility of unexpected behavior caused by inconsistent versions across a cluster when disabling this option.
- '';
- default = false;
- };
+
+ # Generator for HDFS service options
+ hadoopServiceOption = { serviceName, firewallOption ? true, extraOpts ? null }: {
+ enable = mkEnableOption serviceName;
+ restartIfChanged = mkOption {
+ type = types.bool;
+ description = ''
+ Automatically restart the service on config change.
+ This can be set to false to defer restarts on clusters running critical applications.
+ Please consider the security implications of inadvertently running an older version,
+ and the possibility of unexpected behavior caused by inconsistent versions across a cluster when disabling this option.
+ '';
+ default = false;
+ };
+ extraFlags = mkOption{
+ type = with types; listOf str;
+ default = [];
+ description = "Extra command line flags to pass to ${serviceName}";
+ example = [
+ "-Dcom.sun.management.jmxremote"
+ "-Dcom.sun.management.jmxremote.port=8010"
+ ];
+ };
+ extraEnv = mkOption{
+ type = with types; attrsOf str;
+ default = {};
+ description = "Extra environment variables for ${serviceName}";
+ };
+ } // (optionalAttrs firewallOption {
+ openFirewall = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Open firewall ports for ${serviceName}.";
+ };
+ }) // (optionalAttrs (extraOpts != null) extraOpts);
+
+ # Generator for HDFS service configs
+ hadoopServiceConfig =
+ { name
+ , serviceOptions ? cfg.hdfs."${toLower name}"
+ , description ? "Hadoop HDFS ${name}"
+ , User ? "hdfs"
+ , allowedTCPPorts ? [ ]
+ , preStart ? ""
+ , environment ? { }
+ , extraConfig ? { }
+ }: (
+
+ mkIf serviceOptions.enable ( mkMerge [{
+ systemd.services."hdfs-${toLower name}" = {
+ inherit description preStart;
+ environment = environment // serviceOptions.extraEnv;
+ wantedBy = [ "multi-user.target" ];
+ inherit (serviceOptions) restartIfChanged;
+ serviceConfig = {
+ inherit User;
+ SyslogIdentifier = "hdfs-${toLower name}";
+ ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} ${toLower name} ${escapeShellArgs serviceOptions.extraFlags}";
+ Restart = "always";
+ };
+ };
+
+ services.hadoop.gatewayRole.enable = true;
+
+ networking.firewall.allowedTCPPorts = mkIf
+ ((builtins.hasAttr "openFirewall" serviceOptions) && serviceOptions.openFirewall)
+ allowedTCPPorts;
+ } extraConfig])
+ );
+
in
{
options.services.hadoop.hdfs = {
- namenode = {
- enable = mkEnableOption "Whether to run the HDFS NameNode";
+
+ namenode = hadoopServiceOption { serviceName = "HDFS NameNode"; } // {
formatOnInit = mkOption {
type = types.bool;
default = false;
description = ''
- Format HDFS namenode on first start. This is useful for quickly spinning up ephemeral HDFS clusters with a single namenode.
- For HA clusters, initialization involves multiple steps across multiple nodes. Follow [this guide](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html)
- to initialize an HA cluster manually.
- '';
- };
- inherit restartIfChanged;
- openFirewall = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Open firewall ports for namenode
+ Format HDFS namenode on first start. This is useful for quickly spinning up
+ ephemeral HDFS clusters with a single namenode.
+ For HA clusters, initialization involves multiple steps across multiple nodes.
+ Follow this guide to initialize an HA cluster manually:
+
'';
};
};
- datanode = {
- enable = mkEnableOption "Whether to run the HDFS DataNode";
- inherit restartIfChanged;
- openFirewall = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Open firewall ports for datanode
- '';
+
+ datanode = hadoopServiceOption { serviceName = "HDFS DataNode"; } // {
+ dataDirs = mkOption {
+ default = null;
+ description = "Tier and path definitions for datanode storage.";
+ type = with types; nullOr (listOf (submodule {
+ options = {
+ type = mkOption {
+ type = enum [ "SSD" "DISK" "ARCHIVE" "RAM_DISK" ];
+ description = ''
+ Storage types ([SSD]/[DISK]/[ARCHIVE]/[RAM_DISK]) for HDFS storage policies.
+ '';
+ };
+ path = mkOption {
+ type = path;
+ example = [ "/var/lib/hadoop/hdfs/dn" ];
+ description = "Determines where on the local filesystem a data node should store its blocks.";
+ };
+ };
+ }));
};
};
- journalnode = {
- enable = mkEnableOption "Whether to run the HDFS JournalNode";
- inherit restartIfChanged;
- openFirewall = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Open firewall ports for journalnode
- '';
- };
+
+ journalnode = hadoopServiceOption { serviceName = "HDFS JournalNode"; };
+
+ zkfc = hadoopServiceOption {
+ serviceName = "HDFS ZooKeeper failover controller";
+ firewallOption = false;
};
- zkfc = {
- enable = mkEnableOption "Whether to run the HDFS ZooKeeper failover controller";
- inherit restartIfChanged;
- };
- httpfs = {
- enable = mkEnableOption "Whether to run the HDFS HTTPfs server";
+
+ httpfs = hadoopServiceOption { serviceName = "HDFS JournalNode"; } // {
tempPath = mkOption {
type = types.path;
default = "/tmp/hadoop/httpfs";
- description = ''
- HTTPFS_TEMP path used by HTTPFS
- '';
- };
- inherit restartIfChanged;
- openFirewall = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Open firewall ports for HTTPFS
- '';
+ description = "HTTPFS_TEMP path used by HTTPFS";
};
};
+
};
config = mkMerge [
- (mkIf cfg.hdfs.namenode.enable {
- systemd.services.hdfs-namenode = {
- description = "Hadoop HDFS NameNode";
- wantedBy = [ "multi-user.target" ];
- inherit (cfg.hdfs.namenode) restartIfChanged;
-
- preStart = (mkIf cfg.hdfs.namenode.formatOnInit ''
- ${cfg.package}/bin/hdfs --config ${hadoopConf} namenode -format -nonInteractive || true
- '');
-
- serviceConfig = {
- User = "hdfs";
- SyslogIdentifier = "hdfs-namenode";
- ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} namenode";
- Restart = "always";
- };
- };
-
- networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.namenode.openFirewall [
+ (hadoopServiceConfig {
+ name = "NameNode";
+ allowedTCPPorts = [
9870 # namenode.http-address
8020 # namenode.rpc-address
- 8022 # namenode. servicerpc-address
- ]);
+ 8022 # namenode.servicerpc-address
+ 8019 # dfs.ha.zkfc.port
+ ];
+ preStart = (mkIf cfg.hdfs.namenode.formatOnInit
+ "${cfg.package}/bin/hdfs --config ${hadoopConf} namenode -format -nonInteractive || true"
+ );
})
- (mkIf cfg.hdfs.datanode.enable {
- systemd.services.hdfs-datanode = {
- description = "Hadoop HDFS DataNode";
- wantedBy = [ "multi-user.target" ];
- inherit (cfg.hdfs.datanode) restartIfChanged;
- serviceConfig = {
- User = "hdfs";
- SyslogIdentifier = "hdfs-datanode";
- ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} datanode";
- Restart = "always";
- };
- };
-
- networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.datanode.openFirewall [
+ (hadoopServiceConfig {
+ name = "DataNode";
+ # port numbers for datanode changed between hadoop 2 and 3
+ allowedTCPPorts = if versionAtLeast cfg.package.version "3" then [
9864 # datanode.http.address
9866 # datanode.address
9867 # datanode.ipc.address
- ]);
+ ] else [
+ 50075 # datanode.http.address
+ 50010 # datanode.address
+ 50020 # datanode.ipc.address
+ ];
+ extraConfig.services.hadoop.hdfsSiteInternal."dfs.datanode.data.dir" = let d = cfg.hdfs.datanode.dataDirs; in
+ if (d!= null) then (concatMapStringsSep "," (x: "["+x.type+"]file://"+x.path) cfg.hdfs.datanode.dataDirs) else d;
})
- (mkIf cfg.hdfs.journalnode.enable {
- systemd.services.hdfs-journalnode = {
- description = "Hadoop HDFS JournalNode";
- wantedBy = [ "multi-user.target" ];
- inherit (cfg.hdfs.journalnode) restartIfChanged;
- serviceConfig = {
- User = "hdfs";
- SyslogIdentifier = "hdfs-journalnode";
- ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} journalnode";
- Restart = "always";
- };
- };
-
- networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.journalnode.openFirewall [
+ (hadoopServiceConfig {
+ name = "JournalNode";
+ allowedTCPPorts = [
8480 # dfs.journalnode.http-address
8485 # dfs.journalnode.rpc-address
- ]);
+ ];
})
- (mkIf cfg.hdfs.zkfc.enable {
- systemd.services.hdfs-zkfc = {
- description = "Hadoop HDFS ZooKeeper failover controller";
- wantedBy = [ "multi-user.target" ];
- inherit (cfg.hdfs.zkfc) restartIfChanged;
- serviceConfig = {
- User = "hdfs";
- SyslogIdentifier = "hdfs-zkfc";
- ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} zkfc";
- Restart = "always";
- };
- };
+ (hadoopServiceConfig {
+ name = "zkfc";
+ description = "Hadoop HDFS ZooKeeper failover controller";
})
- (mkIf cfg.hdfs.httpfs.enable {
- systemd.services.hdfs-httpfs = {
- description = "Hadoop httpfs";
- wantedBy = [ "multi-user.target" ];
- inherit (cfg.hdfs.httpfs) restartIfChanged;
- environment.HTTPFS_TEMP = cfg.hdfs.httpfs.tempPath;
-
- preStart = ''
- mkdir -p $HTTPFS_TEMP
- '';
-
- serviceConfig = {
- User = "httpfs";
- SyslogIdentifier = "hdfs-httpfs";
- ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} httpfs";
- Restart = "always";
- };
- };
- networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.httpfs.openFirewall [
+ (hadoopServiceConfig {
+ name = "HTTPFS";
+ environment.HTTPFS_TEMP = cfg.hdfs.httpfs.tempPath;
+ preStart = "mkdir -p $HTTPFS_TEMP";
+ User = "httpfs";
+ allowedTCPPorts = [
14000 # httpfs.http.port
- ]);
+ ];
})
- (mkIf (
- cfg.hdfs.namenode.enable || cfg.hdfs.datanode.enable || cfg.hdfs.journalnode.enable || cfg.hdfs.zkfc.enable
- ) {
+
+ (mkIf cfg.gatewayRole.enable {
users.users.hdfs = {
description = "Hadoop HDFS user";
group = "hadoop";
@@ -199,5 +199,6 @@ in
isSystemUser = true;
};
})
+
];
}
diff --git a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/yarn.nix b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/yarn.nix
index 37c26ea10f..74e16bdec6 100644
--- a/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/yarn.nix
+++ b/third_party/nixpkgs/nixos/modules/services/cluster/hadoop/yarn.nix
@@ -13,23 +13,77 @@ let
'';
default = false;
};
+ extraFlags = mkOption{
+ type = with types; listOf str;
+ default = [];
+ description = "Extra command line flags to pass to the service";
+ example = [
+ "-Dcom.sun.management.jmxremote"
+ "-Dcom.sun.management.jmxremote.port=8010"
+ ];
+ };
+ extraEnv = mkOption{
+ type = with types; attrsOf str;
+ default = {};
+ description = "Extra environment variables";
+ };
in
{
options.services.hadoop.yarn = {
resourcemanager = {
- enable = mkEnableOption "Whether to run the Hadoop YARN ResourceManager";
- inherit restartIfChanged;
+ enable = mkEnableOption "Hadoop YARN ResourceManager";
+ inherit restartIfChanged extraFlags extraEnv;
+
openFirewall = mkOption {
type = types.bool;
- default = true;
+ default = false;
description = ''
Open firewall ports for resourcemanager
'';
};
};
nodemanager = {
- enable = mkEnableOption "Whether to run the Hadoop YARN NodeManager";
- inherit restartIfChanged;
+ enable = mkEnableOption "Hadoop YARN NodeManager";
+ inherit restartIfChanged extraFlags extraEnv;
+
+ resource = {
+ cpuVCores = mkOption {
+ description = "Number of vcores that can be allocated for containers.";
+ type = with types; nullOr ints.positive;
+ default = null;
+ };
+ maximumAllocationVCores = mkOption {
+ description = "The maximum virtual CPU cores any container can be allocated.";
+ type = with types; nullOr ints.positive;
+ default = null;
+ };
+ memoryMB = mkOption {
+ description = "Amount of physical memory, in MB, that can be allocated for containers.";
+ type = with types; nullOr ints.positive;
+ default = null;
+ };
+ maximumAllocationMB = mkOption {
+ description = "The maximum physical memory any container can be allocated.";
+ type = with types; nullOr ints.positive;
+ default = null;
+ };
+ };
+
+ useCGroups = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Use cgroups to enforce resource limits on containers
+ '';
+ };
+
+ localDir = mkOption {
+ description = "List of directories to store localized files in.";
+ type = with types; nullOr (listOf path);
+ example = [ "/var/lib/hadoop/yarn/nm" ];
+ default = null;
+ };
+
addBinBash = mkOption {
type = types.bool;
default = true;
@@ -39,7 +93,7 @@ in
};
openFirewall = mkOption {
type = types.bool;
- default = true;
+ default = false;
description = ''
Open firewall ports for nodemanager.
Because containers can listen on any ephemeral port, TCP ports 1024–65535 will be opened.
@@ -49,10 +103,7 @@ in
};
config = mkMerge [
- (mkIf (
- cfg.yarn.resourcemanager.enable || cfg.yarn.nodemanager.enable
- ) {
-
+ (mkIf cfg.gatewayRole.enable {
users.users.yarn = {
description = "Hadoop YARN user";
group = "hadoop";
@@ -65,15 +116,19 @@ in
description = "Hadoop YARN ResourceManager";
wantedBy = [ "multi-user.target" ];
inherit (cfg.yarn.resourcemanager) restartIfChanged;
+ environment = cfg.yarn.resourcemanager.extraEnv;
serviceConfig = {
User = "yarn";
SyslogIdentifier = "yarn-resourcemanager";
ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " +
- " resourcemanager";
+ " resourcemanager ${escapeShellArgs cfg.yarn.resourcemanager.extraFlags}";
Restart = "always";
};
};
+
+ services.hadoop.gatewayRole.enable = true;
+
networking.firewall.allowedTCPPorts = (mkIf cfg.yarn.resourcemanager.openFirewall [
8088 # resourcemanager.webapp.address
8030 # resourcemanager.scheduler.address
@@ -94,6 +149,7 @@ in
description = "Hadoop YARN NodeManager";
wantedBy = [ "multi-user.target" ];
inherit (cfg.yarn.nodemanager) restartIfChanged;
+ environment = cfg.yarn.nodemanager.extraEnv;
preStart = ''
# create log dir
@@ -101,8 +157,9 @@ in
chown yarn:hadoop /var/log/hadoop/yarn/nodemanager
# set up setuid container executor binary
+ umount /run/wrappers/yarn-nodemanager/cgroup/cpu || true
rm -rf /run/wrappers/yarn-nodemanager/ || true
- mkdir -p /run/wrappers/yarn-nodemanager/{bin,etc/hadoop}
+ mkdir -p /run/wrappers/yarn-nodemanager/{bin,etc/hadoop,cgroup/cpu}
cp ${cfg.package}/lib/${cfg.package.untarDir}/bin/container-executor /run/wrappers/yarn-nodemanager/bin/
chgrp hadoop /run/wrappers/yarn-nodemanager/bin/container-executor
chmod 6050 /run/wrappers/yarn-nodemanager/bin/container-executor
@@ -114,11 +171,26 @@ in
SyslogIdentifier = "yarn-nodemanager";
PermissionsStartOnly = true;
ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " +
- " nodemanager";
+ " nodemanager ${escapeShellArgs cfg.yarn.nodemanager.extraFlags}";
Restart = "always";
};
};
+ services.hadoop.gatewayRole.enable = true;
+
+ services.hadoop.yarnSiteInternal = with cfg.yarn.nodemanager; {
+ "yarn.nodemanager.local-dirs" = localDir;
+ "yarn.scheduler.maximum-allocation-vcores" = resource.maximumAllocationVCores;
+ "yarn.scheduler.maximum-allocation-mb" = resource.maximumAllocationMB;
+ "yarn.nodemanager.resource.cpu-vcores" = resource.cpuVCores;
+ "yarn.nodemanager.resource.memory-mb" = resource.memoryMB;
+ } // mkIf useCGroups {
+ "yarn.nodemanager.linux-container-executor.cgroups.hierarchy" = "/hadoop-yarn";
+ "yarn.nodemanager.linux-container-executor.resources-handler.class" = "org.apache.hadoop.yarn.server.nodemanager.util.CgroupsLCEResourcesHandler";
+ "yarn.nodemanager.linux-container-executor.cgroups.mount" = "true";
+ "yarn.nodemanager.linux-container-executor.cgroups.mount-path" = "/run/wrappers/yarn-nodemanager/cgroup";
+ };
+
networking.firewall.allowedTCPPortRanges = [
(mkIf (cfg.yarn.nodemanager.openFirewall) {from = 1024; to = 65535;})
];
diff --git a/third_party/nixpkgs/nixos/modules/services/cluster/pacemaker/default.nix b/third_party/nixpkgs/nixos/modules/services/cluster/pacemaker/default.nix
new file mode 100644
index 0000000000..7eeadffcc5
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/cluster/pacemaker/default.nix
@@ -0,0 +1,52 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+ cfg = config.services.pacemaker;
+in
+{
+ # interface
+ options.services.pacemaker = {
+ enable = mkEnableOption "pacemaker";
+
+ package = mkOption {
+ type = types.package;
+ default = pkgs.pacemaker;
+ defaultText = literalExpression "pkgs.pacemaker";
+ description = "Package that should be used for pacemaker.";
+ };
+ };
+
+ # implementation
+ config = mkIf cfg.enable {
+ assertions = [ {
+ assertion = config.services.corosync.enable;
+ message = ''
+ Enabling services.pacemaker requires a services.corosync configuration.
+ '';
+ } ];
+
+ environment.systemPackages = [ cfg.package ];
+
+ # required by pacemaker
+ users.users.hacluster = {
+ isSystemUser = true;
+ group = "pacemaker";
+ home = "/var/lib/pacemaker";
+ };
+ users.groups.pacemaker = {};
+
+ systemd.tmpfiles.rules = [
+ "d /var/log/pacemaker 0700 hacluster pacemaker -"
+ ];
+
+ systemd.packages = [ cfg.package ];
+ systemd.services.pacemaker = {
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ StateDirectory = "pacemaker";
+ StateDirectoryMode = "0700";
+ };
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/continuous-integration/buildbot/master.nix b/third_party/nixpkgs/nixos/modules/services/continuous-integration/buildbot/master.nix
index aaa159d3cb..80c6c6abfd 100644
--- a/third_party/nixpkgs/nixos/modules/services/continuous-integration/buildbot/master.nix
+++ b/third_party/nixpkgs/nixos/modules/services/continuous-integration/buildbot/master.nix
@@ -64,7 +64,7 @@ in {
description = "Factory Steps";
default = [];
example = [
- "steps.Git(repourl='git://github.com/buildbot/pyflakes.git', mode='incremental')"
+ "steps.Git(repourl='https://github.com/buildbot/pyflakes.git', mode='incremental')"
"steps.ShellCommand(command=['trial', 'pyflakes'])"
];
};
@@ -74,7 +74,7 @@ in {
description = "List of Change Sources.";
default = [];
example = [
- "changes.GitPoller('git://github.com/buildbot/pyflakes.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)"
+ "changes.GitPoller('https://github.com/buildbot/pyflakes.git', workdir='gitpoller-workdir', branch='master', pollinterval=300)"
];
};
diff --git a/third_party/nixpkgs/nixos/modules/services/continuous-integration/github-runner.nix b/third_party/nixpkgs/nixos/modules/services/continuous-integration/github-runner.nix
index c3bd8f99c5..a7645e1f56 100644
--- a/third_party/nixpkgs/nixos/modules/services/continuous-integration/github-runner.nix
+++ b/third_party/nixpkgs/nixos/modules/services/continuous-integration/github-runner.nix
@@ -34,6 +34,14 @@ in
Repository to add the runner to.
Changing this option triggers a new runner registration.
+
+ IMPORTANT: If your token is org-wide (not per repository), you need to
+ provide a github org link, not a single repository, so do it like this
+ https://github.com/nixos, not like this
+ https://github.com/nixos/nixpkgs.
+ Otherwise, you are going to get a 404 NotFound
+ from POST https://api.github.com/actions/runner-registration
+ in the configure script.
'';
example = "https://github.com/nixos/nixpkgs";
};
diff --git a/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix b/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix
index 109c91134b..6027e4f3d4 100644
--- a/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix
+++ b/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire-media-session.nix
@@ -110,6 +110,11 @@ in {
source = json.generate "v4l2-monitor.conf" configs.v4l2-monitor;
};
+ environment.etc."pipewire/media-session.d/with-audio" =
+ mkIf config.services.pipewire.audio.enable {
+ text = "";
+ };
+
environment.etc."pipewire/media-session.d/with-alsa" =
mkIf config.services.pipewire.alsa.enable {
text = "";
diff --git a/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix b/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
index 59e9342a6e..1323336d86 100644
--- a/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
+++ b/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/pipewire.nix
@@ -116,6 +116,16 @@ in {
};
};
+ audio = {
+ enable = lib.mkOption {
+ type = lib.types.bool;
+ # this is for backwards compatibility
+ default = cfg.alsa.enable || cfg.jack.enable || cfg.pulse.enable;
+ defaultText = lib.literalExpression "config.services.pipewire.alsa.enable || config.services.pipewire.jack.enable || config.services.pipewire.pulse.enable";
+ description = "Whether to use PipeWire as the primary sound server";
+ };
+ };
+
alsa = {
enable = mkEnableOption "ALSA support";
support32Bit = mkEnableOption "32-bit ALSA support on 64-bit systems";
@@ -152,13 +162,18 @@ in {
config = mkIf cfg.enable {
assertions = [
{
- assertion = cfg.pulse.enable -> !config.hardware.pulseaudio.enable;
- message = "PipeWire based PulseAudio server emulation replaces PulseAudio. This option requires `hardware.pulseaudio.enable` to be set to false";
+ assertion = cfg.audio.enable -> !config.hardware.pulseaudio.enable;
+ message = "Using PipeWire as the sound server conflicts with PulseAudio. This option requires `hardware.pulseaudio.enable` to be set to false";
}
{
assertion = cfg.jack.enable -> !config.services.jack.jackd.enable;
message = "PipeWire based JACK emulation doesn't use the JACK service. This option requires `services.jack.jackd.enable` to be set to false";
}
+ {
+ # JACK intentionally not checked, as PW-on-JACK setups are a thing that some people may want
+ assertion = (cfg.alsa.enable || cfg.pulse.enable) -> cfg.audio.enable;
+ message = "Using PipeWire's ALSA/PulseAudio compatibility layers requires running PipeWire as the sound server. Set `services.pipewire.audio.enable` to true.";
+ }
];
environment.systemPackages = [ cfg.package ]
diff --git a/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix b/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
index 52ec17b95d..32206ccb4e 100644
--- a/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
+++ b/third_party/nixpkgs/nixos/modules/services/desktops/pipewire/wireplumber.nix
@@ -1,7 +1,9 @@
{ config, lib, pkgs, ... }:
let
- cfg = config.services.pipewire.wireplumber;
+ pwCfg = config.services.pipewire;
+ cfg = pwCfg.wireplumber;
+ pwUsedForAudio = pwCfg.audio.enable;
in
{
meta.maintainers = [ lib.maintainers.k900 ];
@@ -33,6 +35,14 @@ in
];
environment.systemPackages = [ cfg.package ];
+
+ environment.etc."wireplumber/main.lua.d/80-nixos.lua" = lib.mkIf (!pwUsedForAudio) {
+ text = ''
+ # Pipewire is not used for audio, so prevent it from grabbing audio devices
+ alsa_monitor.enable = function() end
+ '';
+ };
+
systemd.packages = [ cfg.package ];
systemd.services.wireplumber.enable = config.services.pipewire.systemWide;
diff --git a/third_party/nixpkgs/nixos/modules/services/games/factorio.nix b/third_party/nixpkgs/nixos/modules/services/games/factorio.nix
index 96fcd6d2c8..ff73d7a46e 100644
--- a/third_party/nixpkgs/nixos/modules/services/games/factorio.nix
+++ b/third_party/nixpkgs/nixos/modules/services/games/factorio.nix
@@ -53,6 +53,14 @@ in
'';
};
+ bind = mkOption {
+ type = types.str;
+ default = "0.0.0.0";
+ description = ''
+ The address to which the service should bind.
+ '';
+ };
+
admins = mkOption {
type = types.listOf types.str;
default = [];
@@ -241,6 +249,7 @@ in
"${cfg.package}/bin/factorio"
"--config=${cfg.configFile}"
"--port=${toString cfg.port}"
+ "--bind=${cfg.bind}"
"--start-server=${mkSavePath cfg.saveName}"
"--server-settings=${serverSettingsFile}"
(optionalString (cfg.mods != []) "--mod-directory=${modDir}")
diff --git a/third_party/nixpkgs/nixos/modules/services/games/minecraft-server.nix b/third_party/nixpkgs/nixos/modules/services/games/minecraft-server.nix
index 5bb8eff576..8233962c1a 100644
--- a/third_party/nixpkgs/nixos/modules/services/games/minecraft-server.nix
+++ b/third_party/nixpkgs/nixos/modules/services/games/minecraft-server.nix
@@ -153,7 +153,7 @@ in {
type = types.separatedString " ";
default = "-Xmx2048M -Xms2048M";
# Example options from https://minecraft.gamepedia.com/Tutorials/Server_startup_script
- example = "-Xmx2048M -Xms4092M -XX:+UseG1GC -XX:+CMSIncrementalPacing "
+ example = "-Xms4092M -Xmx4092M -XX:+UseG1GC -XX:+CMSIncrementalPacing "
+ "-XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=2 "
+ "-XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10";
description = "JVM options for the Minecraft server.";
diff --git a/third_party/nixpkgs/nixos/modules/services/hardware/joycond.nix b/third_party/nixpkgs/nixos/modules/services/hardware/joycond.nix
index ffef4f8a4e..d81c1bb6d6 100644
--- a/third_party/nixpkgs/nixos/modules/services/hardware/joycond.nix
+++ b/third_party/nixpkgs/nixos/modules/services/hardware/joycond.nix
@@ -22,13 +22,9 @@ with lib;
};
config = mkIf cfg.enable {
- environment.systemPackages = [
- kernelPackages.hid-nintendo
- cfg.package
- ];
+ environment.systemPackages = [ cfg.package ];
- boot.extraModulePackages = [ kernelPackages.hid-nintendo ];
- boot.kernelModules = [ "hid_nintendo" ];
+ boot.extraModulePackages = optional (versionOlder kernelPackages.kernel.version "5.16") kernelPackages.hid-nintendo;
services.udev.packages = [ cfg.package ];
diff --git a/third_party/nixpkgs/nixos/modules/services/logging/graylog.nix b/third_party/nixpkgs/nixos/modules/services/logging/graylog.nix
index e6a23233ba..28e2d18bf0 100644
--- a/third_party/nixpkgs/nixos/modules/services/logging/graylog.nix
+++ b/third_party/nixpkgs/nixos/modules/services/logging/graylog.nix
@@ -132,7 +132,7 @@ in
description = "Graylog server daemon user";
};
};
- users.groups = mkIf (cfg.user == "graylog") {};
+ users.groups = mkIf (cfg.user == "graylog") { graylog = {}; };
systemd.tmpfiles.rules = [
"d '${cfg.messageJournalDir}' - ${cfg.user} - - -"
diff --git a/third_party/nixpkgs/nixos/modules/services/matrix/matrix-synapse.xml b/third_party/nixpkgs/nixos/modules/services/matrix/matrix-synapse.xml
index cdc4b4de1a..cf33957d58 100644
--- a/third_party/nixpkgs/nixos/modules/services/matrix/matrix-synapse.xml
+++ b/third_party/nixpkgs/nixos/modules/services/matrix/matrix-synapse.xml
@@ -119,7 +119,7 @@ in {
listeners = [
{
port = 8008;
- bind_address = [ "::1" ];
+ bind_addresses = [ "::1" ];
type = "http";
tls = false;
x_forwarded = true;
@@ -152,10 +152,10 @@ in {
If you want to run a server with public registration by anybody, you can
- then enable services.matrix-synapse.enable_registration =
+ then enable services.matrix-synapse.settings.enable_registration =
true;. Otherwise, or you can generate a registration secret with
pwgen -s 64 1 and set it with
- .
+ .
To create a new user or admin, run the following after you have set the secret
and have rebuilt NixOS:
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/autorandr.nix b/third_party/nixpkgs/nixos/modules/services/misc/autorandr.nix
index a65c5c9d11..ef799e9ce3 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/autorandr.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/autorandr.nix
@@ -5,6 +5,243 @@ with lib;
let
cfg = config.services.autorandr;
+ hookType = types.lines;
+
+ matrixOf = n: m: elemType:
+ mkOptionType rec {
+ name = "matrixOf";
+ description =
+ "${toString n}×${toString m} matrix of ${elemType.description}s";
+ check = xss:
+ let listOfSize = l: xs: isList xs && length xs == l;
+ in listOfSize n xss
+ && all (xs: listOfSize m xs && all elemType.check xs) xss;
+ merge = mergeOneOption;
+ getSubOptions = prefix: elemType.getSubOptions (prefix ++ [ "*" "*" ]);
+ getSubModules = elemType.getSubModules;
+ substSubModules = mod: matrixOf n m (elemType.substSubModules mod);
+ functor = (defaultFunctor name) // { wrapped = elemType; };
+ };
+
+ profileModule = types.submodule {
+ options = {
+ fingerprint = mkOption {
+ type = types.attrsOf types.str;
+ description = ''
+ Output name to EDID mapping.
+ Use autorandr --fingerprint
to get current setup values.
+ '';
+ default = { };
+ };
+
+ config = mkOption {
+ type = types.attrsOf configModule;
+ description = "Per output profile configuration.";
+ default = { };
+ };
+
+ hooks = mkOption {
+ type = hooksModule;
+ description = "Profile hook scripts.";
+ default = { };
+ };
+ };
+ };
+
+ configModule = types.submodule {
+ options = {
+ enable = mkOption {
+ type = types.bool;
+ description = "Whether to enable the output.";
+ default = true;
+ };
+
+ crtc = mkOption {
+ type = types.nullOr types.ints.unsigned;
+ description = "Output video display controller.";
+ default = null;
+ example = 0;
+ };
+
+ primary = mkOption {
+ type = types.bool;
+ description = "Whether output should be marked as primary";
+ default = false;
+ };
+
+ position = mkOption {
+ type = types.str;
+ description = "Output position";
+ default = "";
+ example = "5760x0";
+ };
+
+ mode = mkOption {
+ type = types.str;
+ description = "Output resolution.";
+ default = "";
+ example = "3840x2160";
+ };
+
+ rate = mkOption {
+ type = types.str;
+ description = "Output framerate.";
+ default = "";
+ example = "60.00";
+ };
+
+ gamma = mkOption {
+ type = types.str;
+ description = "Output gamma configuration.";
+ default = "";
+ example = "1.0:0.909:0.833";
+ };
+
+ rotate = mkOption {
+ type = types.nullOr (types.enum [ "normal" "left" "right" "inverted" ]);
+ description = "Output rotate configuration.";
+ default = null;
+ example = "left";
+ };
+
+ transform = mkOption {
+ type = types.nullOr (matrixOf 3 3 types.float);
+ default = null;
+ example = literalExpression ''
+ [
+ [ 0.6 0.0 0.0 ]
+ [ 0.0 0.6 0.0 ]
+ [ 0.0 0.0 1.0 ]
+ ]
+ '';
+ description = ''
+ Refer to
+
+ xrandr
+ 1
+
+ for the documentation of the transform matrix.
+ '';
+ };
+
+ dpi = mkOption {
+ type = types.nullOr types.ints.positive;
+ description = "Output DPI configuration.";
+ default = null;
+ example = 96;
+ };
+
+ scale = mkOption {
+ type = types.nullOr (types.submodule {
+ options = {
+ method = mkOption {
+ type = types.enum [ "factor" "pixel" ];
+ description = "Output scaling method.";
+ default = "factor";
+ example = "pixel";
+ };
+
+ x = mkOption {
+ type = types.either types.float types.ints.positive;
+ description = "Horizontal scaling factor/pixels.";
+ };
+
+ y = mkOption {
+ type = types.either types.float types.ints.positive;
+ description = "Vertical scaling factor/pixels.";
+ };
+ };
+ });
+ description = ''
+ Output scale configuration.
+
+ Either configure by pixels or a scaling factor. When using pixel method the
+
+ xrandr
+ 1
+
+ option
+ --scale-from
+ will be used; when using factor method the option
+ --scale
+ will be used.
+
+ This option is a shortcut version of the transform option and they are mutually
+ exclusive.
+ '';
+ default = null;
+ example = literalExpression ''
+ {
+ x = 1.25;
+ y = 1.25;
+ }
+ '';
+ };
+ };
+ };
+
+ hooksModule = types.submodule {
+ options = {
+ postswitch = mkOption {
+ type = types.attrsOf hookType;
+ description = "Postswitch hook executed after mode switch.";
+ default = { };
+ };
+
+ preswitch = mkOption {
+ type = types.attrsOf hookType;
+ description = "Preswitch hook executed before mode switch.";
+ default = { };
+ };
+
+ predetect = mkOption {
+ type = types.attrsOf hookType;
+ description = ''
+ Predetect hook executed before autorandr attempts to run xrandr.
+ '';
+ default = { };
+ };
+ };
+ };
+
+ hookToFile = folder: name: hook:
+ nameValuePair "xdg/autorandr/${folder}/${name}" {
+ source = "${pkgs.writeShellScriptBin "hook" hook}/bin/hook";
+ };
+ profileToFiles = name: profile:
+ with profile;
+ mkMerge ([
+ {
+ "xdg/autorandr/${name}/setup".text = concatStringsSep "\n"
+ (mapAttrsToList fingerprintToString fingerprint);
+ "xdg/autorandr/${name}/config".text =
+ concatStringsSep "\n" (mapAttrsToList configToString profile.config);
+ }
+ (mapAttrs' (hookToFile "${name}/postswitch.d") hooks.postswitch)
+ (mapAttrs' (hookToFile "${name}/preswitch.d") hooks.preswitch)
+ (mapAttrs' (hookToFile "${name}/predetect.d") hooks.predetect)
+ ]);
+ fingerprintToString = name: edid: "${name} ${edid}";
+ configToString = name: config:
+ if config.enable then
+ concatStringsSep "\n" ([ "output ${name}" ]
+ ++ optional (config.position != "") "pos ${config.position}"
+ ++ optional (config.crtc != null) "crtc ${toString config.crtc}"
+ ++ optional config.primary "primary"
+ ++ optional (config.dpi != null) "dpi ${toString config.dpi}"
+ ++ optional (config.gamma != "") "gamma ${config.gamma}"
+ ++ optional (config.mode != "") "mode ${config.mode}"
+ ++ optional (config.rate != "") "rate ${config.rate}"
+ ++ optional (config.rotate != null) "rotate ${config.rotate}"
+ ++ optional (config.transform != null) ("transform "
+ + concatMapStringsSep "," toString (flatten config.transform))
+ ++ optional (config.scale != null)
+ ((if config.scale.method == "factor" then "scale" else "scale-from")
+ + " ${toString config.scale.x}x${toString config.scale.y}"))
+ else ''
+ output ${name}
+ off
+ '';
in {
@@ -22,6 +259,67 @@ in {
for further reference.
'';
};
+
+ hooks = mkOption {
+ type = hooksModule;
+ description = "Global hook scripts";
+ default = { };
+ example = ''
+ {
+ postswitch = {
+ "notify-i3" = "''${pkgs.i3}/bin/i3-msg restart";
+ "change-background" = readFile ./change-background.sh;
+ "change-dpi" = '''
+ case "$AUTORANDR_CURRENT_PROFILE" in
+ default)
+ DPI=120
+ ;;
+ home)
+ DPI=192
+ ;;
+ work)
+ DPI=144
+ ;;
+ *)
+ echo "Unknown profle: $AUTORANDR_CURRENT_PROFILE"
+ exit 1
+ esac
+ echo "Xft.dpi: $DPI" | ''${pkgs.xorg.xrdb}/bin/xrdb -merge
+ '''
+ };
+ }
+ '';
+ };
+ profiles = mkOption {
+ type = types.attrsOf profileModule;
+ description = "Autorandr profiles specification.";
+ default = { };
+ example = literalExpression ''
+ {
+ "work" = {
+ fingerprint = {
+ eDP1 = "";
+ DP1 = "";
+ };
+ config = {
+ eDP1.enable = false;
+ DP1 = {
+ enable = true;
+ crtc = 0;
+ primary = true;
+ position = "0x0";
+ mode = "3840x2160";
+ gamma = "1.0:0.909:0.833";
+ rate = "60.00";
+ rotate = "left";
+ };
+ };
+ hooks.postswitch = readFile ./work-postswitch.sh;
+ };
+ }
+ '';
+ };
+
};
};
@@ -30,7 +328,15 @@ in {
services.udev.packages = [ pkgs.autorandr ];
- environment.systemPackages = [ pkgs.autorandr ];
+ environment = {
+ systemPackages = [ pkgs.autorandr ];
+ etc = mkMerge ([
+ (mapAttrs' (hookToFile "postswitch.d") cfg.hooks.postswitch)
+ (mapAttrs' (hookToFile "preswitch.d") cfg.hooks.preswitch)
+ (mapAttrs' (hookToFile "predetect.d") cfg.hooks.predetect)
+ (mkMerge (mapAttrsToList profileToFiles cfg.profiles))
+ ]);
+ };
systemd.services.autorandr = {
wantedBy = [ "sleep.target" ];
@@ -49,5 +355,5 @@ in {
};
- meta.maintainers = with maintainers; [ ];
+ meta.maintainers = with maintainers; [ alexnortung ];
}
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/dendrite.nix b/third_party/nixpkgs/nixos/modules/services/misc/dendrite.nix
index b2885b0941..89bb989a09 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/dendrite.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/dendrite.nix
@@ -248,14 +248,11 @@ in
RuntimeDirectory = "dendrite";
RuntimeDirectoryMode = "0700";
EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
- ExecStartPre =
- if (cfg.environmentFile != null) then ''
- ${pkgs.envsubst}/bin/envsubst \
- -i ${configurationYaml} \
- -o /run/dendrite/dendrite.yaml
- '' else ''
- ${pkgs.coreutils}/bin/cp ${configurationYaml} /run/dendrite/dendrite.yaml
- '';
+ ExecStartPre = ''
+ ${pkgs.envsubst}/bin/envsubst \
+ -i ${configurationYaml} \
+ -o /run/dendrite/dendrite.yaml
+ '';
ExecStart = lib.strings.concatStringsSep " " ([
"${pkgs.dendrite}/bin/dendrite-monolith-server"
"--config /run/dendrite/dendrite.yaml"
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/jellyfin.nix b/third_party/nixpkgs/nixos/modules/services/misc/jellyfin.nix
index 64b74ddd70..04cf82f8a4 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/jellyfin.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/jellyfin.nix
@@ -70,7 +70,8 @@ in
LockPersonality = true;
PrivateTmp = true;
- PrivateDevices = true;
+ # Disabled to allow Jellyfin to access hw accel devices endpoints
+ # PrivateDevices = true;
PrivateUsers = true;
# Disabled as it does not allow Jellyfin to interface with CUDA devices
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/moonraker.nix b/third_party/nixpkgs/nixos/modules/services/misc/moonraker.nix
index ae57aaa6d4..b75227effa 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/moonraker.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/moonraker.nix
@@ -79,6 +79,19 @@ in {
for supported values.
'';
};
+
+ allowSystemControl = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to allow Moonraker to perform system-level operations.
+
+ Moonraker exposes APIs to perform system-level operations, such as
+ reboot, shutdown, and management of systemd units. See the
+ documentation
+ for details on what clients are able to do.
+ '';
+ };
};
};
@@ -86,6 +99,13 @@ in {
warnings = optional (cfg.settings ? update_manager)
''Enabling update_manager is not supported on NixOS and will lead to non-removable warnings in some clients.'';
+ assertions = [
+ {
+ assertion = cfg.allowSystemControl -> config.security.polkit.enable;
+ message = "services.moonraker.allowSystemControl requires polkit to be enabled (security.polkit.enable).";
+ }
+ ];
+
users.users = optionalAttrs (cfg.user == "moonraker") {
moonraker = {
group = cfg.group;
@@ -128,11 +148,31 @@ in {
exec ${pkg}/bin/moonraker -c ${cfg.configDir}/moonraker-temp.cfg
'';
+ # Needs `ip` command
+ path = [ pkgs.iproute2 ];
+
serviceConfig = {
WorkingDirectory = cfg.stateDir;
Group = cfg.group;
User = cfg.user;
};
};
+
+ security.polkit.extraConfig = lib.optionalString cfg.allowSystemControl ''
+ // nixos/moonraker: Allow Moonraker to perform system-level operations
+ //
+ // This was enabled via services.moonraker.allowSystemControl.
+ polkit.addRule(function(action, subject) {
+ if ((action.id == "org.freedesktop.systemd1.manage-units" ||
+ action.id == "org.freedesktop.login1.power-off" ||
+ action.id == "org.freedesktop.login1.power-off-multiple-sessions" ||
+ action.id == "org.freedesktop.login1.reboot" ||
+ action.id == "org.freedesktop.login1.reboot-multiple-sessions" ||
+ action.id.startsWith("org.freedesktop.packagekit.")) &&
+ subject.user == "${cfg.user}") {
+ return polkit.Result.YES;
+ }
+ });
+ '';
};
}
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/nix-daemon.nix b/third_party/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
index 2b21df91b8..4bc5b04d3a 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/nix-daemon.nix
@@ -112,11 +112,11 @@ in
{
imports = [
- (mkRenamedOptionModule [ "nix" "useChroot" ] [ "nix" "useSandbox" ])
- (mkRenamedOptionModule [ "nix" "chrootDirs" ] [ "nix" "sandboxPaths" ])
- (mkRenamedOptionModule [ "nix" "daemonIONiceLevel" ] [ "nix" "daemonIOSchedPriority" ])
+ (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "useChroot" ]; to = [ "nix" "useSandbox" ]; })
+ (mkRenamedOptionModuleWith { sinceRelease = 2003; from = [ "nix" "chrootDirs" ]; to = [ "nix" "sandboxPaths" ]; })
+ (mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" "daemonIONiceLevel" ]; to = [ "nix" "daemonIOSchedPriority" ]; })
(mkRemovedOptionModule [ "nix" "daemonNiceLevel" ] "Consider nix.daemonCPUSchedPolicy instead.")
- ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModule [ "nix" oldConf ] [ "nix" "settings" newConf ]) legacyConfMappings;
+ ] ++ mapAttrsToList (oldConf: newConf: mkRenamedOptionModuleWith { sinceRelease = 2205; from = [ "nix" oldConf ]; to = [ "nix" "settings" newConf ]; }) legacyConfMappings;
###### interface
@@ -409,14 +409,14 @@ in
to = mkOption {
type = referenceAttrs;
example = { type = "github"; owner = "my-org"; repo = "my-nixpkgs"; };
- description = "The flake reference is rewritten to.";
+ description = "The flake reference is rewritten to.";
};
flake = mkOption {
type = types.nullOr types.attrs;
default = null;
example = literalExpression "nixpkgs";
description = ''
- The flake input is rewritten to.
+ The flake input is rewritten to.
'';
};
exact = mkOption {
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/nix-gc.nix b/third_party/nixpkgs/nixos/modules/services/misc/nix-gc.nix
index a7a6a3b596..b4b4b55a6c 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/nix-gc.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/nix-gc.nix
@@ -81,8 +81,14 @@ in
###### implementation
config = {
+ assertions = [
+ {
+ assertion = cfg.automatic -> config.nix.enable;
+ message = ''nix.gc.automatic requires nix.enable'';
+ }
+ ];
- systemd.services.nix-gc = {
+ systemd.services.nix-gc = lib.mkIf config.nix.enable {
description = "Nix Garbage Collector";
script = "exec ${config.nix.package.out}/bin/nix-collect-garbage ${cfg.options}";
startAt = optional cfg.automatic cfg.dates;
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/nix-optimise.nix b/third_party/nixpkgs/nixos/modules/services/misc/nix-optimise.nix
index e02026d5f7..acf8177b14 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/nix-optimise.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/nix-optimise.nix
@@ -37,8 +37,14 @@ in
###### implementation
config = {
+ assertions = [
+ {
+ assertion = cfg.automatic -> config.nix.enable;
+ message = ''nix.optimise.automatic requires nix.enable'';
+ }
+ ];
- systemd.services.nix-optimise =
+ systemd.services.nix-optimise = lib.mkIf config.nix.enable
{ description = "Nix Store Optimiser";
# No point this if the nix daemon (and thus the nix store) is outside
unitConfig.ConditionPathIsReadWrite = "/nix/var/nix/daemon-socket";
diff --git a/third_party/nixpkgs/nixos/modules/services/misc/paperless-ng.nix b/third_party/nixpkgs/nixos/modules/services/misc/paperless-ng.nix
index 44efc234a2..64da340f42 100644
--- a/third_party/nixpkgs/nixos/modules/services/misc/paperless-ng.nix
+++ b/third_party/nixpkgs/nixos/modules/services/misc/paperless-ng.nix
@@ -53,7 +53,6 @@ let
PrivateNetwork = true;
PrivateTmp = true;
PrivateUsers = true;
- ProcSubset = "pid";
ProtectClock = true;
# Breaks if the home dir of the user is in /home
# Also does not add much value in combination with the TemporaryFileSystem.
@@ -214,6 +213,8 @@ in
User = cfg.user;
ExecStart = "${cfg.package}/bin/paperless-ng qcluster";
Restart = "on-failure";
+ # The `mbind` syscall is needed for running the classifier.
+ SystemCallFilter = defaultServiceConfig.SystemCallFilter ++ [ "mbind" ];
};
environment = env;
wantedBy = [ "multi-user.target" ];
diff --git a/third_party/nixpkgs/nixos/modules/services/monitoring/grafana.nix b/third_party/nixpkgs/nixos/modules/services/monitoring/grafana.nix
index 81fca33f5f..b959379d33 100644
--- a/third_party/nixpkgs/nixos/modules/services/monitoring/grafana.nix
+++ b/third_party/nixpkgs/nixos/modules/services/monitoring/grafana.nix
@@ -214,6 +214,11 @@ let
type = types.path;
description = "Path grafana will watch for dashboards.";
};
+ foldersFromFilesStructure = mkOption {
+ type = types.bool;
+ default = false;
+ description = "Use folder names from filesystem to create folders in Grafana.";
+ };
};
};
};
diff --git a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
index d29d50706e..41302d6d3c 100644
--- a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
+++ b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters.nix
@@ -29,6 +29,7 @@ let
"blackbox"
"buildkite-agent"
"collectd"
+ "dmarc"
"dnsmasq"
"domain"
"dovecot"
@@ -55,6 +56,7 @@ let
"postfix"
"postgres"
"process"
+ "pve"
"py-air-control"
"redis"
"rspamd"
diff --git a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix
new file mode 100644
index 0000000000..330610a15d
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/dmarc.nix
@@ -0,0 +1,117 @@
+{ config, lib, pkgs, options }:
+
+with lib;
+
+let
+ cfg = config.services.prometheus.exporters.dmarc;
+
+ json = builtins.toJSON {
+ inherit (cfg) folders port;
+ listen_addr = cfg.listenAddress;
+ storage_path = "$STATE_DIRECTORY";
+ imap = (builtins.removeAttrs cfg.imap [ "passwordFile" ]) // { password = "$IMAP_PASSWORD"; use_ssl = true; };
+ poll_interval_seconds = cfg.pollIntervalSeconds;
+ deduplication_max_seconds = cfg.deduplicationMaxSeconds;
+ logging = {
+ version = 1;
+ disable_existing_loggers = false;
+ };
+ };
+in {
+ port = 9797;
+ extraOpts = {
+ imap = {
+ host = mkOption {
+ type = types.str;
+ default = "localhost";
+ description = ''
+ Hostname of IMAP server to connect to.
+ '';
+ };
+ port = mkOption {
+ type = types.port;
+ default = 993;
+ description = ''
+ Port of the IMAP server to connect to.
+ '';
+ };
+ username = mkOption {
+ type = types.str;
+ example = "postmaster@example.org";
+ description = ''
+ Login username for the IMAP connection.
+ '';
+ };
+ passwordFile = mkOption {
+ type = types.str;
+ example = "/run/secrets/dovecot_pw";
+ description = ''
+ File containing the login password for the IMAP connection.
+ '';
+ };
+ };
+ folders = {
+ inbox = mkOption {
+ type = types.str;
+ default = "INBOX";
+ description = ''
+ IMAP mailbox that is checked for incoming DMARC aggregate reports
+ '';
+ };
+ done = mkOption {
+ type = types.str;
+ default = "Archive";
+ description = ''
+ IMAP mailbox that successfully processed reports are moved to.
+ '';
+ };
+ error = mkOption {
+ type = types.str;
+ default = "Invalid";
+ description = ''
+ IMAP mailbox that emails are moved to that could not be processed.
+ '';
+ };
+ };
+ pollIntervalSeconds = mkOption {
+ type = types.ints.unsigned;
+ default = 60;
+ description = ''
+ How often to poll the IMAP server in seconds.
+ '';
+ };
+ deduplicationMaxSeconds = mkOption {
+ type = types.ints.unsigned;
+ default = 604800;
+ defaultText = "7 days (in seconds)";
+ description = ''
+ How long individual report IDs will be remembered to avoid
+ counting double delivered reports twice.
+ '';
+ };
+ debug = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether to declare enable --debug.
+ '';
+ };
+ };
+ serviceOpts = {
+ path = with pkgs; [ envsubst coreutils ];
+ serviceConfig = {
+ StateDirectory = "prometheus-dmarc-exporter";
+ WorkingDirectory = "/var/lib/prometheus-dmarc-exporter";
+ ExecStart = "${pkgs.writeShellScript "setup-cfg" ''
+ export IMAP_PASSWORD="$(<${cfg.imap.passwordFile})"
+ envsubst \
+ -i ${pkgs.writeText "dmarc-exporter.json.template" json} \
+ -o ''${STATE_DIRECTORY}/dmarc-exporter.json
+
+ exec ${pkgs.prometheus-dmarc-exporter}/bin/prometheus-dmarc-exporter \
+ --configuration /var/lib/prometheus-dmarc-exporter/dmarc-exporter.json \
+ ${optionalString cfg.debug "--debug"}
+ ''}";
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/kea.nix b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/kea.nix
index 27aeb90962..e0ee90d9b9 100644
--- a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/kea.nix
+++ b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/kea.nix
@@ -25,6 +25,10 @@ in {
};
};
serviceOpts = {
+ after = [
+ "kea-dhcp4-server.service"
+ "kea-dhcp6-server.service"
+ ];
serviceConfig = {
User = "kea";
ExecStart = ''
diff --git a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/pve.nix b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/pve.nix
new file mode 100644
index 0000000000..ef708414c9
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/pve.nix
@@ -0,0 +1,118 @@
+{ config, lib, pkgs, options }:
+
+with lib;
+let
+ cfg = config.services.prometheus.exporters.pve;
+
+ # pve exporter requires a config file so create an empty one if configFile is not provided
+ emptyConfigFile = pkgs.writeTextFile {
+ name = "pve.yml";
+ text = "default:";
+ };
+
+ computedConfigFile = "${if cfg.configFile == null then emptyConfigFile else cfg.configFile}";
+in
+{
+ port = 9221;
+ extraOpts = {
+ package = mkOption {
+ type = types.package;
+ default = pkgs.prometheus-pve-exporter;
+ defaultText = literalExpression "pkgs.prometheus-pve-exporter";
+ example = literalExpression "pkgs.prometheus-pve-exporter";
+ description = ''
+ The package to use for prometheus-pve-exporter
+ '';
+ };
+
+ environmentFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "/etc/prometheus-pve-exporter/pve.env";
+ description = ''
+ Path to the service's environment file. This path can either be a computed path in /nix/store or a path in the local filesystem.
+
+ The environment file should NOT be stored in /nix/store as it contains passwords and/or keys in plain text.
+
+ Environment reference: https://github.com/prometheus-pve/prometheus-pve-exporter#authentication
+ '';
+ };
+
+ configFile = mkOption {
+ type = with types; nullOr path;
+ default = null;
+ example = "/etc/prometheus-pve-exporter/pve.yml";
+ description = ''
+ Path to the service's config file. This path can either be a computed path in /nix/store or a path in the local filesystem.
+
+ The config file should NOT be stored in /nix/store as it will contain passwords and/or keys in plain text.
+
+ If both configFile and environmentFile are provided, the configFile option will be ignored.
+
+ Configuration reference: https://github.com/prometheus-pve/prometheus-pve-exporter/#authentication
+ '';
+ };
+
+ collectors = {
+ status = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect Node/VM/CT status
+ '';
+ };
+ version = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE version info
+ '';
+ };
+ node = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE node info
+ '';
+ };
+ cluster = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE cluster info
+ '';
+ };
+ resources = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE resources info
+ '';
+ };
+ config = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Collect PVE onboot status
+ '';
+ };
+ };
+ };
+ serviceOpts = {
+ serviceConfig = {
+ ExecStart = ''
+ ${cfg.package}/bin/pve_exporter \
+ --${if cfg.collectors.status == true then "" else "no-"}collector.status \
+ --${if cfg.collectors.version == true then "" else "no-"}collector.version \
+ --${if cfg.collectors.node == true then "" else "no-"}collector.node \
+ --${if cfg.collectors.cluster == true then "" else "no-"}collector.cluster \
+ --${if cfg.collectors.resources == true then "" else "no-"}collector.resources \
+ --${if cfg.collectors.config == true then "" else "no-"}collector.config \
+ ${computedConfigFile} \
+ ${toString cfg.port} ${cfg.listenAddress}
+ '';
+ } // optionalAttrs (cfg.environmentFile != null) {
+ EnvironmentFile = cfg.environmentFile;
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix
index 5b5a6e18fc..ede6028933 100644
--- a/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix
+++ b/third_party/nixpkgs/nixos/modules/services/monitoring/prometheus/exporters/varnish.nix
@@ -45,7 +45,8 @@ in
};
instance = mkOption {
type = types.nullOr types.str;
- default = null;
+ default = config.services.varnish.stateDir;
+ defaultText = lib.literalExpression "config.services.varnish.stateDir";
description = ''
varnishstat -n value.
'';
@@ -66,7 +67,7 @@ in
};
};
serviceOpts = {
- path = [ pkgs.varnish ];
+ path = [ config.services.varnish.package ];
serviceConfig = {
RestartSec = mkDefault 1;
DynamicUser = false;
diff --git a/third_party/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix b/third_party/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
index 17da020bf3..7e96179b3c 100644
--- a/third_party/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
+++ b/third_party/nixpkgs/nixos/modules/services/network-filesystems/ipfs.nix
@@ -1,16 +1,17 @@
-{ config, lib, pkgs, options, ... }:
+{ config, lib, pkgs, options, utils, ... }:
with lib;
let
cfg = config.services.ipfs;
opt = options.services.ipfs;
- ipfsFlags = toString ([
- (optionalString cfg.autoMount "--mount")
- (optionalString cfg.enableGC "--enable-gc")
- (optionalString (cfg.serviceFdlimit != null) "--manage-fdlimit=false")
- (optionalString (cfg.defaultMode == "offline") "--offline")
- (optionalString (cfg.defaultMode == "norouting") "--routing=none")
- ] ++ cfg.extraFlags);
+ ipfsFlags = utils.escapeSystemdExecArgs (
+ optional cfg.autoMount "--mount" ++
+ optional cfg.enableGC "--enable-gc" ++
+ optional (cfg.serviceFdlimit != null) "--manage-fdlimit=false" ++
+ optional (cfg.defaultMode == "offline") "--offline" ++
+ optional (cfg.defaultMode == "norouting") "--routing=none" ++
+ cfg.extraFlags
+ );
profile =
if cfg.localDiscovery
@@ -239,7 +240,10 @@ in
"d '${cfg.ipnsMountDir}' - ${cfg.user} ${cfg.group} - -"
];
- systemd.packages = [ cfg.package ];
+ # The hardened systemd unit breaks the fuse-mount function according to documentation in the unit file itself
+ systemd.packages = if cfg.autoMount
+ then [ cfg.package.systemd_unit ]
+ else [ cfg.package.systemd_unit_hardened ];
systemd.services.ipfs = {
path = [ "/run/wrappers" cfg.package ];
@@ -275,6 +279,8 @@ in
ExecStart = [ "" "${cfg.package}/bin/ipfs daemon ${ipfsFlags}" ];
User = cfg.user;
Group = cfg.group;
+ StateDirectory = "";
+ ReadWritePaths = [ "" cfg.dataDir ];
} // optionalAttrs (cfg.serviceFdlimit != null) { LimitNOFILE = cfg.serviceFdlimit; };
} // optionalAttrs (!cfg.startWhenNeeded) {
wantedBy = [ "default.target" ];
diff --git a/third_party/nixpkgs/nixos/modules/services/network-filesystems/samba.nix b/third_party/nixpkgs/nixos/modules/services/network-filesystems/samba.nix
index 9ed755d046..992f948e8c 100644
--- a/third_party/nixpkgs/nixos/modules/services/network-filesystems/samba.nix
+++ b/third_party/nixpkgs/nixos/modules/services/network-filesystems/samba.nix
@@ -224,6 +224,7 @@ in
targets.samba = {
description = "Samba Server";
after = [ "network.target" ];
+ wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
};
# Refer to https://github.com/samba-team/samba/tree/master/packaging/systemd
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/amuled.nix b/third_party/nixpkgs/nixos/modules/services/networking/amuled.nix
index e55ac7a6b1..aa72a04752 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/amuled.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/amuled.nix
@@ -76,7 +76,7 @@ in
script = ''
${pkgs.su}/bin/su -s ${pkgs.runtimeShell} ${user} \
- -c 'HOME="${cfg.dataDir}" ${pkgs.amuleDaemon}/bin/amuled'
+ -c 'HOME="${cfg.dataDir}" ${pkgs.amule-daemon}/bin/amuled'
'';
};
};
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/dhcpd.nix b/third_party/nixpkgs/nixos/modules/services/networking/dhcpd.nix
index 3c4c0069df..49950efc0a 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/dhcpd.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/dhcpd.nix
@@ -7,7 +7,7 @@ let
cfg4 = config.services.dhcpd4;
cfg6 = config.services.dhcpd6;
- writeConfig = cfg: pkgs.writeText "dhcpd.conf"
+ writeConfig = postfix: cfg: pkgs.writeText "dhcpd.conf"
''
default-lease-time 600;
max-lease-time 7200;
@@ -21,7 +21,9 @@ let
(machine: ''
host ${machine.hostName} {
hardware ethernet ${machine.ethernetAddress};
- fixed-address ${machine.ipAddress};
+ fixed-address${
+ optionalString (postfix == "6") postfix
+ } ${machine.ipAddress};
}
'')
cfg.machines
@@ -33,7 +35,7 @@ let
configFile =
if cfg.configFile != null
then cfg.configFile
- else writeConfig cfg;
+ else writeConfig postfix cfg;
leaseFile = "/var/lib/dhcpd${postfix}/dhcpd.leases";
args = [
"@${pkgs.dhcp}/sbin/dhcpd" "dhcpd${postfix}" "-${postfix}"
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/https-dns-proxy.nix b/third_party/nixpkgs/nixos/modules/services/networking/https-dns-proxy.nix
new file mode 100644
index 0000000000..85d6c362b4
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/networking/https-dns-proxy.nix
@@ -0,0 +1,128 @@
+{ config, lib, pkgs, ... }:
+
+let
+ inherit (lib)
+ concatStringsSep
+ mkEnableOption mkIf mkOption types;
+
+ cfg = config.services.https-dns-proxy;
+
+ providers = {
+ cloudflare = {
+ ips = [ "1.1.1.1" "1.0.0.1" ];
+ url = "https://cloudflare-dns.com/dns-query";
+ };
+ google = {
+ ips = [ "8.8.8.8" "8.8.4.4" ];
+ url = "https://dns.google/dns-query";
+ };
+ quad9 = {
+ ips = [ "9.9.9.9" "149.112.112.112" ];
+ url = "https://dns.quad9.net/dns-query";
+ };
+ };
+
+ defaultProvider = "quad9";
+
+ providerCfg =
+ let
+ isCustom = cfg.provider.kind == "custom";
+ in
+ lib.concatStringsSep " " [
+ "-b"
+ (concatStringsSep "," (if isCustom then cfg.provider.ips else providers."${cfg.provider.kind}".ips))
+ "-r"
+ (if isCustom then cfg.provider.url else providers."${cfg.provider.kind}".url)
+ ];
+
+in
+{
+ meta.maintainers = with lib.maintainers; [ peterhoeg ];
+
+ ###### interface
+
+ options.services.https-dns-proxy = {
+ enable = mkEnableOption "https-dns-proxy daemon";
+
+ address = mkOption {
+ description = "The address on which to listen";
+ type = types.str;
+ default = "127.0.0.1";
+ };
+
+ port = mkOption {
+ description = "The port on which to listen";
+ type = types.port;
+ default = 5053;
+ };
+
+ provider = {
+ kind = mkOption {
+ description = ''
+ The upstream provider to use or custom in case you do not trust any of
+ the predefined providers or just want to use your own.
+
+ The default is ${defaultProvider} and there are privacy and security trade-offs
+ when using any upstream provider. Please consider that before using any
+ of them.
+
+ If you pick a custom provider, you will need to provide the bootstrap
+ IP addresses as well as the resolver https URL.
+ '';
+ type = types.enum ((builtins.attrNames providers) ++ [ "custom" ]);
+ default = defaultProvider;
+ };
+
+ ips = mkOption {
+ description = "The custom provider IPs";
+ type = types.listOf types.str;
+ };
+
+ url = mkOption {
+ description = "The custom provider URL";
+ type = types.str;
+ };
+ };
+
+ preferIPv4 = mkOption {
+ description = ''
+ https_dns_proxy will by default use IPv6 and fail if it is not available.
+ To play it safe, we choose IPv4.
+ '';
+ type = types.bool;
+ default = true;
+ };
+
+ extraArgs = mkOption {
+ description = "Additional arguments to pass to the process.";
+ type = types.listOf types.str;
+ default = [ "-v" ];
+ };
+ };
+
+ ###### implementation
+
+ config = lib.mkIf cfg.enable {
+ systemd.services.https-dns-proxy = {
+ description = "DNS to DNS over HTTPS (DoH) proxy";
+ after = [ "network.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = rec {
+ Type = "exec";
+ DynamicUser = true;
+ ExecStart = lib.concatStringsSep " " (
+ [
+ "${pkgs.https-dns-proxy}/bin/https_dns_proxy"
+ "-a ${toString cfg.address}"
+ "-p ${toString cfg.port}"
+ "-l -"
+ providerCfg
+ ]
+ ++ lib.optional cfg.preferIPv4 "-4"
+ ++ cfg.extraArgs
+ );
+ Restart = "on-failure";
+ };
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/iwd.nix b/third_party/nixpkgs/nixos/modules/services/networking/iwd.nix
index 8835f7f937..5c1480e7e2 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/iwd.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/iwd.nix
@@ -1,12 +1,21 @@
{ config, lib, pkgs, ... }:
-with lib;
-
let
+ inherit (lib)
+ mkEnableOption mkIf mkOption types
+ recursiveUpdate;
+
cfg = config.networking.wireless.iwd;
ini = pkgs.formats.ini { };
- configFile = ini.generate "main.conf" cfg.settings;
-in {
+ defaults = {
+ # without UseDefaultInterface, sometimes wlan0 simply goes AWOL with NetworkManager
+ # https://iwd.wiki.kernel.org/interface_lifecycle#interface_management_in_iwd
+ General.UseDefaultInterface = with config.networking.networkmanager; (enable && (wifi.backend == "iwd"));
+ };
+ configFile = ini.generate "main.conf" (recursiveUpdate defaults cfg.settings);
+
+in
+{
options.networking.wireless.iwd = {
enable = mkEnableOption "iwd";
@@ -38,10 +47,10 @@ in {
'';
}];
- environment.etc."iwd/main.conf".source = configFile;
+ environment.etc."iwd/${configFile.name}".source = configFile;
# for iwctl
- environment.systemPackages = [ pkgs.iwd ];
+ environment.systemPackages = [ pkgs.iwd ];
services.dbus.packages = [ pkgs.iwd ];
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/nbd.nix b/third_party/nixpkgs/nixos/modules/services/networking/nbd.nix
new file mode 100644
index 0000000000..87f8c41a8e
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/networking/nbd.nix
@@ -0,0 +1,146 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.nbd;
+ configFormat = pkgs.formats.ini { };
+ iniFields = with types; attrsOf (oneOf [ bool int float str ]);
+ serverConfig = configFormat.generate "nbd-server-config"
+ ({
+ generic =
+ (cfg.server.extraOptions // {
+ user = "root";
+ group = "root";
+ port = cfg.server.listenPort;
+ } // (optionalAttrs (cfg.server.listenAddress != null) {
+ listenaddr = cfg.server.listenAddress;
+ }));
+ }
+ // (mapAttrs
+ (_: { path, allowAddresses, extraOptions }:
+ extraOptions // {
+ exportname = path;
+ } // (optionalAttrs (allowAddresses != null) {
+ authfile = pkgs.writeText "authfile" (concatStringsSep "\n" allowAddresses);
+ }))
+ cfg.server.exports)
+ );
+ splitLists =
+ partition
+ (path: hasPrefix "/dev/" path)
+ (mapAttrsToList (_: { path, ... }: path) cfg.server.exports);
+ allowedDevices = splitLists.right;
+ boundPaths = splitLists.wrong;
+in
+{
+ options = {
+ services.nbd = {
+ server = {
+ enable = mkEnableOption "the Network Block Device (nbd) server";
+
+ listenPort = mkOption {
+ type = types.port;
+ default = 10809;
+ description = "Port to listen on. The port is NOT automatically opened in the firewall.";
+ };
+
+ extraOptions = mkOption {
+ type = iniFields;
+ default = {
+ allowlist = false;
+ };
+ description = ''
+ Extra options for the server. See
+ nbd-server
+ 5.
+ '';
+ };
+
+ exports = mkOption {
+ description = "Files or block devices to make available over the network.";
+ default = { };
+ type = with types; attrsOf
+ (submodule {
+ options = {
+ path = mkOption {
+ type = str;
+ description = "File or block device to export.";
+ example = "/dev/sdb1";
+ };
+
+ allowAddresses = mkOption {
+ type = nullOr (listOf str);
+ default = null;
+ example = [ "10.10.0.0/24" "127.0.0.1" ];
+ description = "IPs and subnets that are authorized to connect for this device. If not specified, the server will allow all connections.";
+ };
+
+ extraOptions = mkOption {
+ type = iniFields;
+ default = {
+ flush = true;
+ fua = true;
+ };
+ description = ''
+ Extra options for this export. See
+ nbd-server
+ 5.
+ '';
+ };
+ };
+ });
+ };
+
+ listenAddress = mkOption {
+ type = with types; nullOr str;
+ description = "Address to listen on. If not specified, the server will listen on all interfaces.";
+ default = null;
+ example = "10.10.0.1";
+ };
+ };
+ };
+ };
+
+ config = mkIf cfg.server.enable {
+ boot.kernelModules = [ "nbd" ];
+
+ systemd.services.nbd-server = {
+ after = [ "network-online.target" ];
+ before = [ "multi-user.target" ];
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ ExecStart = "${pkgs.nbd}/bin/nbd-server -C ${serverConfig}";
+ Type = "forking";
+
+ DeviceAllow = map (path: "${path} rw") allowedDevices;
+ BindPaths = boundPaths;
+
+ CapabilityBoundingSet = "";
+ DevicePolicy = "closed";
+ LockPersonality = true;
+ MemoryDenyWriteExecute = true;
+ NoNewPrivileges = true;
+ PrivateDevices = false;
+ PrivateMounts = true;
+ PrivateTmp = true;
+ PrivateUsers = true;
+ ProcSubset = "pid";
+ ProtectClock = true;
+ ProtectControlGroups = true;
+ ProtectHome = true;
+ ProtectHostname = true;
+ ProtectKernelLogs = true;
+ ProtectKernelModules = true;
+ ProtectKernelTunables = true;
+ ProtectProc = "noaccess";
+ ProtectSystem = "strict";
+ RestrictAddressFamilies = "AF_INET AF_INET6";
+ RestrictNamespaces = true;
+ RestrictRealtime = true;
+ RestrictSUIDSGID = true;
+ UMask = "0077";
+ };
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/nsd.nix b/third_party/nixpkgs/nixos/modules/services/networking/nsd.nix
index cf6c9661dc..a51fc53453 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/nsd.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/nsd.nix
@@ -194,19 +194,8 @@ let
zone.children
);
- # fighting infinite recursion
- zoneOptions = zoneOptionsRaw // childConfig zoneOptions1 true;
- zoneOptions1 = zoneOptionsRaw // childConfig zoneOptions2 false;
- zoneOptions2 = zoneOptionsRaw // childConfig zoneOptions3 false;
- zoneOptions3 = zoneOptionsRaw // childConfig zoneOptions4 false;
- zoneOptions4 = zoneOptionsRaw // childConfig zoneOptions5 false;
- zoneOptions5 = zoneOptionsRaw // childConfig zoneOptions6 false;
- zoneOptions6 = zoneOptionsRaw // childConfig null false;
-
- childConfig = x: v: { options.children = { type = types.attrsOf x; visible = v; }; };
-
# options are ordered alphanumerically
- zoneOptionsRaw = types.submodule {
+ zoneOptions = types.submodule {
options = {
allowAXFRFallback = mkOption {
@@ -246,6 +235,13 @@ let
};
children = mkOption {
+ # TODO: This relies on the fact that `types.anything` doesn't set any
+ # values of its own to any defaults, because in the above zoneConfigs',
+ # values from children override ones from parents, but only if the
+ # attributes are defined. Because of this, we can't replace the element
+ # type here with `zoneConfigs`, since that would set all the attributes
+ # to default values, breaking the parent inheriting function.
+ type = types.attrsOf types.anything;
default = {};
description = ''
Children zones inherit all options of their parents. Attributes
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/pleroma.nix b/third_party/nixpkgs/nixos/modules/services/networking/pleroma.nix
index 9b8382392c..c6d4c14dcb 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/pleroma.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/pleroma.nix
@@ -1,6 +1,7 @@
{ config, options, lib, pkgs, stdenv, ... }:
let
cfg = config.services.pleroma;
+ cookieFile = "/var/lib/pleroma/.cookie";
in {
options = {
services.pleroma = with lib; {
@@ -8,7 +9,7 @@ in {
package = mkOption {
type = types.package;
- default = pkgs.pleroma;
+ default = pkgs.pleroma.override { inherit cookieFile; };
defaultText = literalExpression "pkgs.pleroma";
description = "Pleroma package to use.";
};
@@ -100,7 +101,6 @@ in {
after = [ "network-online.target" "postgresql.service" ];
wantedBy = [ "multi-user.target" ];
restartTriggers = [ config.environment.etc."/pleroma/config.exs".source ];
- environment.RELEASE_COOKIE = "/var/lib/pleroma/.cookie";
serviceConfig = {
User = cfg.user;
Group = cfg.group;
@@ -118,10 +118,10 @@ in {
# Better be safe than sorry migration-wise.
ExecStartPre =
let preScript = pkgs.writers.writeBashBin "pleromaStartPre" ''
- if [ ! -f /var/lib/pleroma/.cookie ]
+ if [ ! -f "${cookieFile}" ] || [ ! -s "${cookieFile}" ]
then
echo "Creating cookie file"
- dd if=/dev/urandom bs=1 count=16 | hexdump -e '16/1 "%02x"' > /var/lib/pleroma/.cookie
+ dd if=/dev/urandom bs=1 count=16 | ${pkgs.hexdump}/bin/hexdump -e '16/1 "%02x"' > "${cookieFile}"
fi
${cfg.package}/bin/pleroma_ctl migrate
'';
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/powerdns.nix b/third_party/nixpkgs/nixos/modules/services/networking/powerdns.nix
index 8cae61b835..b035698456 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/powerdns.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/powerdns.nix
@@ -24,14 +24,14 @@ in {
config = mkIf cfg.enable {
- systemd.packages = [ pkgs.powerdns ];
+ systemd.packages = [ pkgs.pdns ];
systemd.services.pdns = {
wantedBy = [ "multi-user.target" ];
after = [ "network.target" "mysql.service" "postgresql.service" "openldap.service" ];
serviceConfig = {
- ExecStart = [ "" "${pkgs.powerdns}/bin/pdns_server --config-dir=${configDir} --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no" ];
+ ExecStart = [ "" "${pkgs.pdns}/bin/pdns_server --config-dir=${configDir} --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no" ];
};
};
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/squid.nix b/third_party/nixpkgs/nixos/modules/services/networking/squid.nix
index 4f3881af8b..db4f0d26b6 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/squid.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/squid.nix
@@ -111,6 +111,13 @@ in
description = "Whether to run squid web proxy.";
};
+ package = mkOption {
+ default = pkgs.squid;
+ defaultText = literalExpression "pkgs.squid";
+ type = types.package;
+ description = "Squid package to use.";
+ };
+
proxyAddress = mkOption {
type = types.nullOr types.str;
default = null;
@@ -157,17 +164,21 @@ in
users.groups.squid = {};
systemd.services.squid = {
- description = "Squid caching web proxy";
+ description = "Squid caching proxy";
+ documentation = [ "man:squid(8)" ];
after = [ "network.target" "nss-lookup.target" ];
wantedBy = [ "multi-user.target"];
preStart = ''
mkdir -p "/var/log/squid"
chown squid:squid "/var/log/squid"
+ ${cfg.package}/bin/squid --foreground -z -f ${squidConfig}
'';
serviceConfig = {
- Type="forking";
PIDFile="/run/squid.pid";
- ExecStart = "${pkgs.squid}/bin/squid -YCs -f ${squidConfig}";
+ ExecStart = "${cfg.package}/bin/squid --foreground -YCs -f ${squidConfig}";
+ ExecReload="kill -HUP $MAINPID";
+ KillMode="mixed";
+ NotifyAccess="all";
};
};
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/tox-node.nix b/third_party/nixpkgs/nixos/modules/services/networking/tox-node.nix
index c24e7fd128..c6e5c2d6e8 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/tox-node.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/tox-node.nix
@@ -8,12 +8,7 @@ let
homeDir = "/var/lib/tox-node";
configFile = let
- # fetchurl should be switched to getting this file from tox-node.src once
- # the dpkg directory is in a release
- src = pkgs.fetchurl {
- url = "https://raw.githubusercontent.com/tox-rs/tox-node/master/dpkg/config.yml";
- sha256 = "1431wzpzm786mcvyzk1rp7ar418n45dr75hdggxvlm7pkpam31xa";
- };
+ src = "${pkg.src}/dpkg/config.yml";
confJSON = pkgs.writeText "config.json" (
builtins.toJSON {
log-type = cfg.logType;
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/unbound.nix b/third_party/nixpkgs/nixos/modules/services/networking/unbound.nix
index f6e9634909..87873c8c1e 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/unbound.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/unbound.nix
@@ -62,6 +62,7 @@ in {
};
stateDir = mkOption {
+ type = types.path;
default = "/var/lib/unbound";
description = "Directory holding all state for unbound to run.";
};
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/vsftpd.nix b/third_party/nixpkgs/nixos/modules/services/networking/vsftpd.nix
index 710c2d9ca1..d205302051 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/vsftpd.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/vsftpd.nix
@@ -153,6 +153,7 @@ in
userlist = mkOption {
default = [];
+ type = types.listOf types.str;
description = "See .";
};
diff --git a/third_party/nixpkgs/nixos/modules/services/networking/wg-quick.nix b/third_party/nixpkgs/nixos/modules/services/networking/wg-quick.nix
index 414775fc35..61e9fe5096 100644
--- a/third_party/nixpkgs/nixos/modules/services/networking/wg-quick.nix
+++ b/third_party/nixpkgs/nixos/modules/services/networking/wg-quick.nix
@@ -17,6 +17,13 @@ let
description = "The IP addresses of the interface.";
};
+ autostart = mkOption {
+ description = "Whether to bring up this interface automatically during boot.";
+ default = true;
+ example = false;
+ type = types.bool;
+ };
+
dns = mkOption {
example = [ "192.168.2.2" ];
default = [];
@@ -247,7 +254,7 @@ let
description = "wg-quick WireGuard Tunnel - ${name}";
requires = [ "network-online.target" ];
after = [ "network.target" "network-online.target" ];
- wantedBy = [ "multi-user.target" ];
+ wantedBy = optional values.autostart "multi-user.target";
environment.DEVICE = name;
path = [ pkgs.kmod pkgs.wireguard-tools ];
diff --git a/third_party/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix b/third_party/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix
index 4d35624241..ce295bd4ba 100644
--- a/third_party/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix
+++ b/third_party/nixpkgs/nixos/modules/services/security/oauth2_proxy.nix
@@ -102,17 +102,19 @@ in
# Taken from: https://github.com/oauth2-proxy/oauth2-proxy/blob/master/providers/providers.go
provider = mkOption {
type = types.enum [
- "google"
+ "adfs"
"azure"
+ "bitbucket"
+ "digitalocean"
"facebook"
"github"
- "keycloak"
"gitlab"
+ "google"
+ "keycloak"
+ "keycloak-oidc"
"linkedin"
"login.gov"
- "bitbucket"
"nextcloud"
- "digitalocean"
"oidc"
];
default = "google";
diff --git a/third_party/nixpkgs/nixos/modules/services/security/sslmate-agent.nix b/third_party/nixpkgs/nixos/modules/services/security/sslmate-agent.nix
new file mode 100644
index 0000000000..c850eb22a0
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/security/sslmate-agent.nix
@@ -0,0 +1,32 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.sslmate-agent;
+
+in {
+ meta.maintainers = with maintainers; [ wolfangaukang ];
+
+ options = {
+ services.sslmate-agent = {
+ enable = mkEnableOption "sslmate-agent, a daemon for managing SSL/TLS certificates on a server";
+ };
+ };
+
+ config = mkIf cfg.enable {
+ environment.systemPackages = with pkgs; [ sslmate-agent ];
+
+ systemd = {
+ packages = [ pkgs.sslmate-agent ];
+ services.sslmate-agent = {
+ wantedBy = [ "multi-user.target" ];
+ serviceConfig = {
+ ConfigurationDirectory = "sslmate-agent";
+ LogsDirectory = "sslmate-agent";
+ StateDirectory = "sslmate-agent";
+ };
+ };
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/security/tor.nix b/third_party/nixpkgs/nixos/modules/services/security/tor.nix
index 3bf70c4aa4..a5822c0279 100644
--- a/third_party/nixpkgs/nixos/modules/services/security/tor.nix
+++ b/third_party/nixpkgs/nixos/modules/services/security/tor.nix
@@ -910,6 +910,11 @@ in
ORPort = mkForce [];
PublishServerDescriptor = mkForce false;
})
+ (mkIf (!cfg.client.enable) {
+ # Make sure application connections via SOCKS are disabled
+ # when services.tor.client.enable is false
+ SOCKSPort = mkForce [ 0 ];
+ })
(mkIf cfg.client.enable (
{ SOCKSPort = [ cfg.client.socksListenAddress ];
} // optionalAttrs cfg.client.transparentProxy.enable {
@@ -1008,7 +1013,11 @@ in
#InaccessiblePaths = [ "-+${runDir}/root" ];
UMask = "0066";
BindPaths = [ stateDir ];
- BindReadOnlyPaths = [ storeDir "/etc" ];
+ BindReadOnlyPaths = [ storeDir "/etc" ] ++
+ optionals config.services.resolved.enable [
+ "/run/systemd/resolve/stub-resolv.conf"
+ "/run/systemd/resolve/resolv.conf"
+ ];
AmbientCapabilities = [""] ++ lib.optional bindsPrivilegedPort "CAP_NET_BIND_SERVICE";
CapabilityBoundingSet = [""] ++ lib.optional bindsPrivilegedPort "CAP_NET_BIND_SERVICE";
# ProtectClock= adds DeviceAllow=char-rtc r
diff --git a/third_party/nixpkgs/nixos/modules/services/system/earlyoom.nix b/third_party/nixpkgs/nixos/modules/services/system/earlyoom.nix
index b355df056b..6293585598 100644
--- a/third_party/nixpkgs/nixos/modules/services/system/earlyoom.nix
+++ b/third_party/nixpkgs/nixos/modules/services/system/earlyoom.nix
@@ -1,81 +1,121 @@
{ config, lib, pkgs, ... }:
-with lib;
-
let
- ecfg = config.services.earlyoom;
+ cfg = config.services.earlyoom;
+
+ inherit (lib)
+ mkDefault mkEnableOption mkIf mkOption types
+ mkRemovedOptionModule literalExpression
+ escapeShellArg concatStringsSep optional optionalString;
+
in
{
- options = {
- services.earlyoom = {
+ options.services.earlyoom = {
+ enable = mkEnableOption "Early out of memory killing";
- enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Enable early out of memory killing.
- '';
- };
+ freeMemThreshold = mkOption {
+ type = types.ints.between 1 100;
+ default = 10;
+ description = ''
+ Minimum available memory (in percent).
- freeMemThreshold = mkOption {
- type = types.int;
- default = 10;
- description = ''
- Minimum of availabe memory (in percent).
- If the free memory falls below this threshold and the analog is true for
-
- the killing begins.
- '';
- };
+ If the available memory falls below this threshold (and the analog is true for
+ ) the killing begins.
+ SIGTERM is sent first to the process that uses the most memory; then, if the available
+ memory falls below (and the analog is true for
+ ), SIGKILL is sent.
- freeSwapThreshold = mkOption {
- type = types.int;
- default = 10;
- description = ''
- Minimum of availabe swap space (in percent).
- If the available swap space falls below this threshold and the analog
- is true for
- the killing begins.
- '';
- };
+ See README for details.
+ '';
+ };
- # TODO: remove or warn after 1.7 (https://github.com/rfjakob/earlyoom/commit/7ebc4554)
- ignoreOOMScoreAdjust = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Ignore oom_score_adjust values of processes.
- '';
- };
+ freeMemKillThreshold = mkOption {
+ type = types.nullOr (types.ints.between 1 100);
+ default = null;
+ description = ''
+ Minimum available memory (in percent) before sending SIGKILL.
+ If unset, this defaults to half of .
- enableDebugInfo = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Enable debugging messages.
- '';
- };
+ See the description of .
+ '';
+ };
- notificationsCommand = mkOption {
- type = types.nullOr types.str;
- default = null;
- description = ''
- This option is deprecated and ignored by earlyoom since 1.6.
- Use instead.
- '';
- };
+ freeSwapThreshold = mkOption {
+ type = types.ints.between 1 100;
+ default = 10;
+ description = ''
+ Minimum free swap space (in percent) before sending SIGTERM.
- enableNotifications = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Send notifications about killed processes via the system d-bus.
- To actually see the notifications in your GUI session, you need to have
- systembus-notify running as your user.
+ See the description of .
+ '';
+ };
- See README for details.
- '';
- };
+ freeSwapKillThreshold = mkOption {
+ type = types.nullOr (types.ints.between 1 100);
+ default = null;
+ description = ''
+ Minimum free swap space (in percent) before sending SIGKILL.
+ If unset, this defaults to half of .
+
+ See the description of .
+ '';
+ };
+
+ enableDebugInfo = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Enable debugging messages.
+ '';
+ };
+
+ enableNotifications = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Send notifications about killed processes via the system d-bus.
+
+ WARNING: enabling this option (while convenient) should *not* be done on a
+ machine where you do not trust the other users as it allows any other
+ local user to DoS your session by spamming notifications.
+
+ To actually see the notifications in your GUI session, you need to have
+ systembus-notify running as your user, which this
+ option handles by enabling .
+
+ See README for details.
+ '';
+ };
+
+ killHook = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = literalExpression ''
+ pkgs.writeShellScript "earlyoom-kill-hook" '''
+ echo "Process $EARLYOOM_NAME ($EARLYOOM_PID) was killed" >> /path/to/log
+ '''
+ '';
+ description = ''
+ An absolute path to an executable to be run for each process killed.
+ Some environment variables are available, see
+ README and
+ the man page
+ for details.
+ '';
+ };
+
+ reportInterval = mkOption {
+ type = types.int;
+ default = 3600;
+ example = 0;
+ description = "Interval (in seconds) at which a memory report is printed (set to 0 to disable).";
+ };
+
+ extraArgs = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "-g" "--prefer '(^|/)(java|chromium)$'" ];
+ description = "Extra command-line arguments to be passed to earlyoom.";
};
};
@@ -83,37 +123,38 @@ in
(mkRemovedOptionModule [ "services" "earlyoom" "useKernelOOMKiller" ] ''
This option is deprecated and ignored by earlyoom since 1.2.
'')
+ (mkRemovedOptionModule [ "services" "earlyoom" "notificationsCommand" ] ''
+ This option was removed in earlyoom 1.6, but was reimplemented in 1.7
+ and is available as the new option `services.earlyoom.killHook`.
+ '')
+ (mkRemovedOptionModule [ "services" "earlyoom" "ignoreOOMScoreAdjust" ] ''
+ This option is deprecated and ignored by earlyoom since 1.7.
+ '')
];
- config = mkIf ecfg.enable {
- assertions = [
- { assertion = ecfg.freeMemThreshold > 0 && ecfg.freeMemThreshold <= 100;
- message = "Needs to be a positive percentage"; }
- { assertion = ecfg.freeSwapThreshold > 0 && ecfg.freeSwapThreshold <= 100;
- message = "Needs to be a positive percentage"; }
- ];
-
- # TODO: reimplement this option as -N after 1.7 (https://github.com/rfjakob/earlyoom/commit/afe03606)
- warnings = optional (ecfg.notificationsCommand != null)
- "`services.earlyoom.notificationsCommand` is deprecated and ignored by earlyoom since 1.6.";
+ config = mkIf cfg.enable {
+ services.systembus-notify.enable = mkDefault cfg.enableNotifications;
systemd.services.earlyoom = {
description = "Early OOM Daemon for Linux";
wantedBy = [ "multi-user.target" ];
- path = optional ecfg.enableNotifications pkgs.dbus;
+ path = optional cfg.enableNotifications pkgs.dbus;
serviceConfig = {
- StandardOutput = "null";
StandardError = "journal";
ExecStart = concatStringsSep " " ([
"${pkgs.earlyoom}/bin/earlyoom"
- "-m ${toString ecfg.freeMemThreshold}"
- "-s ${toString ecfg.freeSwapThreshold}"
- ] ++ optional ecfg.ignoreOOMScoreAdjust "-i"
- ++ optional ecfg.enableDebugInfo "-d"
- ++ optional ecfg.enableNotifications "-n");
+ ("-m ${toString cfg.freeMemThreshold}"
+ + optionalString (cfg.freeMemKillThreshold != null) ",${toString cfg.freeMemKillThreshold}")
+ ("-s ${toString cfg.freeSwapThreshold}"
+ + 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
+ );
};
};
-
- environment.systemPackages = optional ecfg.enableNotifications pkgs.systembus-notify;
};
}
diff --git a/third_party/nixpkgs/nixos/modules/services/system/systembus-notify.nix b/third_party/nixpkgs/nixos/modules/services/system/systembus-notify.nix
new file mode 100644
index 0000000000..e918bc552e
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/services/system/systembus-notify.nix
@@ -0,0 +1,27 @@
+{ config, lib, pkgs, ... }:
+
+let
+ cfg = config.services.systembus-notify;
+
+ inherit (lib) mkEnableOption mkIf;
+
+in
+{
+ options.services.systembus-notify = {
+ enable = mkEnableOption ''
+ System bus notification support
+
+ WARNING: enabling this option (while convenient) should *not* be done on a
+ machine where you do not trust the other users as it allows any other
+ local user to DoS your session by spamming notifications.
+ '';
+ };
+
+ config = mkIf cfg.enable {
+ systemd = {
+ packages = with pkgs; [ systembus-notify ];
+
+ user.services.systembus-notify.wantedBy = [ "graphical-session.target" ];
+ };
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/services/video/epgstation/default.nix b/third_party/nixpkgs/nixos/modules/services/video/epgstation/default.nix
index 41613dcbb3..191f6eb52e 100644
--- a/third_party/nixpkgs/nixos/modules/services/video/epgstation/default.nix
+++ b/third_party/nixpkgs/nixos/modules/services/video/epgstation/default.nix
@@ -1,30 +1,40 @@
{ config, lib, options, pkgs, ... }:
-with lib;
-
let
cfg = config.services.epgstation;
opt = options.services.epgstation;
+ description = "EPGStation: DVR system for Mirakurun-managed TV tuners";
+
username = config.users.users.epgstation.name;
groupname = config.users.users.epgstation.group;
+ mirakurun = {
+ sock = config.services.mirakurun.unixSocket;
+ option = options.services.mirakurun.unixSocket;
+ };
- settingsFmt = pkgs.formats.json {};
- settingsTemplate = settingsFmt.generate "config.json" cfg.settings;
+ yaml = pkgs.formats.yaml { };
+ settingsTemplate = yaml.generate "config.yml" cfg.settings;
preStartScript = pkgs.writeScript "epgstation-prestart" ''
#!${pkgs.runtimeShell}
- PASSWORD="$(head -n1 "${cfg.basicAuth.passwordFile}")"
- DB_PASSWORD="$(head -n1 "${cfg.database.passwordFile}")"
+ DB_PASSWORD_FILE=${lib.escapeShellArg cfg.database.passwordFile}
+
+ if [[ ! -f "$DB_PASSWORD_FILE" ]]; then
+ printf "[FATAL] File containing the DB password was not found in '%s'. Double check the NixOS option '%s'." \
+ "$DB_PASSWORD_FILE" ${lib.escapeShellArg opt.database.passwordFile} >&2
+ exit 1
+ fi
+
+ DB_PASSWORD="$(head -n1 ${lib.escapeShellArg cfg.database.passwordFile})"
# setup configuration
- touch /etc/epgstation/config.json
- chmod 640 /etc/epgstation/config.json
+ touch /etc/epgstation/config.yml
+ chmod 640 /etc/epgstation/config.yml
sed \
- -e "s,@password@,$PASSWORD,g" \
-e "s,@dbPassword@,$DB_PASSWORD,g" \
- ${settingsTemplate} > /etc/epgstation/config.json
- chown "${username}:${groupname}" /etc/epgstation/config.json
+ ${settingsTemplate} > /etc/epgstation/config.yml
+ chown "${username}:${groupname}" /etc/epgstation/config.yml
# NOTE: Use password authentication, since mysqljs does not yet support auth_socket
if [ ! -e /var/lib/epgstation/db-created ]; then
@@ -35,7 +45,7 @@ let
'';
streamingConfig = lib.importJSON ./streaming.json;
- logConfig = {
+ logConfig = yaml.generate "logConfig.yml" {
appenders.stdout.type = "stdout";
categories = {
default = { appenders = [ "stdout" ]; level = "info"; };
@@ -45,53 +55,51 @@ let
};
};
- defaultPassword = "INSECURE_GO_CHECK_CONFIGURATION_NIX\n";
+ # Deprecate top level options that are redundant.
+ deprecateTopLevelOption = config:
+ lib.mkRenamedOptionModule
+ ([ "services" "epgstation" ] ++ config)
+ ([ "services" "epgstation" "settings" ] ++ config);
+
+ removeOption = config: instruction:
+ lib.mkRemovedOptionModule
+ ([ "services" "epgstation" ] ++ config)
+ instruction;
in
{
- options.services.epgstation = {
- enable = mkEnableOption "EPGStation: DTV Software in Japan";
+ meta.maintainers = with lib.maintainers; [ midchildan ];
- usePreconfiguredStreaming = mkOption {
- type = types.bool;
+ imports = [
+ (deprecateTopLevelOption [ "port" ])
+ (deprecateTopLevelOption [ "socketioPort" ])
+ (deprecateTopLevelOption [ "clientSocketioPort" ])
+ (removeOption [ "basicAuth" ]
+ "Use a TLS-terminated reverse proxy with authentication instead.")
+ ];
+
+ options.services.epgstation = {
+ enable = lib.mkEnableOption description;
+
+ package = lib.mkOption {
+ default = pkgs.epgstation;
+ type = lib.types.package;
+ defaultText = lib.literalExpression "pkgs.epgstation";
+ description = "epgstation package to use";
+ };
+
+ usePreconfiguredStreaming = lib.mkOption {
+ type = lib.types.bool;
default = true;
description = ''
Use preconfigured default streaming options.
Upstream defaults:
-
+
'';
};
- port = mkOption {
- type = types.port;
- default = 20772;
- description = ''
- HTTP port for EPGStation to listen on.
- '';
- };
-
- socketioPort = mkOption {
- type = types.port;
- default = cfg.port + 1;
- defaultText = literalExpression "config.${opt.port} + 1";
- description = ''
- Socket.io port for EPGStation to listen on.
- '';
- };
-
- clientSocketioPort = mkOption {
- type = types.port;
- default = cfg.socketioPort;
- defaultText = literalExpression "config.${opt.socketioPort}";
- description = ''
- Socket.io port that the web client is going to connect to. This may be
- different from if EPGStation is hidden
- behind a reverse proxy.
- '';
- };
-
- openFirewall = mkOption {
- type = types.bool;
+ openFirewall = lib.mkOption {
+ type = lib.types.bool;
default = false;
description = ''
Open ports in the firewall for the EPGStation web interface.
@@ -106,50 +114,17 @@ in
'';
};
- basicAuth = {
- user = mkOption {
- type = with types; nullOr str;
- default = null;
- example = "epgstation";
- description = ''
- Basic auth username for EPGStation. If null, basic
- auth will be disabled.
-
-
-
- Basic authentication has known weaknesses, the most critical being
- that it sends passwords over the network in clear text. Use this
- feature to control access to EPGStation within your family and
- friends, but don't rely on it for security.
-
-
- '';
- };
-
- passwordFile = mkOption {
- type = types.path;
- default = pkgs.writeText "epgstation-password" defaultPassword;
- defaultText = literalDocBook ''a file containing ${defaultPassword}'';
- example = "/run/keys/epgstation-password";
- description = ''
- A file containing the password for .
- '';
- };
- };
-
- database = {
- name = mkOption {
- type = types.str;
+ database = {
+ name = lib.mkOption {
+ type = lib.types.str;
default = "epgstation";
description = ''
Name of the MySQL database that holds EPGStation's data.
'';
};
- passwordFile = mkOption {
- type = types.path;
- default = pkgs.writeText "epgstation-db-password" defaultPassword;
- defaultText = literalDocBook ''a file containing ${defaultPassword}'';
+ passwordFile = lib.mkOption {
+ type = lib.types.path;
example = "/run/keys/epgstation-db-password";
description = ''
A file containing the password for the database named
@@ -158,69 +133,106 @@ in
};
};
- settings = mkOption {
+ # The defaults for some options come from the upstream template
+ # configuration, which is the one that users would get if they follow the
+ # upstream instructions. This is, in some cases, different from the
+ # application defaults. Some options like encodeProcessNum and
+ # concurrentEncodeNum doesn't have an optimal default value that works for
+ # all hardware setups and/or performance requirements. For those kind of
+ # options, the application default wouldn't always result in the expected
+ # out-of-the-box behavior because it's the responsibility of the user to
+ # configure them according to their needs. In these cases, the value in the
+ # upstream template configuration should serve as a "good enough" default.
+ settings = lib.mkOption {
description = ''
- Options to add to config.json.
+ Options to add to config.yml.
Documentation:
'';
- default = {};
+ default = { };
example = {
recPriority = 20;
conflictPriority = 10;
};
- type = types.submodule {
- freeformType = settingsFmt.type;
+ type = lib.types.submodule {
+ freeformType = yaml.type;
- options.readOnlyOnce = mkOption {
- type = types.bool;
- default = false;
- description = "Don't reload configuration files at runtime.";
+ options.port = lib.mkOption {
+ type = lib.types.port;
+ default = 20772;
+ description = ''
+ HTTP port for EPGStation to listen on.
+ '';
};
- options.mirakurunPath = mkOption (let
- sockPath = config.services.mirakurun.unixSocket;
- in {
- type = types.str;
- default = "http+unix://${replaceStrings ["/"] ["%2F"] sockPath}";
- defaultText = literalExpression ''
- "http+unix://''${replaceStrings ["/"] ["%2F"] config.${options.services.mirakurun.unixSocket}}"
+ options.socketioPort = lib.mkOption {
+ type = lib.types.port;
+ default = cfg.settings.port + 1;
+ defaultText = lib.literalExpression "config.${opt.settings}.port + 1";
+ description = ''
+ Socket.io port for EPGStation to listen on. It is valid to share
+ ports with .
+ '';
+ };
+
+ options.clientSocketioPort = lib.mkOption {
+ type = lib.types.port;
+ default = cfg.settings.socketioPort;
+ defaultText = lib.literalExpression "config.${opt.settings}.socketioPort";
+ description = ''
+ Socket.io port that the web client is going to connect to. This may
+ be different from if
+ EPGStation is hidden behind a reverse proxy.
+ '';
+ };
+
+ options.mirakurunPath = with mirakurun; lib.mkOption {
+ type = lib.types.str;
+ default = "http+unix://${lib.replaceStrings ["/"] ["%2F"] sock}";
+ defaultText = lib.literalExpression ''
+ "http+unix://''${lib.replaceStrings ["/"] ["%2F"] config.${option}}"
'';
example = "http://localhost:40772";
description = "URL to connect to Mirakurun.";
- });
+ };
- options.encode = mkOption {
- type = with types; listOf attrs;
+ options.encodeProcessNum = lib.mkOption {
+ type = lib.types.ints.positive;
+ default = 4;
+ description = ''
+ The maximum number of processes that EPGStation would allow to run
+ at the same time for encoding or streaming videos.
+ '';
+ };
+
+ options.concurrentEncodeNum = lib.mkOption {
+ type = lib.types.ints.positive;
+ default = 1;
+ description = ''
+ The maximum number of encoding jobs that EPGStation would run at the
+ same time.
+ '';
+ };
+
+ options.encode = lib.mkOption {
+ type = with lib.types; listOf attrs;
description = "Encoding presets for recorded videos.";
default = [
{
- name = "H264";
- cmd = "${pkgs.epgstation}/libexec/enc.sh main";
+ name = "H.264";
+ cmd = "%NODE% ${cfg.package}/libexec/enc.js";
suffix = ".mp4";
- default = true;
- }
- {
- name = "H264-sub";
- cmd = "${pkgs.epgstation}/libexec/enc.sh sub";
- suffix = "-sub.mp4";
}
];
- defaultText = literalExpression ''
+ defaultText = lib.literalExpression ''
[
{
- name = "H264";
- cmd = "''${pkgs.epgstation}/libexec/enc.sh main";
+ name = "H.264";
+ cmd = "%NODE% config.${opt.package}/libexec/enc.js";
suffix = ".mp4";
- default = true;
- }
- {
- name = "H264-sub";
- cmd = "''${pkgs.epgstation}/libexec/enc.sh sub";
- suffix = "-sub.mp4";
}
]
'';
@@ -229,14 +241,25 @@ in
};
};
- config = mkIf cfg.enable {
+ config = lib.mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = !(lib.hasAttr "readOnlyOnce" cfg.settings);
+ message = ''
+ The option config.${opt.settings}.readOnlyOnce can no longer be used
+ since it's been removed. No replacements are available.
+ '';
+ }
+ ];
+
environment.etc = {
- "epgstation/operatorLogConfig.json".text = builtins.toJSON logConfig;
- "epgstation/serviceLogConfig.json".text = builtins.toJSON logConfig;
+ "epgstation/epgUpdaterLogConfig.yml".source = logConfig;
+ "epgstation/operatorLogConfig.yml".source = logConfig;
+ "epgstation/serviceLogConfig.yml".source = logConfig;
};
- networking.firewall = mkIf cfg.openFirewall {
- allowedTCPPorts = with cfg; [ port socketioPort ];
+ networking.firewall = lib.mkIf cfg.openFirewall {
+ allowedTCPPorts = with cfg.settings; [ port socketioPort ];
};
users.users.epgstation = {
@@ -245,13 +268,13 @@ in
isSystemUser = true;
};
- users.groups.epgstation = {};
+ users.groups.epgstation = { };
- services.mirakurun.enable = mkDefault true;
+ services.mirakurun.enable = lib.mkDefault true;
services.mysql = {
- enable = mkDefault true;
- package = mkDefault pkgs.mariadb;
+ enable = lib.mkDefault true;
+ package = lib.mkDefault pkgs.mariadb;
ensureDatabases = [ cfg.database.name ];
# FIXME: enable once mysqljs supports auth_socket
# ensureUsers = [ {
@@ -260,39 +283,28 @@ in
# } ];
};
- services.epgstation.settings = let
- defaultSettings = {
- serverPort = cfg.port;
- socketioPort = cfg.socketioPort;
- clientSocketioPort = cfg.clientSocketioPort;
+ services.epgstation.settings =
+ let
+ defaultSettings = {
+ dbtype = lib.mkDefault "mysql";
+ mysql = {
+ socketPath = lib.mkDefault "/run/mysqld/mysqld.sock";
+ user = username;
+ password = lib.mkDefault "@dbPassword@";
+ database = cfg.database.name;
+ };
- dbType = mkDefault "mysql";
- mysql = {
- user = username;
- database = cfg.database.name;
- socketPath = mkDefault "/run/mysqld/mysqld.sock";
- password = mkDefault "@dbPassword@";
- connectTimeout = mkDefault 1000;
- connectionLimit = mkDefault 10;
+ ffmpeg = lib.mkDefault "${pkgs.ffmpeg-full}/bin/ffmpeg";
+ ffprobe = lib.mkDefault "${pkgs.ffmpeg-full}/bin/ffprobe";
+
+ # for disambiguation with TypeScript files
+ recordedFileExtension = lib.mkDefault ".m2ts";
};
-
- basicAuth = mkIf (cfg.basicAuth.user != null) {
- user = mkDefault cfg.basicAuth.user;
- password = mkDefault "@password@";
- };
-
- ffmpeg = mkDefault "${pkgs.ffmpeg-full}/bin/ffmpeg";
- ffprobe = mkDefault "${pkgs.ffmpeg-full}/bin/ffprobe";
-
- fileExtension = mkDefault ".m2ts";
- maxEncode = mkDefault 2;
- maxStreaming = mkDefault 2;
- };
- in
- mkMerge [
- defaultSettings
- (mkIf cfg.usePreconfiguredStreaming streamingConfig)
- ];
+ in
+ lib.mkMerge [
+ defaultSettings
+ (lib.mkIf cfg.usePreconfiguredStreaming streamingConfig)
+ ];
systemd.tmpfiles.rules = [
"d '/var/lib/epgstation/streamfiles' - ${username} ${groupname} - -"
@@ -301,15 +313,15 @@ in
];
systemd.services.epgstation = {
- description = pkgs.epgstation.meta.description;
+ inherit description;
+
wantedBy = [ "multi-user.target" ];
- after = [
- "network.target"
- ] ++ optional config.services.mirakurun.enable "mirakurun.service"
- ++ optional config.services.mysql.enable "mysql.service";
+ after = [ "network.target" ]
+ ++ lib.optional config.services.mirakurun.enable "mirakurun.service"
+ ++ lib.optional config.services.mysql.enable "mysql.service";
serviceConfig = {
- ExecStart = "${pkgs.epgstation}/bin/epgstation start";
+ ExecStart = "${cfg.package}/bin/epgstation start";
ExecStartPre = "+${preStartScript}";
User = username;
Group = groupname;
diff --git a/third_party/nixpkgs/nixos/modules/services/video/epgstation/streaming.json b/third_party/nixpkgs/nixos/modules/services/video/epgstation/streaming.json
index 8eb99cf855..7f8df0817f 100644
--- a/third_party/nixpkgs/nixos/modules/services/video/epgstation/streaming.json
+++ b/third_party/nixpkgs/nixos/modules/services/video/epgstation/streaming.json
@@ -1,119 +1,140 @@
{
- "liveHLS": [
- {
- "name": "720p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ "urlscheme": {
+ "m2ts": {
+ "ios": "vlc-x-callback://x-callback-url/stream?url=PROTOCOL://ADDRESS",
+ "android": "intent://ADDRESS#Intent;package=org.videolan.vlc;type=video;scheme=PROTOCOL;end"
},
- {
- "name": "480p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ "video": {
+ "ios": "infuse://x-callback-url/play?url=PROTOCOL://ADDRESS",
+ "android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=PROTOCOL;end"
},
- {
- "name": "180p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 48k -ac 2 -c:v libx264 -vf yadif,scale=-2:180 -b:v 100k -preset veryfast -maxrate 110k -bufsize 1000k -flags +loop-global_header %OUTPUT%"
+ "download": {
+ "ios": "vlc-x-callback://x-callback-url/download?url=PROTOCOL://ADDRESS&filename=FILENAME"
}
- ],
- "liveMP4": [
- {
- "name": "720p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
- },
- {
- "name": "480p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
- }
- ],
- "liveWebM": [
- {
- "name": "720p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
- },
- {
- "name": "480p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
- }
- ],
- "mpegTsStreaming": [
- {
- "name": "720p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -y -f mpegts pipe:1"
- },
- {
- "name": "480p",
- "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -y -f mpegts pipe:1"
- },
- {
- "name": "Original"
- }
- ],
- "mpegTsViewer": {
- "ios": "vlc-x-callback://x-callback-url/stream?url=http://ADDRESS",
- "android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=http;end"
},
- "recordedDownloader": {
- "ios": "vlc-x-callback://x-callback-url/download?url=http://ADDRESS&filename=FILENAME",
- "android": "intent://ADDRESS#Intent;package=com.dv.adm;type=video;scheme=http;end"
- },
- "recordedStreaming": {
- "webm": [
- {
- "name": "720p",
- "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
- "vb": "3000k",
- "ab": "192k"
- },
- {
- "name": "360p",
- "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1",
- "vb": "1500k",
- "ab": "128k"
+ "stream": {
+ "live": {
+ "ts": {
+ "m2ts": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -y -f mpegts pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -y -f mpegts pipe:1"
+ },
+ {
+ "name": "無変換"
+ }
+ ],
+ "m2tsll": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -f mpegts -analyzeduration 500000 -i pipe:0 -map 0 -c:s copy -c:d copy -ignore_unknown -fflags nobuffer -flags low_delay -max_delay 250000 -max_interleave_delta 1 -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -flags +cgop -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -y -f mpegts pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -f mpegts -analyzeduration 500000 -i pipe:0 -map 0 -c:s copy -c:d copy -ignore_unknown -fflags nobuffer -flags low_delay -max_delay 250000 -max_interleave_delta 1 -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -flags +cgop -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -y -f mpegts pipe:1"
+ }
+ ],
+ "webm": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 2 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
+ }
+ ],
+ "mp4": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
+ }
+ ],
+ "hls": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ }
+ ]
}
- ],
- "mp4": [
- {
- "name": "720p",
- "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
- "vb": "3000k",
- "ab": "192k"
- },
- {
- "name": "360p",
- "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1",
- "vb": "1500k",
- "ab": "128k"
- }
- ],
- "mpegTs": [
- {
- "name": "720p (H.264)",
- "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:720 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -y -f mpegts pipe:1",
- "vb": "3000k",
- "ab": "192k"
- },
- {
- "name": "360p (H.264)",
- "cmd": "%FFMPEG% -dual_mono_mode main %RE% -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -ac 2 -c:v libx264 -vf yadif,scale=-2:360 %VB% %VBUFFER% %AB% %ABUFFER% -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -y -f mpegts pipe:1",
- "vb": "1500k",
- "ab": "128k"
- }
- ]
- },
- "recordedHLS": [
- {
- "name": "720p",
- "cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
},
- {
- "name": "480p",
- "cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -threads 0 -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
- },
- {
- "name": "480p(h265)",
- "cmd": "%FFMPEG% -dual_mono_mode main -i %INPUT% -sn -map 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_type fmp4 -hls_fmp4_init_filename stream%streamNum%-init.mp4 -hls_segment_filename stream%streamNum%-%09d.m4s -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx265 -vf yadif,scale=-2:480 -b:v 350k -preset veryfast -tag:v hvc1 %OUTPUT%"
+ "recorded": {
+ "ts": {
+ "webm": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf yadif,scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
+ }
+ ],
+ "mp4": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
+ }
+ ],
+ "hls": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf yadif,scale=-2:480 -b:v 1500k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ }
+ ]
+ },
+ "encoded": {
+ "webm": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 192k -ac 2 -c:v libvpx-vp9 -vf scale=-2:720 -b:v 3000k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 3 -c:a libvorbis -ar 48000 -b:a 128k -ac 2 -c:v libvpx-vp9 -vf scale=-2:480 -b:v 1500k -deadline realtime -speed 4 -cpu-used -8 -y -f webm pipe:1"
+ }
+ ],
+ "mp4": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf scale=-2:720 -b:v 3000k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf scale=-2:480 -b:v 1500k -profile:v baseline -preset veryfast -tune fastdecode,zerolatency -movflags frag_keyframe+empty_moov+faststart+default_base_moof -y -f mp4 pipe:1"
+ }
+ ],
+ "hls": [
+ {
+ "name": "720p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf scale=-2:720 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ },
+ {
+ "name": "480p",
+ "cmd": "%FFMPEG% -dual_mono_mode main -ss %SS% -i %INPUT% -sn -threads 0 -ignore_unknown -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 0 -hls_allow_cache 1 -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:a aac -ar 48000 -b:a 128k -ac 2 -c:v libx264 -vf scale=-2:480 -b:v 3000k -preset veryfast -flags +loop-global_header %OUTPUT%"
+ }
+ ]
+ }
}
- ],
- "recordedViewer": {
- "ios": "infuse://x-callback-url/play?url=http://ADDRESS",
- "android": "intent://ADDRESS#Intent;package=com.mxtech.videoplayer.ad;type=video;scheme=http;end"
}
}
diff --git a/third_party/nixpkgs/nixos/modules/services/video/unifi-video.nix b/third_party/nixpkgs/nixos/modules/services/video/unifi-video.nix
index 43208a9fe4..11d9fe3054 100644
--- a/third_party/nixpkgs/nixos/modules/services/video/unifi-video.nix
+++ b/third_party/nixpkgs/nixos/modules/services/video/unifi-video.nix
@@ -16,7 +16,7 @@ let
-pidfile ${cfg.pidFile} \
-procname unifi-video \
-Djava.security.egd=file:/dev/./urandom \
- -Xmx${cfg.maximumJavaHeapSize}M \
+ -Xmx${toString cfg.maximumJavaHeapSize}M \
-Xss512K \
-XX:+UseG1GC \
-XX:+UseStringDeduplication \
@@ -91,98 +91,102 @@ let
stateDir = "/var/lib/unifi-video";
in
- {
+{
- options.services.unifi-video = {
- enable = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Whether or not to enable the unifi-video service.
- '';
- };
+ options.services.unifi-video = {
- jrePackage = mkOption {
- type = types.package;
- default = pkgs.jre8;
- defaultText = literalExpression "pkgs.jre8";
- description = ''
- The JRE package to use. Check the release notes to ensure it is supported.
- '';
- };
+ enable = mkOption {
+ type = types.bool;
+ default = false;
+ description = ''
+ Whether or not to enable the unifi-video service.
+ '';
+ };
- unifiVideoPackage = mkOption {
- type = types.package;
- default = pkgs.unifi-video;
- defaultText = literalExpression "pkgs.unifi-video";
- description = ''
- The unifi-video package to use.
- '';
- };
+ jrePackage = mkOption {
+ type = types.package;
+ default = pkgs.jre8;
+ defaultText = literalExpression "pkgs.jre8";
+ description = ''
+ The JRE package to use. Check the release notes to ensure it is supported.
+ '';
+ };
- mongodbPackage = mkOption {
- type = types.package;
- default = pkgs.mongodb-4_0;
- defaultText = literalExpression "pkgs.mongodb";
- description = ''
- The mongodb package to use.
- '';
- };
+ unifiVideoPackage = mkOption {
+ type = types.package;
+ default = pkgs.unifi-video;
+ defaultText = literalExpression "pkgs.unifi-video";
+ description = ''
+ The unifi-video package to use.
+ '';
+ };
- logDir = mkOption {
- type = types.str;
- default = "${stateDir}/logs";
- description = ''
- Where to store the logs.
- '';
- };
+ mongodbPackage = mkOption {
+ type = types.package;
+ default = pkgs.mongodb-4_0;
+ defaultText = literalExpression "pkgs.mongodb";
+ description = ''
+ The mongodb package to use.
+ '';
+ };
- dataDir = mkOption {
- type = types.str;
- default = "${stateDir}/data";
- description = ''
- Where to store the database and other data.
- '';
- };
+ logDir = mkOption {
+ type = types.str;
+ default = "${stateDir}/logs";
+ description = ''
+ Where to store the logs.
+ '';
+ };
- openPorts = mkOption {
- type = types.bool;
- default = true;
- description = ''
- Whether or not to open the required ports on the firewall.
- '';
- };
+ dataDir = mkOption {
+ type = types.str;
+ default = "${stateDir}/data";
+ description = ''
+ Where to store the database and other data.
+ '';
+ };
- maximumJavaHeapSize = mkOption {
- type = types.nullOr types.int;
- default = 1024;
- example = 4096;
- description = ''
- Set the maximimum heap size for the JVM in MB.
- '';
- };
+ openFirewall = mkOption {
+ type = types.bool;
+ default = true;
+ description = ''
+ Whether or not to open the required ports on the firewall.
+ '';
+ };
- pidFile = mkOption {
- type = types.path;
- default = "${cfg.dataDir}/unifi-video.pid";
- defaultText = literalExpression ''"''${config.${opt.dataDir}}/unifi-video.pid"'';
- description = "Location of unifi-video pid file.";
- };
+ maximumJavaHeapSize = mkOption {
+ type = types.nullOr types.int;
+ default = 1024;
+ example = 4096;
+ description = ''
+ Set the maximimum heap size for the JVM in MB.
+ '';
+ };
-};
+ pidFile = mkOption {
+ type = types.path;
+ default = "${cfg.dataDir}/unifi-video.pid";
+ defaultText = literalExpression ''"''${config.${opt.dataDir}}/unifi-video.pid"'';
+ description = "Location of unifi-video pid file.";
+ };
-config = mkIf cfg.enable {
- users = {
- users.unifi-video = {
+ };
+
+ config = mkIf cfg.enable {
+
+ warnings = optional
+ (options.services.unifi-video.openFirewall.highestPrio >= (mkOptionDefault null).priority)
+ "The current services.unifi-video.openFirewall = true default is deprecated and will change to false in 22.11. Set it explicitly to silence this warning.";
+
+ users.users.unifi-video = {
description = "UniFi Video controller daemon user";
home = stateDir;
group = "unifi-video";
isSystemUser = true;
};
- groups.unifi-video = {};
- };
+ users.groups.unifi-video = {};
- networking.firewall = mkIf cfg.openPorts {
+ networking.firewall = mkIf cfg.openFirewall {
# https://help.ui.com/hc/en-us/articles/217875218-UniFi-Video-Ports-Used
allowedTCPPorts = [
7080 # HTTP portal
@@ -237,7 +241,6 @@ config = mkIf cfg.enable {
"L+ '${stateDir}/conf/server.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/server.xml"
"L+ '${stateDir}/conf/tomcat-users.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/tomcat-users.xml"
"L+ '${stateDir}/conf/web.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/web.xml"
-
];
systemd.services.unifi-video = {
@@ -258,10 +261,11 @@ config = mkIf cfg.enable {
WorkingDirectory = "${stateDir}";
};
};
-
};
- meta = {
- maintainers = with lib.maintainers; [ rsynnest ];
- };
+ imports = [
+ (mkRenamedOptionModule [ "services" "unifi-video" "openPorts" ] [ "services" "unifi-video" "openFirewall" ])
+ ];
+
+ meta.maintainers = with lib.maintainers; [ rsynnest ];
}
diff --git a/third_party/nixpkgs/nixos/modules/services/web-apps/keycloak.nix b/third_party/nixpkgs/nixos/modules/services/web-apps/keycloak.nix
index 22c16be761..c4a2127663 100644
--- a/third_party/nixpkgs/nixos/modules/services/web-apps/keycloak.nix
+++ b/third_party/nixpkgs/nixos/modules/services/web-apps/keycloak.nix
@@ -129,6 +129,14 @@ in
'';
};
+ plugins = lib.mkOption {
+ type = lib.types.listOf lib.types.path;
+ default = [];
+ description = ''
+ Keycloak plugin jar, ear files or derivations with them
+ '';
+ };
+
database = {
type = mkOption {
type = enum [ "mysql" "postgresql" ];
@@ -787,6 +795,14 @@ in
umask u=rwx,g=,o=
+ install_plugin() {
+ if [ -d "$1" ]; then
+ find "$1" -type f \( -iname \*.ear -o -iname \*.jar \) -exec install -m 0500 -o keycloak -g keycloak "{}" "/run/keycloak/deployments/" \;
+ else
+ install -m 0500 -o keycloak -g keycloak "$1" "/run/keycloak/deployments/"
+ fi
+ }
+
install -m 0600 ${cfg.package}/standalone/configuration/*.properties /run/keycloak/configuration
install -T -m 0600 ${keycloakConfig} /run/keycloak/configuration/standalone.xml
@@ -794,7 +810,9 @@ in
export JAVA_OPTS=-Djboss.server.config.user.dir=/run/keycloak/configuration
add-user-keycloak.sh -u admin -p '${cfg.initialAdminPassword}'
- '' + optionalString (cfg.sslCertificate != null && cfg.sslCertificateKey != null) ''
+ ''
+ + lib.optionalString (cfg.plugins != []) (lib.concatStringsSep "\n" (map (pl: "install_plugin ${lib.escapeShellArg pl}") cfg.plugins)) + "\n"
+ + optionalString (cfg.sslCertificate != null && cfg.sslCertificateKey != null) ''
pushd /run/keycloak/ssl/
cat "$CREDENTIALS_DIRECTORY/ssl_cert" <(echo) \
"$CREDENTIALS_DIRECTORY/ssl_key" <(echo) \
diff --git a/third_party/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix b/third_party/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
index 141ab98e29..b32220a5e5 100644
--- a/third_party/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
+++ b/third_party/nixpkgs/nixos/modules/services/web-apps/nextcloud.nix
@@ -153,7 +153,7 @@ in {
package = mkOption {
type = types.package;
description = "Which package to use for the Nextcloud instance.";
- relatedPackages = [ "nextcloud21" "nextcloud22" "nextcloud23" ];
+ relatedPackages = [ "nextcloud22" "nextcloud23" ];
};
phpPackage = mkOption {
type = types.package;
@@ -571,15 +571,6 @@ in {
nextcloud defined in an overlay, please set `services.nextcloud.package` to
`pkgs.nextcloud`.
''
- # 21.03 will not be an official release - it was instead 21.05.
- # This versionOlder statement remains set to 21.03 for backwards compatibility.
- # See https://github.com/NixOS/nixpkgs/pull/108899 and
- # https://github.com/NixOS/rfcs/blob/master/rfcs/0080-nixos-release-schedule.md.
- # FIXME(@Ma27) remove this else-if as soon as 21.05 is EOL! This is only here
- # to ensure that users who are on Nextcloud 19 with a stateVersion <21.05 with
- # no explicit services.nextcloud.package don't upgrade to v21 by accident (
- # nextcloud20 throws an eval-error because it's dropped).
- else if versionOlder stateVersion "21.03" then nextcloud20
else if versionOlder stateVersion "21.11" then nextcloud21
else if versionOlder stateVersion "22.05" then nextcloud22
else nextcloud23
diff --git a/third_party/nixpkgs/nixos/modules/services/web-apps/plantuml-server.nix b/third_party/nixpkgs/nixos/modules/services/web-apps/plantuml-server.nix
index f4bf43f56b..9ea37b8a4c 100644
--- a/third_party/nixpkgs/nixos/modules/services/web-apps/plantuml-server.nix
+++ b/third_party/nixpkgs/nixos/modules/services/web-apps/plantuml-server.nix
@@ -20,6 +20,21 @@ in
description = "PlantUML server package to use";
};
+ packages = {
+ jdk = mkOption {
+ type = types.package;
+ default = pkgs.jdk;
+ defaultText = literalExpression "pkgs.jdk";
+ description = "JDK package to use for the server";
+ };
+ jetty = mkOption {
+ type = types.package;
+ default = pkgs.jetty;
+ defaultText = literalExpression "pkgs.jetty";
+ description = "Jetty package to use for the server";
+ };
+ };
+
user = mkOption {
type = types.str;
default = "plantuml";
@@ -105,10 +120,10 @@ in
ALLOW_PLANTUML_INCLUDE = if cfg.allowPlantumlInclude then "true" else "false";
};
script = ''
- ${pkgs.jre}/bin/java \
- -jar ${pkgs.jetty}/start.jar \
+ ${cfg.packages.jdk}/bin/java \
+ -jar ${cfg.packages.jetty}/start.jar \
--module=deploy,http,jsp \
- jetty.home=${pkgs.jetty} \
+ jetty.home=${cfg.packages.jetty} \
jetty.base=${cfg.package} \
jetty.http.host=${cfg.listenHost} \
jetty.http.port=${builtins.toString cfg.listenPort}
diff --git a/third_party/nixpkgs/nixos/modules/services/web-servers/tomcat.nix b/third_party/nixpkgs/nixos/modules/services/web-servers/tomcat.nix
index f9446fe125..877097cf37 100644
--- a/third_party/nixpkgs/nixos/modules/services/web-servers/tomcat.nix
+++ b/third_party/nixpkgs/nixos/modules/services/web-servers/tomcat.nix
@@ -23,8 +23,8 @@ in
package = mkOption {
type = types.package;
- default = pkgs.tomcat85;
- defaultText = literalExpression "pkgs.tomcat85";
+ default = pkgs.tomcat9;
+ defaultText = literalExpression "pkgs.tomcat9";
example = lib.literalExpression "pkgs.tomcat9";
description = ''
Which tomcat package to use.
@@ -127,7 +127,7 @@ in
webapps = mkOption {
type = types.listOf types.path;
default = [ tomcat.webapps ];
- defaultText = literalExpression "[ pkgs.tomcat85.webapps ]";
+ defaultText = literalExpression "[ config.services.tomcat.package.webapps ]";
description = "List containing WAR files or directories with WAR files which are web applications to be deployed on Tomcat";
};
@@ -201,6 +201,7 @@ in
{ uid = config.ids.uids.tomcat;
description = "Tomcat user";
home = "/homeless-shelter";
+ group = "tomcat";
extraGroups = cfg.extraGroups;
};
diff --git a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome.nix b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome.nix
index e232378514..f87258ac8d 100644
--- a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome.nix
+++ b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome.nix
@@ -132,6 +132,10 @@ in
[ "environment" "gnome3" "excludePackages" ]
[ "environment" "gnome" "excludePackages" ]
)
+ (mkRemovedOptionModule
+ [ "services" "gnome" "experimental-features" "realtime-scheduling" ]
+ "Set `security.rtkit.enable = true;` to make realtime scheduling possible. (Still needs to be enabled using GSettings.)"
+ )
];
options = {
@@ -142,38 +146,6 @@ in
core-utilities.enable = mkEnableOption "GNOME core utilities";
core-developer-tools.enable = mkEnableOption "GNOME core developer tools";
games.enable = mkEnableOption "GNOME games";
-
- experimental-features = {
- realtime-scheduling = mkOption {
- type = types.bool;
- default = false;
- description = ''
- Makes mutter (which propagates to gnome-shell) request a low priority real-time
- scheduling which is only available on the wayland session.
- To enable this experimental feature it requires a restart of the compositor.
- Note that enabling this option only enables the capability
- for realtime-scheduling to be used. It doesn't automatically set the gsetting
- so that mutter actually uses realtime-scheduling. This would require adding
- rt-scheduler to /org/gnome/mutter/experimental-features
- with dconf-editor. You cannot use extraGSettingsOverrides because that will only
- change the default value of the setting.
-
- Please be aware of these known issues with the feature in nixos:
-
-
-
- NixOS/nixpkgs#90201
-
-
-
-
- NixOS/nixpkgs#86730
-
-
-
- '';
- };
- };
};
services.xserver.desktopManager.gnome = {
@@ -414,7 +386,6 @@ in
services.gnome.rygel.enable = mkDefault true;
services.gvfs.enable = true;
services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
- services.telepathy.enable = mkDefault true;
systemd.packages = with pkgs.gnome; [
gnome-session
@@ -480,29 +451,6 @@ in
];
})
- # Enable soft realtime scheduling, only supported on wayland
- (mkIf serviceCfg.experimental-features.realtime-scheduling {
- security.wrappers.".gnome-shell-wrapped" = {
- source = "${pkgs.gnome.gnome-shell}/bin/.gnome-shell-wrapped";
- owner = "root";
- group = "root";
- capabilities = "cap_sys_nice=ep";
- };
-
- systemd.user.services.gnome-shell-wayland = let
- gnomeShellRT = with pkgs.gnome; pkgs.runCommand "gnome-shell-rt" {} ''
- mkdir -p $out/bin/
- cp ${gnome-shell}/bin/gnome-shell $out/bin
- sed -i "s@${gnome-shell}/bin/@${config.security.wrapperDir}/@" $out/bin/gnome-shell
- '';
- in {
- # Note we need to clear ExecStart before overriding it
- serviceConfig.ExecStart = ["" "${gnomeShellRT}/bin/gnome-shell"];
- # Do not use the default environment, it provides a broken PATH
- environment = mkForce {};
- };
- })
-
# Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/gnome-3-38/elements/core/meta-gnome-core-utilities.bst
(mkIf serviceCfg.core-utilities.enable {
environment.systemPackages =
@@ -513,18 +461,18 @@ in
cheese
eog
epiphany
- gedit
+ pkgs.gnome-text-editor
gnome-calculator
gnome-calendar
gnome-characters
gnome-clocks
+ pkgs.gnome-console
gnome-contacts
gnome-font-viewer
gnome-logs
gnome-maps
gnome-music
pkgs.gnome-photos
- gnome-screenshot
gnome-system-monitor
gnome-weather
nautilus
@@ -547,10 +495,13 @@ in
programs.file-roller.enable = notExcluded pkgs.gnome.file-roller;
programs.geary.enable = notExcluded pkgs.gnome.geary;
programs.gnome-disks.enable = notExcluded pkgs.gnome.gnome-disk-utility;
- programs.gnome-terminal.enable = notExcluded pkgs.gnome.gnome-terminal;
programs.seahorse.enable = notExcluded pkgs.gnome.seahorse;
services.gnome.sushi.enable = notExcluded pkgs.gnome.sushi;
+ # VTE shell integration for gnome-console
+ programs.bash.vteIntegration = mkDefault true;
+ programs.zsh.vteIntegration = mkDefault true;
+
# Let nautilus find extensions
# TODO: Create nautilus-with-extensions package
environment.sessionVariables.NAUTILUS_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-3.0";
diff --git a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix
index f8f47a0614..a7fda4be97 100644
--- a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix
+++ b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix
@@ -74,11 +74,9 @@ in
# Debugging
environment.sessionVariables.MATE_SESSION_DEBUG = mkIf cfg.debug "1";
- environment.systemPackages =
- pkgs.mate.basePackages ++
- (pkgs.gnome.removePackagesByName
- pkgs.mate.extraPackages
- config.environment.mate.excludePackages) ++
+ environment.systemPackages = pkgs.gnome.removePackagesByName
+ (pkgs.mate.basePackages ++
+ pkgs.mate.extraPackages ++
[
pkgs.desktop-file-utils
pkgs.glib
@@ -87,7 +85,8 @@ in
pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
pkgs.mate.mate-settings-daemon
pkgs.yelp # for 'Contents' in 'Help' menus
- ];
+ ])
+ config.environment.mate.excludePackages;
programs.dconf.enable = true;
# Shell integration for VTE terminals
diff --git a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
index 6a7d2a8aa6..48e119a861 100644
--- a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
+++ b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
@@ -220,13 +220,12 @@ in
] config.environment.pantheon.excludePackages);
programs.evince.enable = mkDefault true;
- programs.evince.package = pkgs.pantheon.evince;
programs.file-roller.enable = mkDefault true;
- programs.file-roller.package = pkgs.pantheon.file-roller;
# Settings from elementary-default-settings
environment.etc."gtk-3.0/settings.ini".source = "${pkgs.pantheon.elementary-default-settings}/etc/gtk-3.0/settings.ini";
+ xdg.portal.enable = true;
xdg.portal.extraPortals = with pkgs.pantheon; [
elementary-files
elementary-settings-daemon
@@ -303,7 +302,6 @@ in
environment.systemPackages = with pkgs.pantheon; [
contractor
file-roller-contract
- gnome-bluetooth-contract
];
environment.pathsToLink = [
diff --git a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
index b7aa2eba81..3ca044ad5b 100644
--- a/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
+++ b/third_party/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -519,7 +519,7 @@ in
with plasma5; with kdeApplications; with kdeFrameworks;
[
# Basic packages without which Plasma Mobile fails to work properly.
- plasma-phone-components
+ plasma-mobile
plasma-nano
pkgs.maliit-framework
pkgs.maliit-keyboard
@@ -573,7 +573,7 @@ in
};
};
- services.xserver.displayManager.sessionPackages = [ pkgs.libsForQt5.plasma5.plasma-phone-components ];
+ services.xserver.displayManager.sessionPackages = [ pkgs.libsForQt5.plasma5.plasma-mobile ];
})
];
}
diff --git a/third_party/nixpkgs/nixos/modules/services/x11/display-managers/default.nix b/third_party/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
index 92b3af8527..a5db3dd5dd 100644
--- a/third_party/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
+++ b/third_party/nixpkgs/nixos/modules/services/x11/display-managers/default.nix
@@ -219,6 +219,7 @@ in
session = mkOption {
default = [];
+ type = types.listOf types.attrs;
example = literalExpression
''
[ { manage = "desktop";
diff --git a/third_party/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix b/third_party/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix
index b1dc6643be..70ae6b8978 100644
--- a/third_party/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/third_party/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix
@@ -141,7 +141,7 @@ in
GDM_X_SERVER_EXTRA_ARGS = toString
(filter (arg: arg != "-terminate") cfg.xserverArgs);
# GDM is needed for gnome-login.session
- XDG_DATA_DIRS = "${gdm}/share:${cfg.sessionData.desktops}/share";
+ XDG_DATA_DIRS = "${gdm}/share:${cfg.sessionData.desktops}/share:${pkgs.gnome.gnome-control-center}/share";
} // optionalAttrs (xSessionWrapper != null) {
# Make GDM use this wrapper before running the session, which runs the
# configured setupCommands. This relies on a patched GDM which supports
diff --git a/third_party/nixpkgs/nixos/modules/system/activation/switch-to-configuration.pl b/third_party/nixpkgs/nixos/modules/system/activation/switch-to-configuration.pl
old mode 100644
new mode 100755
index a1653d451f..9e5b760434
--- a/third_party/nixpkgs/nixos/modules/system/activation/switch-to-configuration.pl
+++ b/third_party/nixpkgs/nixos/modules/system/activation/switch-to-configuration.pl
@@ -8,16 +8,29 @@ use File::Basename;
use File::Slurp qw(read_file write_file edit_file);
use Net::DBus;
use Sys::Syslog qw(:standard :macros);
-use Cwd 'abs_path';
+use Cwd qw(abs_path);
+## no critic(ControlStructures::ProhibitDeepNests)
+## no critic(ErrorHandling::RequireCarping)
+## no critic(CodeLayout::ProhibitParensWithBuiltins)
+## no critic(Variables::ProhibitPunctuationVars, Variables::RequireLocalizedPunctuationVars)
+## no critic(InputOutput::RequireCheckedSyscalls, InputOutput::RequireBracedFileHandleWithPrint, InputOutput::RequireBriefOpen)
+## no critic(ValuesAndExpressions::ProhibitNoisyQuotes, ValuesAndExpressions::ProhibitMagicNumbers, ValuesAndExpressions::ProhibitEmptyQuotes, ValuesAndExpressions::ProhibitInterpolationOfLiterals)
+## no critic(RegularExpressions::ProhibitEscapedMetacharacters)
+
+# System closure path to switch to
my $out = "@out@";
-
-my $curSystemd = abs_path("/run/current-system/sw/bin");
+# Path to the directory containing systemd tools of the old system
+my $cur_systemd = abs_path("/run/current-system/sw/bin");
+# Path to the systemd store path of the new system
+my $new_systemd = "@systemd@";
# To be robust against interruption, record what units need to be started etc.
-my $startListFile = "/run/nixos/start-list";
-my $restartListFile = "/run/nixos/restart-list";
-my $reloadListFile = "/run/nixos/reload-list";
+# We read these files again every time this script starts to make sure we continue
+# where the old (interrupted) script left off.
+my $start_list_file = "/run/nixos/start-list";
+my $restart_list_file = "/run/nixos/restart-list";
+my $reload_list_file = "/run/nixos/reload-list";
# Parse restart/reload requests by the activation script.
# Activation scripts may write newline-separated units to the restart
@@ -29,21 +42,23 @@ my $reloadListFile = "/run/nixos/reload-list";
# The reload file asks the script to reload a unit. This is the same as
# specifying a reload trigger in the NixOS module and can be ignored if
# the unit is restarted in this activation.
-my $restartByActivationFile = "/run/nixos/activation-restart-list";
-my $reloadByActivationFile = "/run/nixos/activation-reload-list";
-my $dryRestartByActivationFile = "/run/nixos/dry-activation-restart-list";
-my $dryReloadByActivationFile = "/run/nixos/dry-activation-reload-list";
+my $restart_by_activation_file = "/run/nixos/activation-restart-list";
+my $reload_by_activation_file = "/run/nixos/activation-reload-list";
+my $dry_restart_by_activation_file = "/run/nixos/dry-activation-restart-list";
+my $dry_reload_by_activation_file = "/run/nixos/dry-activation-reload-list";
-make_path("/run/nixos", { mode => oct(755) });
-
-my $action = shift @ARGV;
+# The action that is to be performed (like switch, boot, test, dry-activate)
+# Also exposed via environment variable from now on
+my $action = shift(@ARGV);
+$ENV{NIXOS_ACTION} = $action;
+# Expose the locale archive as an environment variable for systemctl and the activation script
if ("@localeArchive@" ne "") {
$ENV{LOCALE_ARCHIVE} = "@localeArchive@";
}
-if (!defined $action || ($action ne "switch" && $action ne "boot" && $action ne "test" && $action ne "dry-activate")) {
- print STDERR < 'quiet') // "") =~ /ID="?nixos"?/s;
+if (!-f "/etc/NIXOS" && (read_file("/etc/os-release", err_mode => "quiet") // "") !~ /^ID="?nixos"?/msx) {
+ die("This is not a NixOS installation!\n");
+}
+make_path("/run/nixos", { mode => oct(755) });
openlog("nixos", "", LOG_USER);
# Install or update the bootloader.
if ($action eq "switch" || $action eq "boot") {
- system("@installBootLoader@ $out") == 0 or exit 1;
+ chomp(my $install_boot_loader = <<'EOFBOOTLOADER');
+@installBootLoader@
+EOFBOOTLOADER
+ system("$install_boot_loader $out") == 0 or exit 1;
}
# Just in case the new configuration hangs the system, do a sync now.
-system("@coreutils@/bin/sync", "-f", "/nix/store") unless ($ENV{"NIXOS_NO_SYNC"} // "") eq "1";
+if (($ENV{"NIXOS_NO_SYNC"} // "") ne "1") {
+ system("@coreutils@/bin/sync", "-f", "/nix/store");
+}
-exit 0 if $action eq "boot";
+if ($action eq "boot") {
+ exit(0);
+}
# Check if we can activate the new configuration.
-my $oldVersion = read_file("/run/current-system/init-interface-version", err_mode => 'quiet') // "";
-my $newVersion = read_file("$out/init-interface-version");
+my $cur_init_interface_version = read_file("/run/current-system/init-interface-version", err_mode => "quiet") // "";
+my $new_init_interface_version = read_file("$out/init-interface-version");
-if ($newVersion ne $oldVersion) {
- print STDERR <system->get_service("org.freedesktop.systemd1")->get_object("/org/freedesktop/systemd1");
my $units = $mgr->ListUnitsByPatterns([], []);
my $res = {};
- for my $item (@$units) {
+ for my $item (@{$units}) {
my ($id, $description, $load_state, $active_state, $sub_state,
- $following, $unit_path, $job_id, $job_type, $job_path) = @$item;
- next unless $following eq '';
- next if $job_id == 0 and $active_state eq 'inactive';
+ $following, $unit_path, $job_id, $job_type, $job_path) = @{$item};
+ if ($following ne "") {
+ next;
+ }
+ if ($job_id == 0 and $active_state eq "inactive") {
+ next;
+ }
$res->{$id} = { load => $load_state, state => $active_state, substate => $sub_state };
}
return $res;
}
-sub parseFstab {
+# Asks the currently running systemd instance whether a unit is currently active.
+# Takes the name of the unit as an argument and returns a bool whether the unit is active or not.
+sub unit_is_active {
+ my ($unit_name) = @_;
+
+ my $mgr = Net::DBus->system->get_service("org.freedesktop.systemd1")->get_object("/org/freedesktop/systemd1");
+ my $units = $mgr->ListUnitsByNames([$unit_name]);
+ if (scalar(@{$units}) == 0) {
+ return 0;
+ }
+ my $active_state = $units->[0]->[3];
+ return $active_state eq "active" || $active_state eq "activating";
+}
+
+# Parse a fstab file, given its path.
+# Returns a tuple of filesystems and swaps.
+#
+# Filesystems is a hash of mountpoint and { device, fsType, options }
+# Swaps is a hash of device and { options }
+sub parse_fstab {
my ($filename) = @_;
my ($fss, $swaps);
- foreach my $line (read_file($filename, err_mode => 'quiet')) {
- chomp $line;
- $line =~ s/^\s*#.*//;
- next if $line =~ /^\s*$/;
- my @xs = split / /, $line;
+ foreach my $line (read_file($filename, err_mode => "quiet")) {
+ chomp($line);
+ $line =~ s/^\s*\#.*//msx;
+ if ($line =~ /^\s*$/msx) {
+ next;
+ }
+ my @xs = split(/\s+/msx, $line);
if ($xs[2] eq "swap") {
$swaps->{$xs[0]} = { options => $xs[3] // "" };
} else {
@@ -130,36 +180,35 @@ sub parseFstab {
#
# Instead of returning the hash, this subroutine takes a hashref to return the data in. This
# allows calling the subroutine multiple times with the same hash to parse override files.
-sub parseSystemdIni {
- my ($unitContents, $path) = @_;
+sub parse_systemd_ini {
+ my ($unit_contents, $path) = @_;
# Tie the ini file to a hash for easier access
- my %fileContents;
- tie %fileContents, "Config::IniFiles", (-file => $path, -allowempty => 1, -allowcontinue => 1);
+ tie(my %file_contents, "Config::IniFiles", (-file => $path, -allowempty => 1, -allowcontinue => 1)); ## no critic(Miscellanea::ProhibitTies)
# Copy over all sections
- foreach my $sectionName (keys %fileContents) {
- if ($sectionName eq "Install") {
+ foreach my $section_name (keys(%file_contents)) {
+ if ($section_name eq "Install") {
# Skip the [Install] section because it has no relevant keys for us
next;
}
# Copy over all keys
- foreach my $iniKey (keys %{$fileContents{$sectionName}}) {
+ foreach my $ini_key (keys(%{$file_contents{$section_name}})) {
# Ensure the value is an array so it's easier to work with
- my $iniValue = $fileContents{$sectionName}{$iniKey};
- my @iniValues;
- if (ref($iniValue) eq "ARRAY") {
- @iniValues = @{$iniValue};
+ my $ini_value = $file_contents{$section_name}{$ini_key};
+ my @ini_values;
+ if (ref($ini_value) eq "ARRAY") {
+ @ini_values = @{$ini_value};
} else {
- @iniValues = $iniValue;
+ @ini_values = $ini_value;
}
# Go over all values
- for my $iniValue (@iniValues) {
+ for my $ini_value (@ini_values) {
# If a value is empty, it's an override that tells us to clean the value
- if ($iniValue eq "") {
- delete $unitContents->{$sectionName}->{$iniKey};
+ if ($ini_value eq "") {
+ delete $unit_contents->{$section_name}->{$ini_key};
next;
}
- push(@{$unitContents->{$sectionName}->{$iniKey}}, $iniValue);
+ push(@{$unit_contents->{$section_name}->{$ini_key}}, $ini_value);
}
}
}
@@ -168,7 +217,7 @@ sub parseSystemdIni {
# This subroutine takes the path to a systemd configuration file (like a unit configuration),
# parses it, and returns a hash that contains the contents. The contents of this hash are
-# explained in the `parseSystemdIni` subroutine. Neither the sections nor the keys inside
+# explained in the `parse_systemd_ini` subroutine. Neither the sections nor the keys inside
# the sections are consistently sorted.
#
# If a directory with the same basename ending in .d exists next to the unit file, it will be
@@ -181,37 +230,45 @@ sub parse_unit {
# Replace \ with \\ so glob() still works with units that have a \ in them
# Valid characters in unit names are ASCII letters, digits, ":", "-", "_", ".", and "\"
$unit_path =~ s/\\/\\\\/gmsx;
- foreach (glob "${unit_path}{,.d/*.conf}") {
- parseSystemdIni(\%unit_data, "$_")
+ foreach (glob("${unit_path}{,.d/*.conf}")) {
+ parse_systemd_ini(\%unit_data, "$_")
}
return %unit_data;
}
# Checks whether a specified boolean in a systemd unit is true
# or false, with a default that is applied when the value is not set.
-sub parseSystemdBool {
- my ($unitConfig, $sectionName, $boolName, $default) = @_;
+sub parse_systemd_bool {
+ my ($unit_config, $section_name, $bool_name, $default) = @_;
- my @values = @{$unitConfig->{$sectionName}{$boolName} // []};
+ my @values = @{$unit_config->{$section_name}{$bool_name} // []};
# Return default if value is not set
- if (scalar @values lt 1 || not defined $values[-1]) {
+ if ((scalar(@values) < 1) || (not defined($values[-1]))) {
return $default;
}
# If value is defined multiple times, use the last definition
- my $last = $values[-1];
+ my $last_value = $values[-1];
# These are valid values as of systemd.syntax(7)
- return $last eq "1" || $last eq "yes" || $last eq "true" || $last eq "on";
+ return $last_value eq "1" || $last_value eq "yes" || $last_value eq "true" || $last_value eq "on";
}
-sub recordUnit {
+# Writes a unit name into a given file to be more resilient against
+# crashes of the script. Does nothing when the action is dry-activate.
+sub record_unit {
my ($fn, $unit) = @_;
- write_file($fn, { append => 1 }, "$unit\n") if $action ne "dry-activate";
+ if ($action ne "dry-activate") {
+ write_file($fn, { append => 1 }, "$unit\n");
+ }
+ return;
}
-# The opposite of recordUnit, removes a unit name from a file
+# The opposite of record_unit, removes a unit name from a file
sub unrecord_unit {
my ($fn, $unit) = @_;
- edit_file { s/^$unit\n//msx } $fn if $action ne "dry-activate";
+ if ($action ne "dry-activate") {
+ edit_file(sub { s/^$unit\n//msx }, $fn);
+ }
+ return;
}
# Compare the contents of two unit files and return whether the unit
@@ -223,9 +280,19 @@ sub unrecord_unit {
# - 0 if the units are equal
# - 1 if the units are different and a restart action is required
# - 2 if the units are different and a reload action is required
-sub compare_units {
- my ($old_unit, $new_unit) = @_;
+sub compare_units { ## no critic(Subroutines::ProhibitExcessComplexity)
+ my ($cur_unit, $new_unit) = @_;
my $ret = 0;
+ # Keys to ignore in the [Unit] section
+ my %unit_section_ignores = map { $_ => 1 } qw(
+ X-Reload-Triggers
+ Description Documentation
+ OnFailure OnSuccess OnFailureJobMode
+ IgnoreOnIsolate StopWhenUnneeded
+ RefuseManualStart RefuseManualStop
+ AllowIsolate CollectMode
+ SourcePath
+ );
my $comp_array = sub {
my ($a, $b) = @_;
@@ -233,12 +300,24 @@ sub compare_units {
};
# Comparison hash for the sections
- my %section_cmp = map { $_ => 1 } keys %{$new_unit};
+ my %section_cmp = map { $_ => 1 } keys(%{$new_unit});
# Iterate over the sections
- foreach my $section_name (keys %{$old_unit}) {
+ foreach my $section_name (keys(%{$cur_unit})) {
# Missing section in the new unit?
- if (not exists $section_cmp{$section_name}) {
- if ($section_name eq 'Unit' and %{$old_unit->{'Unit'}} == 1 and defined(%{$old_unit->{'Unit'}}{'X-Reload-Triggers'})) {
+ if (not exists($section_cmp{$section_name})) {
+ # If the [Unit] section was removed, make sure that only keys
+ # were in it that are ignored
+ if ($section_name eq "Unit") {
+ foreach my $ini_key (keys(%{$cur_unit->{"Unit"}})) {
+ if (not defined($unit_section_ignores{$ini_key})) {
+ return 1;
+ }
+ }
+ next; # check the next section
+ } else {
+ return 1;
+ }
+ if ($section_name eq "Unit" and %{$cur_unit->{"Unit"}} == 1 and defined(%{$cur_unit->{"Unit"}}{"X-Reload-Triggers"})) {
# If a new [Unit] section was removed that only contained X-Reload-Triggers,
# do nothing.
next;
@@ -248,46 +327,61 @@ sub compare_units {
}
delete $section_cmp{$section_name};
# Comparison hash for the section contents
- my %ini_cmp = map { $_ => 1 } keys %{$new_unit->{$section_name}};
+ my %ini_cmp = map { $_ => 1 } keys(%{$new_unit->{$section_name}});
# Iterate over the keys of the section
- foreach my $ini_key (keys %{$old_unit->{$section_name}}) {
+ foreach my $ini_key (keys(%{$cur_unit->{$section_name}})) {
delete $ini_cmp{$ini_key};
- my @old_value = @{$old_unit->{$section_name}{$ini_key}};
+ my @cur_value = @{$cur_unit->{$section_name}{$ini_key}};
# If the key is missing in the new unit, they are different...
if (not $new_unit->{$section_name}{$ini_key}) {
- # ... unless the key that is now missing was the reload trigger
- if ($section_name eq 'Unit' and $ini_key eq 'X-Reload-Triggers') {
+ # ... unless the key that is now missing is one of the ignored keys
+ if ($section_name eq "Unit" and defined($unit_section_ignores{$ini_key})) {
next;
}
return 1;
}
my @new_value = @{$new_unit->{$section_name}{$ini_key}};
# If the contents are different, the units are different
- if (not $comp_array->(\@old_value, \@new_value)) {
- # Check if only the reload triggers changed
- if ($section_name eq 'Unit' and $ini_key eq 'X-Reload-Triggers') {
- $ret = 2;
- } else {
- return 1;
+ if (not $comp_array->(\@cur_value, \@new_value)) {
+ # Check if only the reload triggers changed or one of the ignored keys
+ if ($section_name eq "Unit") {
+ if ($ini_key eq "X-Reload-Triggers") {
+ $ret = 2;
+ next;
+ } elsif (defined($unit_section_ignores{$ini_key})) {
+ next;
+ }
}
+ return 1;
}
}
- # A key was introduced that was missing in the old unit
+ # A key was introduced that was missing in the previous unit
if (%ini_cmp) {
- if ($section_name eq 'Unit' and %ini_cmp == 1 and defined($ini_cmp{'X-Reload-Triggers'})) {
- # If the newly introduced key was the reload triggers, reload the unit
- $ret = 2;
+ if ($section_name eq "Unit") {
+ foreach my $ini_key (keys(%ini_cmp)) {
+ if ($ini_key eq "X-Reload-Triggers") {
+ $ret = 2;
+ } elsif (defined($unit_section_ignores{$ini_key})) {
+ next;
+ } else {
+ return 1;
+ }
+ }
} else {
return 1;
}
};
}
- # A section was introduced that was missing in the old unit
+ # A section was introduced that was missing in the previous unit
if (%section_cmp) {
- if (%section_cmp == 1 and defined($section_cmp{'Unit'}) and %{$new_unit->{'Unit'}} == 1 and defined(%{$new_unit->{'Unit'}}{'X-Reload-Triggers'})) {
- # If a new [Unit] section was introduced that only contains X-Reload-Triggers,
- # reload instead of restarting
- $ret = 2;
+ if (%section_cmp == 1 and defined($section_cmp{"Unit"})) {
+ foreach my $ini_key (keys(%{$new_unit->{"Unit"}})) {
+ if (not defined($unit_section_ignores{$ini_key})) {
+ return 1;
+ } elsif ($ini_key eq "X-Reload-Triggers") {
+ $ret = 2;
+ }
+ }
} else {
return 1;
}
@@ -296,72 +390,78 @@ sub compare_units {
return $ret;
}
-sub handleModifiedUnit {
- my ($unit, $baseName, $newUnitFile, $newUnitInfo, $activePrev, $unitsToStop, $unitsToStart, $unitsToReload, $unitsToRestart, $unitsToSkip) = @_;
+# Called when a unit exists in both the old systemd and the new system and the units
+# differ. This figures out of what units are to be stopped, restarted, reloaded, started, and skipped.
+sub handle_modified_unit { ## no critic(Subroutines::ProhibitManyArgs, Subroutines::ProhibitExcessComplexity)
+ my ($unit, $base_name, $new_unit_file, $new_unit_info, $active_cur, $units_to_stop, $units_to_start, $units_to_reload, $units_to_restart, $units_to_skip) = @_;
- if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target" || $unit =~ /\.path$/ || $unit =~ /\.slice$/) {
+ if ($unit eq "sysinit.target" || $unit eq "basic.target" || $unit eq "multi-user.target" || $unit eq "graphical.target" || $unit =~ /\.path$/msx || $unit =~ /\.slice$/msx) {
# Do nothing. These cannot be restarted directly.
# Slices and Paths don't have to be restarted since
# properties (resource limits and inotify watches)
# seem to get applied on daemon-reload.
- } elsif ($unit =~ /\.mount$/) {
+ } elsif ($unit =~ /\.mount$/msx) {
# Reload the changed mount unit to force a remount.
# FIXME: only reload when Options= changed, restart otherwise
- $unitsToReload->{$unit} = 1;
- recordUnit($reloadListFile, $unit);
- } elsif ($unit =~ /\.socket$/) {
+ $units_to_reload->{$unit} = 1;
+ record_unit($reload_list_file, $unit);
+ } elsif ($unit =~ /\.socket$/msx) {
# FIXME: do something?
# Attempt to fix this: https://github.com/NixOS/nixpkgs/pull/141192
# Revert of the attempt: https://github.com/NixOS/nixpkgs/pull/147609
# More details: https://github.com/NixOS/nixpkgs/issues/74899#issuecomment-981142430
} else {
- my %unitInfo = $newUnitInfo ? %{$newUnitInfo} : parse_unit($newUnitFile);
- if (parseSystemdBool(\%unitInfo, "Service", "X-ReloadIfChanged", 0) and not $unitsToRestart->{$unit} and not $unitsToStop->{$unit}) {
- $unitsToReload->{$unit} = 1;
- recordUnit($reloadListFile, $unit);
+ my %new_unit_info = $new_unit_info ? %{$new_unit_info} : parse_unit($new_unit_file);
+ if (parse_systemd_bool(\%new_unit_info, "Service", "X-ReloadIfChanged", 0) and not $units_to_restart->{$unit} and not $units_to_stop->{$unit}) {
+ $units_to_reload->{$unit} = 1;
+ record_unit($reload_list_file, $unit);
}
- elsif (!parseSystemdBool(\%unitInfo, "Service", "X-RestartIfChanged", 1) || parseSystemdBool(\%unitInfo, "Unit", "RefuseManualStop", 0) || parseSystemdBool(\%unitInfo, "Unit", "X-OnlyManualStart", 0)) {
- $unitsToSkip->{$unit} = 1;
+ elsif (!parse_systemd_bool(\%new_unit_info, "Service", "X-RestartIfChanged", 1) || parse_systemd_bool(\%new_unit_info, "Unit", "RefuseManualStop", 0) || parse_systemd_bool(\%new_unit_info, "Unit", "X-OnlyManualStart", 0)) {
+ $units_to_skip->{$unit} = 1;
} else {
# It doesn't make sense to stop and start non-services because
# they can't have ExecStop=
- if (!parseSystemdBool(\%unitInfo, "Service", "X-StopIfChanged", 1) || $unit !~ /\.service$/) {
+ if (!parse_systemd_bool(\%new_unit_info, "Service", "X-StopIfChanged", 1) || $unit !~ /\.service$/msx) {
# This unit should be restarted instead of
# stopped and started.
- $unitsToRestart->{$unit} = 1;
- recordUnit($restartListFile, $unit);
+ $units_to_restart->{$unit} = 1;
+ record_unit($restart_list_file, $unit);
# Remove from units to reload so we don't restart and reload
- if ($unitsToReload->{$unit}) {
- delete $unitsToReload->{$unit};
- unrecord_unit($reloadListFile, $unit);
+ if ($units_to_reload->{$unit}) {
+ delete $units_to_reload->{$unit};
+ unrecord_unit($reload_list_file, $unit);
}
} else {
# If this unit is socket-activated, then stop the
# socket unit(s) as well, and restart the
# socket(s) instead of the service.
my $socket_activated = 0;
- if ($unit =~ /\.service$/) {
- my @sockets = split(/ /, join(" ", @{$unitInfo{Service}{Sockets} // []}));
- if (scalar @sockets == 0) {
- @sockets = ("$baseName.socket");
+ if ($unit =~ /\.service$/msx) {
+ my @sockets = split(/\s+/msx, join(" ", @{$new_unit_info{Service}{Sockets} // []}));
+ if (scalar(@sockets) == 0) {
+ @sockets = ("$base_name.socket");
}
foreach my $socket (@sockets) {
- if (defined $activePrev->{$socket}) {
+ if (defined($active_cur->{$socket})) {
# We can now be sure this is a socket-activate unit
- $unitsToStop->{$socket} = 1;
+ $units_to_stop->{$socket} = 1;
# Only restart sockets that actually
# exist in new configuration:
if (-e "$out/etc/systemd/system/$socket") {
- $unitsToStart->{$socket} = 1;
- recordUnit($startListFile, $socket);
+ $units_to_start->{$socket} = 1;
+ if ($units_to_start eq $units_to_restart) {
+ record_unit($restart_list_file, $socket);
+ } else {
+ record_unit($start_list_file, $socket);
+ }
$socket_activated = 1;
}
# Remove from units to reload so we don't restart and reload
- if ($unitsToReload->{$unit}) {
- delete $unitsToReload->{$unit};
- unrecord_unit($reloadListFile, $unit);
+ if ($units_to_reload->{$unit}) {
+ delete $units_to_reload->{$unit};
+ unrecord_unit($reload_list_file, $unit);
}
}
}
@@ -372,60 +472,67 @@ sub handleModifiedUnit {
# We write this to a file to ensure that the
# service gets restarted if we're interrupted.
if (!$socket_activated) {
- $unitsToStart->{$unit} = 1;
- recordUnit($startListFile, $unit);
+ $units_to_start->{$unit} = 1;
+ if ($units_to_start eq $units_to_restart) {
+ record_unit($restart_list_file, $unit);
+ } else {
+ record_unit($start_list_file, $unit);
+ }
}
- $unitsToStop->{$unit} = 1;
+ $units_to_stop->{$unit} = 1;
# Remove from units to reload so we don't restart and reload
- if ($unitsToReload->{$unit}) {
- delete $unitsToReload->{$unit};
- unrecord_unit($reloadListFile, $unit);
+ if ($units_to_reload->{$unit}) {
+ delete $units_to_reload->{$unit};
+ unrecord_unit($reload_list_file, $unit);
}
}
}
}
+ return;
}
# Figure out what units need to be stopped, started, restarted or reloaded.
-my (%unitsToStop, %unitsToSkip, %unitsToStart, %unitsToRestart, %unitsToReload);
+my (%units_to_stop, %units_to_skip, %units_to_start, %units_to_restart, %units_to_reload);
-my %unitsToFilter; # units not shown
+my %units_to_filter; # units not shown
-$unitsToStart{$_} = 1 foreach
- split('\n', read_file($startListFile, err_mode => 'quiet') // "");
+%units_to_start = map { $_ => 1 }
+ split(/\n/msx, read_file($start_list_file, err_mode => "quiet") // "");
-$unitsToRestart{$_} = 1 foreach
- split('\n', read_file($restartListFile, err_mode => 'quiet') // "");
+%units_to_restart = map { $_ => 1 }
+ split(/\n/msx, read_file($restart_list_file, err_mode => "quiet") // "");
-$unitsToReload{$_} = 1 foreach
- split('\n', read_file($reloadListFile, err_mode => 'quiet') // "");
+%units_to_reload = map { $_ => 1 }
+ split(/\n/msx, read_file($reload_list_file, err_mode => "quiet") // "");
-my $activePrev = getActiveUnits;
-while (my ($unit, $state) = each %{$activePrev}) {
- my $baseUnit = $unit;
+my $active_cur = get_active_units();
+while (my ($unit, $state) = each(%{$active_cur})) {
+ my $base_unit = $unit;
- my $prevUnitFile = "/etc/systemd/system/$baseUnit";
- my $newUnitFile = "$out/etc/systemd/system/$baseUnit";
+ my $cur_unit_file = "/etc/systemd/system/$base_unit";
+ my $new_unit_file = "$out/etc/systemd/system/$base_unit";
# Detect template instances.
- if (!-e $prevUnitFile && !-e $newUnitFile && $unit =~ /^(.*)@[^\.]*\.(.*)$/) {
- $baseUnit = "$1\@.$2";
- $prevUnitFile = "/etc/systemd/system/$baseUnit";
- $newUnitFile = "$out/etc/systemd/system/$baseUnit";
+ if (!-e $cur_unit_file && !-e $new_unit_file && $unit =~ /^(.*)@[^\.]*\.(.*)$/msx) {
+ $base_unit = "$1\@.$2";
+ $cur_unit_file = "/etc/systemd/system/$base_unit";
+ $new_unit_file = "$out/etc/systemd/system/$base_unit";
}
- my $baseName = $baseUnit;
- $baseName =~ s/\.[a-z]*$//;
+ my $base_name = $base_unit;
+ $base_name =~ s/\.[[:lower:]]*$//msx;
- if (-e $prevUnitFile && ($state->{state} eq "active" || $state->{state} eq "activating")) {
- if (! -e $newUnitFile || abs_path($newUnitFile) eq "/dev/null") {
- my %unitInfo = parse_unit($prevUnitFile);
- $unitsToStop{$unit} = 1 if parseSystemdBool(\%unitInfo, "Unit", "X-StopOnRemoval", 1);
+ if (-e $cur_unit_file && ($state->{state} eq "active" || $state->{state} eq "activating")) {
+ if (! -e $new_unit_file || abs_path($new_unit_file) eq "/dev/null") {
+ my %cur_unit_info = parse_unit($cur_unit_file);
+ if (parse_systemd_bool(\%cur_unit_info, "Unit", "X-StopOnRemoval", 1)) {
+ $units_to_stop{$unit} = 1;
+ }
}
- elsif ($unit =~ /\.target$/) {
- my %unitInfo = parse_unit($newUnitFile);
+ elsif ($unit =~ /\.target$/msx) {
+ my %new_unit_info = parse_unit($new_unit_file);
# Cause all active target units to be restarted below.
# This should start most changed units we stop here as
@@ -434,11 +541,11 @@ while (my ($unit, $state) = each %{$activePrev}) {
# active after the system has resumed, which probably
# should not be the case. Just ignore it.
if ($unit ne "suspend.target" && $unit ne "hibernate.target" && $unit ne "hybrid-sleep.target") {
- unless (parseSystemdBool(\%unitInfo, "Unit", "RefuseManualStart", 0) || parseSystemdBool(\%unitInfo, "Unit", "X-OnlyManualStart", 0)) {
- $unitsToStart{$unit} = 1;
- recordUnit($startListFile, $unit);
+ if (!(parse_systemd_bool(\%new_unit_info, "Unit", "RefuseManualStart", 0) || parse_systemd_bool(\%new_unit_info, "Unit", "X-OnlyManualStart", 0))) {
+ $units_to_start{$unit} = 1;
+ record_unit($start_list_file, $unit);
# Don't spam the user with target units that always get started.
- $unitsToFilter{$unit} = 1;
+ $units_to_filter{$unit} = 1;
}
}
@@ -453,33 +560,35 @@ while (my ($unit, $state) = each %{$activePrev}) {
# Stopping a target generally has no effect on other units
# (unless there is a PartOf dependency), so this is just a
# bookkeeping thing to get systemd to do the right thing.
- if (parseSystemdBool(\%unitInfo, "Unit", "X-StopOnReconfiguration", 0)) {
- $unitsToStop{$unit} = 1;
+ if (parse_systemd_bool(\%new_unit_info, "Unit", "X-StopOnReconfiguration", 0)) {
+ $units_to_stop{$unit} = 1;
}
}
else {
- my %old_unit_info = parse_unit($prevUnitFile);
- my %new_unit_info = parse_unit($newUnitFile);
- my $diff = compare_units(\%old_unit_info, \%new_unit_info);
- if ($diff eq 1) {
- handleModifiedUnit($unit, $baseName, $newUnitFile, \%new_unit_info, $activePrev, \%unitsToStop, \%unitsToStart, \%unitsToReload, \%unitsToRestart, \%unitsToSkip);
- } elsif ($diff eq 2 and not $unitsToRestart{$unit}) {
- $unitsToReload{$unit} = 1;
- recordUnit($reloadListFile, $unit);
+ my %cur_unit_info = parse_unit($cur_unit_file);
+ my %new_unit_info = parse_unit($new_unit_file);
+ my $diff = compare_units(\%cur_unit_info, \%new_unit_info);
+ if ($diff == 1) {
+ handle_modified_unit($unit, $base_name, $new_unit_file, \%new_unit_info, $active_cur, \%units_to_stop, \%units_to_start, \%units_to_reload, \%units_to_restart, \%units_to_skip);
+ } elsif ($diff == 2 and not $units_to_restart{$unit}) {
+ $units_to_reload{$unit} = 1;
+ record_unit($reload_list_file, $unit);
}
}
}
}
-sub pathToUnitName {
+# Converts a path to the name of a systemd mount unit that would be responsible
+# for mounting this path.
+sub path_to_unit_name {
my ($path) = @_;
# Use current version of systemctl binary before daemon is reexeced.
- open my $cmd, "-|", "$curSystemd/systemd-escape", "--suffix=mount", "-p", $path
+ open(my $cmd, "-|", "$cur_systemd/systemd-escape", "--suffix=mount", "-p", $path)
or die "Unable to escape $path!\n";
- my $escaped = join "", <$cmd>;
- chomp $escaped;
- close $cmd or die;
+ my $escaped = do { local $/ = undef; <$cmd> };
+ chomp($escaped);
+ close($cmd) or die("Unable to close systemd-escape pipe");
return $escaped;
}
@@ -488,32 +597,32 @@ sub pathToUnitName {
# automatically by starting local-fs.target. FIXME: might be nicer if
# we generated units for all mounts; then we could unify this with the
# unit checking code above.
-my ($prevFss, $prevSwaps) = parseFstab "/etc/fstab";
-my ($newFss, $newSwaps) = parseFstab "$out/etc/fstab";
-foreach my $mountPoint (keys %$prevFss) {
- my $prev = $prevFss->{$mountPoint};
- my $new = $newFss->{$mountPoint};
- my $unit = pathToUnitName($mountPoint);
- if (!defined $new) {
+my ($cur_fss, $cur_swaps) = parse_fstab("/etc/fstab");
+my ($new_fss, $new_swaps) = parse_fstab("$out/etc/fstab");
+foreach my $mount_point (keys(%{$cur_fss})) {
+ my $cur = $cur_fss->{$mount_point};
+ my $new = $new_fss->{$mount_point};
+ my $unit = path_to_unit_name($mount_point);
+ if (!defined($new)) {
# Filesystem entry disappeared, so unmount it.
- $unitsToStop{$unit} = 1;
- } elsif ($prev->{fsType} ne $new->{fsType} || $prev->{device} ne $new->{device}) {
+ $units_to_stop{$unit} = 1;
+ } elsif ($cur->{fsType} ne $new->{fsType} || $cur->{device} ne $new->{device}) {
# Filesystem type or device changed, so unmount and mount it.
- $unitsToStop{$unit} = 1;
- $unitsToStart{$unit} = 1;
- recordUnit($startListFile, $unit);
- } elsif ($prev->{options} ne $new->{options}) {
+ $units_to_stop{$unit} = 1;
+ $units_to_start{$unit} = 1;
+ record_unit($start_list_file, $unit);
+ } elsif ($cur->{options} ne $new->{options}) {
# Mount options changes, so remount it.
- $unitsToReload{$unit} = 1;
- recordUnit($reloadListFile, $unit);
+ $units_to_reload{$unit} = 1;
+ record_unit($reload_list_file, $unit);
}
}
# Also handles swap devices.
-foreach my $device (keys %$prevSwaps) {
- my $prev = $prevSwaps->{$device};
- my $new = $newSwaps->{$device};
- if (!defined $new) {
+foreach my $device (keys(%{$cur_swaps})) {
+ my $cur = $cur_swaps->{$device};
+ my $new = $new_swaps->{$device};
+ if (!defined($new)) {
# Swap entry disappeared, so turn it off. Can't use
# "systemctl stop" here because systemd has lots of alias
# units that prevent a stop from actually calling
@@ -530,97 +639,109 @@ foreach my $device (keys %$prevSwaps) {
# Should we have systemd re-exec itself?
-my $prevSystemd = abs_path("/proc/1/exe") // "/unknown";
-my $prevSystemdSystemConfig = abs_path("/etc/systemd/system.conf") // "/unknown";
-my $newSystemd = abs_path("@systemd@/lib/systemd/systemd") or die;
-my $newSystemdSystemConfig = abs_path("$out/etc/systemd/system.conf") // "/unknown";
+my $cur_pid1_path = abs_path("/proc/1/exe") // "/unknown";
+my $cur_systemd_system_config = abs_path("/etc/systemd/system.conf") // "/unknown";
+my $new_pid1_path = abs_path("$new_systemd/lib/systemd/systemd") or die;
+my $new_systemd_system_config = abs_path("$out/etc/systemd/system.conf") // "/unknown";
-my $restartSystemd = $prevSystemd ne $newSystemd;
-if ($prevSystemdSystemConfig ne $newSystemdSystemConfig) {
- $restartSystemd = 1;
+my $restart_systemd = $cur_pid1_path ne $new_pid1_path;
+if ($cur_systemd_system_config ne $new_systemd_system_config) {
+ $restart_systemd = 1;
}
-
-sub filterUnits {
+# Takes an array of unit names and returns an array with the same elements,
+# except all units that are also in the global variable `unitsToFilter`.
+sub filter_units {
my ($units) = @_;
my @res;
- foreach my $unit (sort(keys %{$units})) {
- push @res, $unit if !defined $unitsToFilter{$unit};
+ foreach my $unit (sort(keys(%{$units}))) {
+ if (!defined($units_to_filter{$unit})) {
+ push(@res, $unit);
+ }
}
return @res;
}
-my @unitsToStopFiltered = filterUnits(\%unitsToStop);
+my @units_to_stop_filtered = filter_units(\%units_to_stop);
# Show dry-run actions.
if ($action eq "dry-activate") {
- print STDERR "would stop the following units: ", join(", ", @unitsToStopFiltered), "\n"
- if scalar @unitsToStopFiltered > 0;
- print STDERR "would NOT stop the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
- if scalar(keys %unitsToSkip) > 0;
+ if (scalar(@units_to_stop_filtered) > 0) {
+ print STDERR "would stop the following units: ", join(", ", @units_to_stop_filtered), "\n";
+ }
+ if (scalar(keys(%units_to_skip)) > 0) {
+ print STDERR "would NOT stop the following changed units: ", join(", ", sort(keys(%units_to_skip))), "\n";
+ }
print STDERR "would activate the configuration...\n";
system("$out/dry-activate", "$out");
# Handle the activation script requesting the restart or reload of a unit.
- foreach (split('\n', read_file($dryRestartByActivationFile, err_mode => 'quiet') // "")) {
+ foreach (split(/\n/msx, read_file($dry_restart_by_activation_file, err_mode => "quiet") // "")) {
my $unit = $_;
- my $baseUnit = $unit;
- my $newUnitFile = "$out/etc/systemd/system/$baseUnit";
+ my $base_unit = $unit;
+ my $new_unit_file = "$out/etc/systemd/system/$base_unit";
# Detect template instances.
- if (!-e $newUnitFile && $unit =~ /^(.*)@[^\.]*\.(.*)$/) {
- $baseUnit = "$1\@.$2";
- $newUnitFile = "$out/etc/systemd/system/$baseUnit";
+ if (!-e $new_unit_file && $unit =~ /^(.*)@[^\.]*\.(.*)$/msx) {
+ $base_unit = "$1\@.$2";
+ $new_unit_file = "$out/etc/systemd/system/$base_unit";
}
- my $baseName = $baseUnit;
- $baseName =~ s/\.[a-z]*$//;
+ my $base_name = $base_unit;
+ $base_name =~ s/\.[[:lower:]]*$//msx;
# Start units if they were not active previously
- if (not defined $activePrev->{$unit}) {
- $unitsToStart{$unit} = 1;
+ if (not defined($active_cur->{$unit})) {
+ $units_to_start{$unit} = 1;
next;
}
- handleModifiedUnit($unit, $baseName, $newUnitFile, undef, $activePrev, \%unitsToRestart, \%unitsToRestart, \%unitsToReload, \%unitsToRestart, \%unitsToSkip);
+ handle_modified_unit($unit, $base_name, $new_unit_file, undef, $active_cur, \%units_to_restart, \%units_to_restart, \%units_to_reload, \%units_to_restart, \%units_to_skip);
}
- unlink($dryRestartByActivationFile);
+ unlink($dry_restart_by_activation_file);
- foreach (split('\n', read_file($dryReloadByActivationFile, err_mode => 'quiet') // "")) {
+ foreach (split(/\n/msx, read_file($dry_reload_by_activation_file, err_mode => "quiet") // "")) {
my $unit = $_;
- if (defined($activePrev->{$unit}) and not $unitsToRestart{$unit} and not $unitsToStop{$unit}) {
- $unitsToReload{$unit} = 1;
- recordUnit($reloadListFile, $unit);
+ if (defined($active_cur->{$unit}) and not $units_to_restart{$unit} and not $units_to_stop{$unit}) {
+ $units_to_reload{$unit} = 1;
+ record_unit($reload_list_file, $unit);
}
}
- unlink($dryReloadByActivationFile);
+ unlink($dry_reload_by_activation_file);
- print STDERR "would restart systemd\n" if $restartSystemd;
- print STDERR "would reload the following units: ", join(", ", sort(keys %unitsToReload)), "\n"
- if scalar(keys %unitsToReload) > 0;
- print STDERR "would restart the following units: ", join(", ", sort(keys %unitsToRestart)), "\n"
- if scalar(keys %unitsToRestart) > 0;
- my @unitsToStartFiltered = filterUnits(\%unitsToStart);
- print STDERR "would start the following units: ", join(", ", @unitsToStartFiltered), "\n"
- if scalar @unitsToStartFiltered;
+ if ($restart_systemd) {
+ print STDERR "would restart systemd\n";
+ }
+ if (scalar(keys(%units_to_reload)) > 0) {
+ print STDERR "would reload the following units: ", join(", ", sort(keys(%units_to_reload))), "\n";
+ }
+ if (scalar(keys(%units_to_restart)) > 0) {
+ print STDERR "would restart the following units: ", join(", ", sort(keys(%units_to_restart))), "\n";
+ }
+ my @units_to_start_filtered = filter_units(\%units_to_start);
+ if (scalar(@units_to_start_filtered)) {
+ print STDERR "would start the following units: ", join(", ", @units_to_start_filtered), "\n";
+ }
exit 0;
}
syslog(LOG_NOTICE, "switching to system configuration $out");
-if (scalar (keys %unitsToStop) > 0) {
- print STDERR "stopping the following units: ", join(", ", @unitsToStopFiltered), "\n"
- if scalar @unitsToStopFiltered;
+if (scalar(keys(%units_to_stop)) > 0) {
+ if (scalar(@units_to_stop_filtered)) {
+ print STDERR "stopping the following units: ", join(", ", @units_to_stop_filtered), "\n";
+ }
# Use current version of systemctl binary before daemon is reexeced.
- system("$curSystemd/systemctl", "stop", "--", sort(keys %unitsToStop));
+ system("$cur_systemd/systemctl", "stop", "--", sort(keys(%units_to_stop)));
}
-print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys %unitsToSkip)), "\n"
- if scalar(keys %unitsToSkip) > 0;
+if (scalar(keys(%units_to_skip)) > 0) {
+ print STDERR "NOT restarting the following changed units: ", join(", ", sort(keys(%units_to_skip))), "\n";
+}
# Activate the new configuration (i.e., update /etc, make accounts,
# and so on).
@@ -629,90 +750,110 @@ print STDERR "activating the configuration...\n";
system("$out/activate", "$out") == 0 or $res = 2;
# Handle the activation script requesting the restart or reload of a unit.
-foreach (split('\n', read_file($restartByActivationFile, err_mode => 'quiet') // "")) {
+foreach (split(/\n/msx, read_file($restart_by_activation_file, err_mode => "quiet") // "")) {
my $unit = $_;
- my $baseUnit = $unit;
- my $newUnitFile = "$out/etc/systemd/system/$baseUnit";
+ my $base_unit = $unit;
+ my $new_unit_file = "$out/etc/systemd/system/$base_unit";
# Detect template instances.
- if (!-e $newUnitFile && $unit =~ /^(.*)@[^\.]*\.(.*)$/) {
- $baseUnit = "$1\@.$2";
- $newUnitFile = "$out/etc/systemd/system/$baseUnit";
+ if (!-e $new_unit_file && $unit =~ /^(.*)@[^\.]*\.(.*)$/msx) {
+ $base_unit = "$1\@.$2";
+ $new_unit_file = "$out/etc/systemd/system/$base_unit";
}
- my $baseName = $baseUnit;
- $baseName =~ s/\.[a-z]*$//;
+ my $base_name = $base_unit;
+ $base_name =~ s/\.[[:lower:]]*$//msx;
# Start units if they were not active previously
- if (not defined $activePrev->{$unit}) {
- $unitsToStart{$unit} = 1;
- recordUnit($startListFile, $unit);
+ if (not defined($active_cur->{$unit})) {
+ $units_to_start{$unit} = 1;
+ record_unit($start_list_file, $unit);
next;
}
- handleModifiedUnit($unit, $baseName, $newUnitFile, undef, $activePrev, \%unitsToRestart, \%unitsToRestart, \%unitsToReload, \%unitsToRestart, \%unitsToSkip);
+ handle_modified_unit($unit, $base_name, $new_unit_file, undef, $active_cur, \%units_to_restart, \%units_to_restart, \%units_to_reload, \%units_to_restart, \%units_to_skip);
}
# We can remove the file now because it has been propagated to the other restart/reload files
-unlink($restartByActivationFile);
+unlink($restart_by_activation_file);
-foreach (split('\n', read_file($reloadByActivationFile, err_mode => 'quiet') // "")) {
+foreach (split(/\n/msx, read_file($reload_by_activation_file, err_mode => "quiet") // "")) {
my $unit = $_;
- if (defined($activePrev->{$unit}) and not $unitsToRestart{$unit} and not $unitsToStop{$unit}) {
- $unitsToReload{$unit} = 1;
- recordUnit($reloadListFile, $unit);
+ if (defined($active_cur->{$unit}) and not $units_to_restart{$unit} and not $units_to_stop{$unit}) {
+ $units_to_reload{$unit} = 1;
+ record_unit($reload_list_file, $unit);
}
}
# We can remove the file now because it has been propagated to the other reload file
-unlink($reloadByActivationFile);
+unlink($reload_by_activation_file);
# Restart systemd if necessary. Note that this is done using the
# current version of systemd, just in case the new one has trouble
# communicating with the running pid 1.
-if ($restartSystemd) {
+if ($restart_systemd) {
print STDERR "restarting systemd...\n";
- system("$curSystemd/systemctl", "daemon-reexec") == 0 or $res = 2;
+ system("$cur_systemd/systemctl", "daemon-reexec") == 0 or $res = 2;
}
# Forget about previously failed services.
-system("@systemd@/bin/systemctl", "reset-failed");
+system("$new_systemd/bin/systemctl", "reset-failed");
# Make systemd reload its units.
-system("@systemd@/bin/systemctl", "daemon-reload") == 0 or $res = 3;
+system("$new_systemd/bin/systemctl", "daemon-reload") == 0 or $res = 3;
# Reload user units
-open my $listActiveUsers, '-|', '@systemd@/bin/loginctl', 'list-users', '--no-legend';
-while (my $f = <$listActiveUsers>) {
- next unless $f =~ /^\s*(?\d+)\s+(?\S+)/;
+open(my $list_active_users, "-|", "$new_systemd/bin/loginctl", "list-users", "--no-legend") || die("Unable to call loginctl");
+while (my $f = <$list_active_users>) {
+ if ($f !~ /^\s*(?\d+)\s+(?\S+)/msx) {
+ next;
+ }
my ($uid, $name) = ($+{uid}, $+{user});
print STDERR "reloading user units for $name...\n";
system("@su@", "-s", "@shell@", "-l", $name, "-c",
"export XDG_RUNTIME_DIR=/run/user/$uid; " .
- "$curSystemd/systemctl --user daemon-reexec; " .
- "@systemd@/bin/systemctl --user start nixos-activation.service");
+ "$cur_systemd/systemctl --user daemon-reexec; " .
+ "$new_systemd/bin/systemctl --user start nixos-activation.service");
}
-close $listActiveUsers;
+close($list_active_users) || die("Unable to close the file handle to loginctl");
# Set the new tmpfiles
print STDERR "setting up tmpfiles\n";
-system("@systemd@/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3;
+system("$new_systemd/bin/systemd-tmpfiles", "--create", "--remove", "--exclude-prefix=/dev") == 0 or $res = 3;
+# Before reloading we need to ensure that the units are still active. They may have been
+# deactivated because one of their requirements got stopped. If they are inactive
+# but should have been reloaded, the user probably expects them to be started.
+if (scalar(keys(%units_to_reload)) > 0) {
+ for my $unit (keys(%units_to_reload)) {
+ if (!unit_is_active($unit)) {
+ # Figure out if we need to start the unit
+ my %unit_info = parse_unit("$out/etc/systemd/system/$unit");
+ if (!(parse_systemd_bool(\%unit_info, "Unit", "RefuseManualStart", 0) || parse_systemd_bool(\%unit_info, "Unit", "X-OnlyManualStart", 0))) {
+ $units_to_start{$unit} = 1;
+ record_unit($start_list_file, $unit);
+ }
+ # Don't reload the unit, reloading would fail
+ delete %units_to_reload{$unit};
+ unrecord_unit($reload_list_file, $unit);
+ }
+ }
+}
# Reload units that need it. This includes remounting changed mount
# units.
-if (scalar(keys %unitsToReload) > 0) {
- print STDERR "reloading the following units: ", join(", ", sort(keys %unitsToReload)), "\n";
- system("@systemd@/bin/systemctl", "reload", "--", sort(keys %unitsToReload)) == 0 or $res = 4;
- unlink($reloadListFile);
+if (scalar(keys(%units_to_reload)) > 0) {
+ print STDERR "reloading the following units: ", join(", ", sort(keys(%units_to_reload))), "\n";
+ system("$new_systemd/bin/systemctl", "reload", "--", sort(keys(%units_to_reload))) == 0 or $res = 4;
+ unlink($reload_list_file);
}
# Restart changed services (those that have to be restarted rather
# than stopped and started).
-if (scalar(keys %unitsToRestart) > 0) {
- print STDERR "restarting the following units: ", join(", ", sort(keys %unitsToRestart)), "\n";
- system("@systemd@/bin/systemctl", "restart", "--", sort(keys %unitsToRestart)) == 0 or $res = 4;
- unlink($restartListFile);
+if (scalar(keys(%units_to_restart)) > 0) {
+ print STDERR "restarting the following units: ", join(", ", sort(keys(%units_to_restart))), "\n";
+ system("$new_systemd/bin/systemctl", "restart", "--", sort(keys(%units_to_restart))) == 0 or $res = 4;
+ unlink($restart_list_file);
}
# Start all active targets, as well as changed units we stopped above.
@@ -721,29 +862,32 @@ if (scalar(keys %unitsToRestart) > 0) {
# that are symlinks to other units. We shouldn't start both at the
# same time because we'll get a "Failed to add path to set" error from
# systemd.
-my @unitsToStartFiltered = filterUnits(\%unitsToStart);
-print STDERR "starting the following units: ", join(", ", @unitsToStartFiltered), "\n"
- if scalar @unitsToStartFiltered;
-system("@systemd@/bin/systemctl", "start", "--", sort(keys %unitsToStart)) == 0 or $res = 4;
-unlink($startListFile);
+my @units_to_start_filtered = filter_units(\%units_to_start);
+if (scalar(@units_to_start_filtered)) {
+ print STDERR "starting the following units: ", join(", ", @units_to_start_filtered), "\n"
+}
+system("$new_systemd/bin/systemctl", "start", "--", sort(keys(%units_to_start))) == 0 or $res = 4;
+unlink($start_list_file);
# Print failed and new units.
my (@failed, @new);
-my $activeNew = getActiveUnits;
-while (my ($unit, $state) = each %{$activeNew}) {
+my $active_new = get_active_units();
+while (my ($unit, $state) = each(%{$active_new})) {
if ($state->{state} eq "failed") {
- push @failed, $unit;
+ push(@failed, $unit);
next;
}
if ($state->{substate} eq "auto-restart") {
# A unit in auto-restart substate is a failure *if* it previously failed to start
- my $main_status = `@systemd@/bin/systemctl show --value --property=ExecMainStatus '$unit'`;
+ open(my $main_status_fd, "-|", "$new_systemd/bin/systemctl", "show", "--value", "--property=ExecMainStatus", $unit) || die("Unable to call 'systemctl show'");
+ my $main_status = do { local $/ = undef; <$main_status_fd> };
+ close($main_status_fd) || die("Unable to close 'systemctl show' fd");
chomp($main_status);
if ($main_status ne "0") {
- push @failed, $unit;
+ push(@failed, $unit);
next;
}
}
@@ -751,19 +895,19 @@ while (my ($unit, $state) = each %{$activeNew}) {
# Ignore scopes since they are not managed by this script but rather
# created and managed by third-party services via the systemd dbus API.
# This only lists units that are not failed (including ones that are in auto-restart but have not failed previously)
- if ($state->{state} ne "failed" && !defined $activePrev->{$unit} && $unit !~ /\.scope$/msx) {
- push @new, $unit;
+ if ($state->{state} ne "failed" && !defined($active_cur->{$unit}) && $unit !~ /\.scope$/msx) {
+ push(@new, $unit);
}
}
-if (scalar @new > 0) {
+if (scalar(@new) > 0) {
print STDERR "the following new units were started: ", join(", ", sort(@new)), "\n"
}
-if (scalar @failed > 0) {
- my @failed_sorted = sort @failed;
+if (scalar(@failed) > 0) {
+ my @failed_sorted = sort(@failed);
print STDERR "warning: the following units failed: ", join(", ", @failed_sorted), "\n\n";
- system "@systemd@/bin/systemctl status --no-pager --full '" . join("' '", @failed_sorted) . "' >&2";
+ system("$new_systemd/bin/systemctl status --no-pager --full '" . join("' '", @failed_sorted) . "' >&2");
$res = 4;
}
@@ -773,4 +917,4 @@ if ($res == 0) {
syslog(LOG_ERR, "switching to system configuration $out failed (status $res)");
}
-exit $res;
+exit($res);
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/kernel.nix b/third_party/nixpkgs/nixos/modules/system/boot/kernel.nix
index d147155d79..db00244ca0 100644
--- a/third_party/nixpkgs/nixos/modules/system/boot/kernel.nix
+++ b/third_party/nixpkgs/nixos/modules/system/boot/kernel.nix
@@ -36,7 +36,7 @@ in
boot.kernelPackages = mkOption {
default = pkgs.linuxPackages;
- type = types.unspecified // { merge = mergeEqualOption; };
+ type = types.raw;
apply = kernelPackages: kernelPackages.extend (self: super: {
kernel = super.kernel.override (originalArgs: {
inherit randstructSeed;
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py b/third_party/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
index adc8930630..fa879437fd 100644
--- a/third_party/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
+++ b/third_party/nixpkgs/nixos/modules/system/boot/loader/systemd-boot/systemd-boot-builder.py
@@ -15,9 +15,12 @@ import re
import datetime
import glob
import os.path
-from typing import Tuple, List, Optional
+from typing import NamedTuple, List, Optional
-SystemIdentifier = Tuple[Optional[str], int, Optional[str]]
+class SystemIdentifier(NamedTuple):
+ profile: Optional[str]
+ generation: int
+ specialisation: Optional[str]
def copy_if_not_exists(source: str, dest: str) -> None:
@@ -151,7 +154,14 @@ def get_generations(profile: Optional[str] = None) -> List[SystemIdentifier]:
gen_lines.pop()
configurationLimit = @configurationLimit@
- configurations: List[SystemIdentifier] = [ (profile, int(line.split()[0]), None) for line in gen_lines ]
+ configurations = [
+ SystemIdentifier(
+ profile=profile,
+ generation=int(line.split()[0]),
+ specialisation=None
+ )
+ for line in gen_lines
+ ]
return configurations[-configurationLimit:]
@@ -160,7 +170,7 @@ def get_specialisations(profile: Optional[str], generation: int, _: Optional[str
system_dir(profile, generation, None), "specialisation")
if not os.path.exists(specialisations_dir):
return []
- return [(profile, generation, spec) for spec in os.listdir(specialisations_dir)]
+ return [SystemIdentifier(profile, generation, spec) for spec in os.listdir(specialisations_dir)]
def remove_old_entries(gens: List[SystemIdentifier]) -> None:
@@ -271,7 +281,8 @@ def main() -> None:
if os.readlink(system_dir(*gen)) == args.default_config:
write_loader_conf(*gen)
except OSError as e:
- print("ignoring generation '{}' in the list of boot entries because of the following error:\n{}".format(*gen, e), file=sys.stderr)
+ profile = f"profile '{gen.profile}'" if gen.profile else "default profile"
+ print("ignoring {} in the list of boot entries because of the following error:\n{}".format(profile, e), file=sys.stderr)
for root, _, files in os.walk('@efiSysMountPoint@/efi/nixos/.extra-files', topdown=False):
relative_root = root.removeprefix("@efiSysMountPoint@/efi/nixos/.extra-files").removeprefix("/")
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/modprobe.nix b/third_party/nixpkgs/nixos/modules/system/boot/modprobe.nix
index 27f78835ad..e683d18172 100644
--- a/third_party/nixpkgs/nixos/modules/system/boot/modprobe.nix
+++ b/third_party/nixpkgs/nixos/modules/system/boot/modprobe.nix
@@ -34,23 +34,6 @@ with lib;
type = types.lines;
};
- boot.initrd.extraModprobeConfig = mkOption {
- default = "";
- example =
- ''
- options zfs zfs_arc_max=1073741824
- '';
- description = ''
- Does exactly the same thing as
- , except
- that the generated modprobe.conf
- file is also included in the initrd.
- This is useful for setting module options for kernel
- modules that are loaded during early boot in the initrd.
- '';
- type = types.lines;
- };
-
};
@@ -67,9 +50,6 @@ with lib;
'')}
${config.boot.extraModprobeConfig}
'';
- environment.etc."modprobe.d/nixos-initrd.conf".text = ''
- ${config.boot.initrd.extraModprobeConfig}
- '';
environment.etc."modprobe.d/debian.conf".source = pkgs.kmod-debian-aliases;
environment.etc."modprobe.d/systemd.conf".source = "${pkgs.systemd}/lib/modprobe.d/systemd.conf";
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/stage-1.nix b/third_party/nixpkgs/nixos/modules/system/boot/stage-1.nix
index 1575c0257d..8b011d9156 100644
--- a/third_party/nixpkgs/nixos/modules/system/boot/stage-1.nix
+++ b/third_party/nixpkgs/nixos/modules/system/boot/stage-1.nix
@@ -338,9 +338,6 @@ let
{ object = pkgs.writeText "mdadm.conf" config.boot.initrd.mdadmConf;
symlink = "/etc/mdadm.conf";
}
- { object = config.environment.etc."modprobe.d/nixos-initrd.conf".source;
- symlink = "/etc/modprobe.d/nixos-initrd.conf";
- }
{ object = pkgs.runCommand "initrd-kmod-blacklist-ubuntu" {
src = "${pkgs.kmod-blacklist-ubuntu}/modprobe.conf";
preferLocalBuild = true;
@@ -581,7 +578,7 @@ in
else "gzip"
);
defaultText = literalDocBook "zstd if the kernel supports it (5.9+), gzip if not";
- type = types.unspecified; # We don't have a function type...
+ type = types.either types.str (types.functionTo types.str);
description = ''
The compressor to use on the initrd image. May be any of:
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/stage-2.nix b/third_party/nixpkgs/nixos/modules/system/boot/stage-2.nix
index f6b6a8e4b0..fa2bf938df 100644
--- a/third_party/nixpkgs/nixos/modules/system/boot/stage-2.nix
+++ b/third_party/nixpkgs/nixos/modules/system/boot/stage-2.nix
@@ -47,36 +47,6 @@ in
'';
};
- devSize = mkOption {
- default = "5%";
- example = "32m";
- type = types.str;
- description = ''
- Size limit for the /dev tmpfs. Look at mount(8), tmpfs size option,
- for the accepted syntax.
- '';
- };
-
- devShmSize = mkOption {
- default = "50%";
- example = "256m";
- type = types.str;
- description = ''
- Size limit for the /dev/shm tmpfs. Look at mount(8), tmpfs size option,
- for the accepted syntax.
- '';
- };
-
- runSize = mkOption {
- default = "25%";
- example = "256m";
- type = types.str;
- description = ''
- Size limit for the /run tmpfs. Look at mount(8), tmpfs size option,
- for the accepted syntax.
- '';
- };
-
systemdExecutable = mkOption {
default = "systemd";
type = types.str;
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/systemd.nix b/third_party/nixpkgs/nixos/modules/system/boot/systemd.nix
index 4019af63ad..057474c607 100644
--- a/third_party/nixpkgs/nixos/modules/system/boot/systemd.nix
+++ b/third_party/nixpkgs/nixos/modules/system/boot/systemd.nix
@@ -2,7 +2,6 @@
with utils;
with systemdUtils.unitOptions;
-with systemdUtils.lib;
with lib;
let
@@ -11,6 +10,24 @@ let
systemd = cfg.package;
+ inherit (systemdUtils.lib)
+ makeUnit
+ generateUnits
+ makeJobScript
+ unitConfig
+ serviceConfig
+ mountConfig
+ automountConfig
+ commonUnitText
+ targetToUnit
+ serviceToUnit
+ socketToUnit
+ timerToUnit
+ pathToUnit
+ mountToUnit
+ automountToUnit
+ sliceToUnit;
+
upstreamSystemUnits =
[ # Targets.
"basic.target"
@@ -63,32 +80,6 @@ let
"printer.target"
"smartcard.target"
- # Login stuff.
- "systemd-logind.service"
- "autovt@.service"
- "systemd-user-sessions.service"
- "dbus-org.freedesktop.import1.service"
- "dbus-org.freedesktop.machine1.service"
- "dbus-org.freedesktop.login1.service"
- "user@.service"
- "user-runtime-dir@.service"
-
- # Journal.
- "systemd-journald.socket"
- "systemd-journald@.socket"
- "systemd-journald-varlink@.socket"
- "systemd-journald.service"
- "systemd-journald@.service"
- "systemd-journal-flush.service"
- "systemd-journal-catalog-update.service"
- ] ++ (optional (!config.boot.isContainer) "systemd-journald-audit.socket") ++ [
- "systemd-journald-dev-log.socket"
- "syslog.socket"
-
- # Coredumps.
- "systemd-coredump.socket"
- "systemd-coredump@.service"
-
# Kernel module loading.
"systemd-modules-load.service"
"kmod-static-nodes.service"
@@ -149,19 +140,12 @@ let
# Slices / containers.
"slices.target"
- "user.slice"
"machine.slice"
"machines.target"
"systemd-importd.service"
"systemd-machined.service"
"systemd-nspawn@.service"
- # Temporary file creation / cleanup.
- "systemd-tmpfiles-clean.service"
- "systemd-tmpfiles-clean.timer"
- "systemd-tmpfiles-setup.service"
- "systemd-tmpfiles-setup-dev.service"
-
# Misc.
"systemd-sysctl.service"
"dbus-org.freedesktop.timedate1.service"
@@ -172,9 +156,6 @@ let
"systemd-hostnamed.service"
"systemd-exit.service"
"systemd-update-done.service"
- ] ++ optionals config.services.journald.enableHttpGateway [
- "systemd-journal-gatewayd.socket"
- "systemd-journal-gatewayd.service"
] ++ cfg.additionalUpstreamSystemUnits;
upstreamSystemWants =
@@ -185,237 +166,6 @@ let
"timers.target.wants"
];
- upstreamUserUnits = [
- "app.slice"
- "background.slice"
- "basic.target"
- "bluetooth.target"
- "default.target"
- "exit.target"
- "graphical-session-pre.target"
- "graphical-session.target"
- "paths.target"
- "printer.target"
- "session.slice"
- "shutdown.target"
- "smartcard.target"
- "sockets.target"
- "sound.target"
- "systemd-exit.service"
- "systemd-tmpfiles-clean.service"
- "systemd-tmpfiles-clean.timer"
- "systemd-tmpfiles-setup.service"
- "timers.target"
- "xdg-desktop-autostart.target"
- ];
-
- makeJobScript = name: text:
- let
- scriptName = replaceChars [ "\\" "@" ] [ "-" "_" ] (shellEscape name);
- out = (pkgs.writeShellScriptBin scriptName ''
- set -e
- ${text}
- '').overrideAttrs (_: {
- # The derivation name is different from the script file name
- # to keep the script file name short to avoid cluttering logs.
- name = "unit-script-${scriptName}";
- });
- in "${out}/bin/${scriptName}";
-
- unitConfig = { config, options, ... }: {
- config = {
- unitConfig =
- optionalAttrs (config.requires != [])
- { Requires = toString config.requires; }
- // optionalAttrs (config.wants != [])
- { Wants = toString config.wants; }
- // optionalAttrs (config.after != [])
- { After = toString config.after; }
- // optionalAttrs (config.before != [])
- { Before = toString config.before; }
- // optionalAttrs (config.bindsTo != [])
- { BindsTo = toString config.bindsTo; }
- // optionalAttrs (config.partOf != [])
- { PartOf = toString config.partOf; }
- // optionalAttrs (config.conflicts != [])
- { Conflicts = toString config.conflicts; }
- // optionalAttrs (config.requisite != [])
- { Requisite = toString config.requisite; }
- // optionalAttrs (config.restartTriggers != [])
- { X-Restart-Triggers = toString config.restartTriggers; }
- // optionalAttrs (config.reloadTriggers != [])
- { X-Reload-Triggers = toString config.reloadTriggers; }
- // optionalAttrs (config.description != "") {
- Description = config.description; }
- // optionalAttrs (config.documentation != []) {
- Documentation = toString config.documentation; }
- // optionalAttrs (config.onFailure != []) {
- OnFailure = toString config.onFailure; }
- // optionalAttrs (options.startLimitIntervalSec.isDefined) {
- StartLimitIntervalSec = toString config.startLimitIntervalSec;
- } // optionalAttrs (options.startLimitBurst.isDefined) {
- StartLimitBurst = toString config.startLimitBurst;
- };
- };
- };
-
- serviceConfig = { name, config, ... }: {
- config = mkMerge
- [ { # Default path for systemd services. Should be quite minimal.
- path = mkAfter
- [ pkgs.coreutils
- pkgs.findutils
- pkgs.gnugrep
- pkgs.gnused
- systemd
- ];
- environment.PATH = "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
- }
- (mkIf (config.preStart != "")
- { serviceConfig.ExecStartPre =
- [ (makeJobScript "${name}-pre-start" config.preStart) ];
- })
- (mkIf (config.script != "")
- { serviceConfig.ExecStart =
- makeJobScript "${name}-start" config.script + " " + config.scriptArgs;
- })
- (mkIf (config.postStart != "")
- { serviceConfig.ExecStartPost =
- [ (makeJobScript "${name}-post-start" config.postStart) ];
- })
- (mkIf (config.reload != "")
- { serviceConfig.ExecReload =
- makeJobScript "${name}-reload" config.reload;
- })
- (mkIf (config.preStop != "")
- { serviceConfig.ExecStop =
- makeJobScript "${name}-pre-stop" config.preStop;
- })
- (mkIf (config.postStop != "")
- { serviceConfig.ExecStopPost =
- makeJobScript "${name}-post-stop" config.postStop;
- })
- ];
- };
-
- mountConfig = { config, ... }: {
- config = {
- mountConfig =
- { What = config.what;
- Where = config.where;
- } // optionalAttrs (config.type != "") {
- Type = config.type;
- } // optionalAttrs (config.options != "") {
- Options = config.options;
- };
- };
- };
-
- automountConfig = { config, ... }: {
- config = {
- automountConfig =
- { Where = config.where;
- };
- };
- };
-
- commonUnitText = def: ''
- [Unit]
- ${attrsToSection def.unitConfig}
- '';
-
- targetToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text =
- ''
- [Unit]
- ${attrsToSection def.unitConfig}
- '';
- };
-
- serviceToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text = commonUnitText def +
- ''
- [Service]
- ${let env = cfg.globalEnvironment // def.environment;
- in concatMapStrings (n:
- let s = optionalString (env.${n} != null)
- "Environment=${builtins.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)}
- ${if def.reloadIfChanged then ''
- X-ReloadIfChanged=true
- '' else if !def.restartIfChanged then ''
- X-RestartIfChanged=false
- '' else ""}
- ${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
- ${attrsToSection def.serviceConfig}
- '';
- };
-
- socketToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text = commonUnitText def +
- ''
- [Socket]
- ${attrsToSection def.socketConfig}
- ${concatStringsSep "\n" (map (s: "ListenStream=${s}") def.listenStreams)}
- ${concatStringsSep "\n" (map (s: "ListenDatagram=${s}") def.listenDatagrams)}
- '';
- };
-
- timerToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text = commonUnitText def +
- ''
- [Timer]
- ${attrsToSection def.timerConfig}
- '';
- };
-
- pathToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text = commonUnitText def +
- ''
- [Path]
- ${attrsToSection def.pathConfig}
- '';
- };
-
- mountToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text = commonUnitText def +
- ''
- [Mount]
- ${attrsToSection def.mountConfig}
- '';
- };
-
- automountToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text = commonUnitText def +
- ''
- [Automount]
- ${attrsToSection def.automountConfig}
- '';
- };
-
- sliceToUnit = name: def:
- { inherit (def) aliases wantedBy requiredBy enable;
- text = commonUnitText def +
- ''
- [Slice]
- ${attrsToSection def.sliceConfig}
- '';
- };
-
- logindHandlerType = types.enum [
- "ignore" "poweroff" "reboot" "halt" "kexec" "suspend"
- "hibernate" "hybrid-sleep" "suspend-then-hibernate" "lock"
- ];
-
proxy_env = config.networking.proxy.envVars;
in
@@ -568,26 +318,6 @@ in
'';
};
- systemd.coredump.enable = mkOption {
- default = true;
- type = types.bool;
- description = ''
- Whether core dumps should be processed by
- systemd-coredump. If disabled, core dumps
- appear in the current directory of the crashing process.
- '';
- };
-
- systemd.coredump.extraConfig = mkOption {
- default = "";
- type = types.lines;
- example = "Storage=journal";
- description = ''
- Extra config options for systemd-coredump. See coredump.conf(5) man page
- for available options.
- '';
- };
-
systemd.extraConfig = mkOption {
default = "";
type = types.lines;
@@ -598,142 +328,6 @@ in
'';
};
- services.journald.console = mkOption {
- default = "";
- type = types.str;
- description = "If non-empty, write log messages to the specified TTY device.";
- };
-
- services.journald.rateLimitInterval = mkOption {
- default = "30s";
- type = types.str;
- description = ''
- Configures the rate limiting interval that is applied to all
- messages generated on the system. This rate limiting is applied
- per-service, so that two services which log do not interfere with
- each other's limit. The value may be specified in the following
- units: s, min, h, ms, us. To turn off any kind of rate limiting,
- set either value to 0.
-
- See for important
- considerations when setting this value.
- '';
- };
-
- services.journald.rateLimitBurst = mkOption {
- default = 10000;
- type = types.int;
- description = ''
- Configures the rate limiting burst limit (number of messages per
- interval) that is applied to all messages generated on the system.
- This rate limiting is applied per-service, so that two services
- which log do not interfere with each other's limit.
-
- Note that the effective rate limit is multiplied by a factor derived
- from the available free disk space for the journal as described on
-
- journald.conf(5).
-
- Note that the total amount of logs stored is limited by journald settings
- such as SystemMaxUse, which defaults to a 4 GB cap.
-
- It is thus recommended to compute what period of time that you will be
- able to store logs for when an application logs at full burst rate.
- With default settings for log lines that are 100 Bytes long, this can
- amount to just a few hours.
- '';
- };
-
- services.journald.extraConfig = mkOption {
- default = "";
- type = types.lines;
- example = "Storage=volatile";
- description = ''
- Extra config options for systemd-journald. See man journald.conf
- for available options.
- '';
- };
-
- services.journald.enableHttpGateway = mkOption {
- default = false;
- type = types.bool;
- description = ''
- Whether to enable the HTTP gateway to the journal.
- '';
- };
-
- services.journald.forwardToSyslog = mkOption {
- default = config.services.rsyslogd.enable || config.services.syslog-ng.enable;
- defaultText = literalExpression "services.rsyslogd.enable || services.syslog-ng.enable";
- type = types.bool;
- description = ''
- Whether to forward log messages to syslog.
- '';
- };
-
- services.logind.extraConfig = mkOption {
- default = "";
- type = types.lines;
- example = "IdleAction=lock";
- description = ''
- Extra config options for systemd-logind. See
-
- logind.conf(5) for available options.
- '';
- };
-
- services.logind.killUserProcesses = mkOption {
- default = false;
- type = types.bool;
- description = ''
- Specifies whether the processes of a user should be killed
- when the user logs out. If true, the scope unit corresponding
- to the session and all processes inside that scope will be
- terminated. If false, the scope is "abandoned" (see
-
- systemd.scope(5)), and processes are not killed.
-
-
-
- See logind.conf(5)
- for more details.
- '';
- };
-
- services.logind.lidSwitch = mkOption {
- default = "suspend";
- example = "ignore";
- type = logindHandlerType;
-
- description = ''
- Specifies what to be done when the laptop lid is closed.
- '';
- };
-
- services.logind.lidSwitchDocked = mkOption {
- default = "ignore";
- example = "suspend";
- type = logindHandlerType;
-
- description = ''
- Specifies what to be done when the laptop lid is closed
- and another screen is added.
- '';
- };
-
- services.logind.lidSwitchExternalPower = mkOption {
- default = config.services.logind.lidSwitch;
- defaultText = literalExpression "services.logind.lidSwitch";
- example = "ignore";
- type = logindHandlerType;
-
- description = ''
- Specifies what to do when the laptop lid is closed and the system is
- on external power. By default use the same action as specified in
- services.logind.lidSwitch.
- '';
- };
-
systemd.sleep.extraConfig = mkOption {
default = "";
type = types.lines;
@@ -744,95 +338,6 @@ in
'';
};
- systemd.user.extraConfig = mkOption {
- default = "";
- type = types.lines;
- example = "DefaultCPUAccounting=yes";
- description = ''
- Extra config options for systemd user instances. See man systemd-user.conf for
- available options.
- '';
- };
-
- systemd.tmpfiles.rules = mkOption {
- type = types.listOf types.str;
- default = [];
- example = [ "d /tmp 1777 root root 10d" ];
- description = ''
- Rules for creation, deletion and cleaning of volatile and temporary files
- automatically. See
- tmpfiles.d5
- for the exact format.
- '';
- };
-
- systemd.tmpfiles.packages = mkOption {
- type = types.listOf types.package;
- default = [];
- example = literalExpression "[ pkgs.lvm2 ]";
- apply = map getLib;
- description = ''
- List of packages containing systemd-tmpfiles rules.
-
- All files ending in .conf found in
- pkg/lib/tmpfiles.d
- will be included.
- If this folder does not exist or does not contain any files an error will be returned instead.
-
- If a lib output is available, rules are searched there and only there.
- If there is no lib output it will fall back to out
- and if that does not exist either, the default output will be used.
- '';
- };
-
- systemd.user.units = mkOption {
- description = "Definition of systemd per-user units.";
- default = {};
- type = with types; attrsOf (submodule (
- { name, config, ... }:
- { options = concreteUnitOptions;
- config = {
- unit = mkDefault (makeUnit name config);
- };
- }));
- };
-
- systemd.user.paths = mkOption {
- default = {};
- type = with types; attrsOf (submodule [ { options = pathOptions; } unitConfig ]);
- description = "Definition of systemd per-user path units.";
- };
-
- systemd.user.services = mkOption {
- default = {};
- type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ] );
- description = "Definition of systemd per-user service units.";
- };
-
- systemd.user.slices = mkOption {
- default = {};
- type = with types; attrsOf (submodule [ { options = sliceOptions; } unitConfig ] );
- description = "Definition of systemd per-user slice units.";
- };
-
- systemd.user.sockets = mkOption {
- default = {};
- type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ] );
- description = "Definition of systemd per-user socket units.";
- };
-
- systemd.user.targets = mkOption {
- default = {};
- type = with types; attrsOf (submodule [ { options = targetOptions; } unitConfig] );
- description = "Definition of systemd per-user target units.";
- };
-
- systemd.user.timers = mkOption {
- default = {};
- type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ] );
- description = "Definition of systemd per-user timer units.";
- };
-
systemd.additionalUpstreamSystemUnits = mkOption {
default = [ ];
type = types.listOf types.str;
@@ -968,8 +473,6 @@ in
in ({
"systemd/system".source = generateUnits "system" enabledUnits enabledUpstreamSystemUnits upstreamSystemWants;
- "systemd/user".source = generateUnits "user" cfg.user.units upstreamUserUnits [];
-
"systemd/system.conf".text = ''
[Manager]
${optionalString config.systemd.enableCgroupAccounting ''
@@ -995,76 +498,17 @@ in
${config.systemd.extraConfig}
'';
- "systemd/user.conf".text = ''
- [Manager]
- ${config.systemd.user.extraConfig}
- '';
-
- "systemd/journald.conf".text = ''
- [Journal]
- Storage=persistent
- RateLimitInterval=${config.services.journald.rateLimitInterval}
- RateLimitBurst=${toString config.services.journald.rateLimitBurst}
- ${optionalString (config.services.journald.console != "") ''
- ForwardToConsole=yes
- TTYPath=${config.services.journald.console}
- ''}
- ${optionalString (config.services.journald.forwardToSyslog) ''
- ForwardToSyslog=yes
- ''}
- ${config.services.journald.extraConfig}
- '';
-
- "systemd/coredump.conf".text =
- ''
- [Coredump]
- ${config.systemd.coredump.extraConfig}
- '';
-
- "systemd/logind.conf".text = ''
- [Login]
- KillUserProcesses=${if config.services.logind.killUserProcesses then "yes" else "no"}
- HandleLidSwitch=${config.services.logind.lidSwitch}
- HandleLidSwitchDocked=${config.services.logind.lidSwitchDocked}
- HandleLidSwitchExternalPower=${config.services.logind.lidSwitchExternalPower}
- ${config.services.logind.extraConfig}
- '';
-
"systemd/sleep.conf".text = ''
[Sleep]
${config.systemd.sleep.extraConfig}
'';
- # install provided sysctl snippets
- "sysctl.d/50-coredump.conf".source = "${systemd}/example/sysctl.d/50-coredump.conf";
- "sysctl.d/50-default.conf".source = "${systemd}/example/sysctl.d/50-default.conf";
-
- "tmpfiles.d".source = (pkgs.symlinkJoin {
- name = "tmpfiles.d";
- paths = map (p: p + "/lib/tmpfiles.d") cfg.tmpfiles.packages;
- postBuild = ''
- for i in $(cat $pathsPath); do
- (test -d "$i" && test $(ls "$i"/*.conf | wc -l) -ge 1) || (
- echo "ERROR: The path '$i' from systemd.tmpfiles.packages contains no *.conf files."
- exit 1
- )
- done
- '' + concatMapStrings (name: optionalString (hasPrefix "tmpfiles.d/" name) ''
- rm -f $out/${removePrefix "tmpfiles.d/" name}
- '') config.system.build.etc.passthru.targets;
- }) + "/*";
-
"systemd/system-generators" = { source = hooks "generators" cfg.generators; };
"systemd/system-shutdown" = { source = hooks "shutdown" cfg.shutdown; };
});
services.dbus.enable = true;
- users.users.systemd-coredump = {
- uid = config.ids.uids.systemd-coredump;
- group = "systemd-coredump";
- };
- users.groups.systemd-coredump = {};
users.users.systemd-network = {
uid = config.ids.uids.systemd-network;
group = "systemd-network";
@@ -1084,36 +528,6 @@ in
unitConfig.X-StopOnReconfiguration = true;
};
- systemd.tmpfiles.packages = [
- # Default tmpfiles rules provided by systemd
- (pkgs.runCommand "systemd-default-tmpfiles" {} ''
- mkdir -p $out/lib/tmpfiles.d
- cd $out/lib/tmpfiles.d
-
- ln -s "${systemd}/example/tmpfiles.d/home.conf"
- ln -s "${systemd}/example/tmpfiles.d/journal-nocow.conf"
- ln -s "${systemd}/example/tmpfiles.d/static-nodes-permissions.conf"
- ln -s "${systemd}/example/tmpfiles.d/systemd.conf"
- ln -s "${systemd}/example/tmpfiles.d/systemd-nologin.conf"
- ln -s "${systemd}/example/tmpfiles.d/systemd-nspawn.conf"
- ln -s "${systemd}/example/tmpfiles.d/systemd-tmp.conf"
- ln -s "${systemd}/example/tmpfiles.d/tmp.conf"
- ln -s "${systemd}/example/tmpfiles.d/var.conf"
- ln -s "${systemd}/example/tmpfiles.d/x11.conf"
- '')
- # User-specified tmpfiles rules
- (pkgs.writeTextFile {
- name = "nixos-tmpfiles.d";
- destination = "/lib/tmpfiles.d/00-nixos.conf";
- text = ''
- # This file is created automatically and should not be modified.
- # Please change the option ‘systemd.tmpfiles.rules’ instead.
-
- ${concatStringsSep "\n" cfg.tmpfiles.rules}
- '';
- })
- ];
-
systemd.units =
mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths
// mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
@@ -1128,14 +542,6 @@ in
(v: let n = escapeSystemdPath v.where;
in nameValuePair "${n}.automount" (automountToUnit n v)) cfg.automounts);
- systemd.user.units =
- mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.user.paths
- // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.user.services
- // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.user.slices
- // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.user.sockets
- // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.user.targets
- // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.user.timers;
-
system.requiredKernelConfig = map config.lib.kernelConfig.isEnabled
[ "DEVTMPFS" "CGROUPS" "INOTIFY_USER" "SIGNALFD" "TIMERFD" "EPOLL" "NET"
"SYSFS" "PROC_FS" "FHANDLE" "CRYPTO_USER_API_HASH" "CRYPTO_HMAC"
@@ -1143,11 +549,6 @@ in
"TMPFS_XATTR" "SECCOMP"
];
- users.groups.systemd-journal.gid = config.ids.gids.systemd-journal;
- users.users.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway;
- users.users.systemd-journal-gateway.group = "systemd-journal-gateway";
- users.groups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway;
-
# Generate timer units for all services that have a ‘startAt’ value.
systemd.timers =
mapAttrs (name: service:
@@ -1164,42 +565,14 @@ in
})
(filterAttrs (name: service: service.startAt != []) cfg.user.services);
- systemd.sockets.systemd-journal-gatewayd.wantedBy =
- optional config.services.journald.enableHttpGateway "sockets.target";
-
- # Provide the systemd-user PAM service, required to run systemd
- # user instances.
- security.pam.services.systemd-user =
- { # Ensure that pam_systemd gets included. This is special-cased
- # in systemd to provide XDG_RUNTIME_DIR.
- startSession = true;
- };
-
# Some overrides to upstream units.
systemd.services."systemd-backlight@".restartIfChanged = false;
systemd.services."systemd-fsck@".restartIfChanged = false;
systemd.services."systemd-fsck@".path = [ config.system.path ];
- systemd.services."user@".restartIfChanged = false;
- systemd.services.systemd-journal-flush.restartIfChanged = false;
systemd.services.systemd-random-seed.restartIfChanged = false;
systemd.services.systemd-remount-fs.restartIfChanged = false;
systemd.services.systemd-update-utmp.restartIfChanged = false;
- systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
systemd.services.systemd-udev-settle.restartIfChanged = false; # Causes long delays in nixos-rebuild
- # Restarting systemd-logind breaks X11
- # - upstream commit: https://cgit.freedesktop.org/xorg/xserver/commit/?id=dc48bd653c7e101
- # - systemd announcement: https://github.com/systemd/systemd/blob/22043e4317ecd2bc7834b48a6d364de76bb26d91/NEWS#L103-L112
- # - this might be addressed in the future by xorg
- #systemd.services.systemd-logind.restartTriggers = [ config.environment.etc."systemd/logind.conf".source ];
- systemd.services.systemd-logind.restartIfChanged = false;
- systemd.services.systemd-logind.stopIfChanged = false;
- # The user-runtime-dir@ service is managed by systemd-logind we should not touch it or else we break the users' sessions.
- systemd.services."user-runtime-dir@".stopIfChanged = false;
- systemd.services."user-runtime-dir@".restartIfChanged = false;
- systemd.services.systemd-journald.restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
- systemd.services.systemd-journald.stopIfChanged = false;
- systemd.services."systemd-journald@".restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
- systemd.services."systemd-journald@".stopIfChanged = false;
systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true;
systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true;
systemd.targets.network-online.wantedBy = [ "multi-user.target" ];
@@ -1210,8 +583,6 @@ in
systemd.services.systemd-remount-fs.unitConfig.ConditionVirtualization = "!container";
systemd.services.systemd-random-seed.unitConfig.ConditionVirtualization = "!container";
- boot.kernel.sysctl."kernel.core_pattern" = mkIf (!cfg.coredump.enable) "core";
-
# Increase numeric PID range (set directly instead of copying a one-line file from systemd)
# https://github.com/systemd/systemd/pull/12226
boot.kernel.sysctl."kernel.pid_max" = mkIf pkgs.stdenv.is64bit (lib.mkDefault 4194304);
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix b/third_party/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix
new file mode 100644
index 0000000000..b6ee2cff1f
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/system/boot/systemd/coredump.nix
@@ -0,0 +1,57 @@
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+let
+ cfg = config.systemd.coredump;
+ systemd = config.systemd.package;
+in {
+ options = {
+ systemd.coredump.enable = mkOption {
+ default = true;
+ type = types.bool;
+ description = ''
+ Whether core dumps should be processed by
+ systemd-coredump. If disabled, core dumps
+ appear in the current directory of the crashing process.
+ '';
+ };
+
+ systemd.coredump.extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ example = "Storage=journal";
+ description = ''
+ Extra config options for systemd-coredump. See coredump.conf(5) man page
+ for available options.
+ '';
+ };
+ };
+
+ config = {
+ systemd.additionalUpstreamSystemUnits = [
+ "systemd-coredump.socket"
+ "systemd-coredump@.service"
+ ];
+
+ environment.etc = {
+ "systemd/coredump.conf".text =
+ ''
+ [Coredump]
+ ${cfg.extraConfig}
+ '';
+
+ # install provided sysctl snippets
+ "sysctl.d/50-coredump.conf".source = "${systemd}/example/sysctl.d/50-coredump.conf";
+ "sysctl.d/50-default.conf".source = "${systemd}/example/sysctl.d/50-default.conf";
+ };
+
+ users.users.systemd-coredump = {
+ uid = config.ids.uids.systemd-coredump;
+ group = "systemd-coredump";
+ };
+ users.groups.systemd-coredump = {};
+
+ boot.kernel.sysctl."kernel.core_pattern" = mkIf (!cfg.enable) "core";
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/systemd/journald.nix b/third_party/nixpkgs/nixos/modules/system/boot/systemd/journald.nix
new file mode 100644
index 0000000000..7e14c8ae40
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/system/boot/systemd/journald.nix
@@ -0,0 +1,131 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.services.journald;
+in {
+ options = {
+ services.journald.console = mkOption {
+ default = "";
+ type = types.str;
+ description = "If non-empty, write log messages to the specified TTY device.";
+ };
+
+ services.journald.rateLimitInterval = mkOption {
+ default = "30s";
+ type = types.str;
+ description = ''
+ Configures the rate limiting interval that is applied to all
+ messages generated on the system. This rate limiting is applied
+ per-service, so that two services which log do not interfere with
+ each other's limit. The value may be specified in the following
+ units: s, min, h, ms, us. To turn off any kind of rate limiting,
+ set either value to 0.
+
+ See for important
+ considerations when setting this value.
+ '';
+ };
+
+ services.journald.rateLimitBurst = mkOption {
+ default = 10000;
+ type = types.int;
+ description = ''
+ Configures the rate limiting burst limit (number of messages per
+ interval) that is applied to all messages generated on the system.
+ This rate limiting is applied per-service, so that two services
+ which log do not interfere with each other's limit.
+
+ Note that the effective rate limit is multiplied by a factor derived
+ from the available free disk space for the journal as described on
+
+ journald.conf(5).
+
+ Note that the total amount of logs stored is limited by journald settings
+ such as SystemMaxUse, which defaults to a 4 GB cap.
+
+ It is thus recommended to compute what period of time that you will be
+ able to store logs for when an application logs at full burst rate.
+ With default settings for log lines that are 100 Bytes long, this can
+ amount to just a few hours.
+ '';
+ };
+
+ services.journald.extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ example = "Storage=volatile";
+ description = ''
+ Extra config options for systemd-journald. See man journald.conf
+ for available options.
+ '';
+ };
+
+ services.journald.enableHttpGateway = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Whether to enable the HTTP gateway to the journal.
+ '';
+ };
+
+ services.journald.forwardToSyslog = mkOption {
+ default = config.services.rsyslogd.enable || config.services.syslog-ng.enable;
+ defaultText = literalExpression "services.rsyslogd.enable || services.syslog-ng.enable";
+ type = types.bool;
+ description = ''
+ Whether to forward log messages to syslog.
+ '';
+ };
+ };
+
+ config = {
+ systemd.additionalUpstreamSystemUnits = [
+ "systemd-journald.socket"
+ "systemd-journald@.socket"
+ "systemd-journald-varlink@.socket"
+ "systemd-journald.service"
+ "systemd-journald@.service"
+ "systemd-journal-flush.service"
+ "systemd-journal-catalog-update.service"
+ ] ++ (optional (!config.boot.isContainer) "systemd-journald-audit.socket") ++ [
+ "systemd-journald-dev-log.socket"
+ "syslog.socket"
+ ] ++ optionals cfg.enableHttpGateway [
+ "systemd-journal-gatewayd.socket"
+ "systemd-journal-gatewayd.service"
+ ];
+
+ environment.etc = {
+ "systemd/journald.conf".text = ''
+ [Journal]
+ Storage=persistent
+ RateLimitInterval=${cfg.rateLimitInterval}
+ RateLimitBurst=${toString cfg.rateLimitBurst}
+ ${optionalString (cfg.console != "") ''
+ ForwardToConsole=yes
+ TTYPath=${cfg.console}
+ ''}
+ ${optionalString (cfg.forwardToSyslog) ''
+ ForwardToSyslog=yes
+ ''}
+ ${cfg.extraConfig}
+ '';
+ };
+
+ users.groups.systemd-journal.gid = config.ids.gids.systemd-journal;
+ users.users.systemd-journal-gateway.uid = config.ids.uids.systemd-journal-gateway;
+ users.users.systemd-journal-gateway.group = "systemd-journal-gateway";
+ users.groups.systemd-journal-gateway.gid = config.ids.gids.systemd-journal-gateway;
+
+ systemd.sockets.systemd-journal-gatewayd.wantedBy =
+ optional cfg.enableHttpGateway "sockets.target";
+
+ systemd.services.systemd-journal-flush.restartIfChanged = false;
+ systemd.services.systemd-journald.restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
+ systemd.services.systemd-journald.stopIfChanged = false;
+ systemd.services."systemd-journald@".restartTriggers = [ config.environment.etc."systemd/journald.conf".source ];
+ systemd.services."systemd-journald@".stopIfChanged = false;
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/systemd/logind.nix b/third_party/nixpkgs/nixos/modules/system/boot/systemd/logind.nix
new file mode 100644
index 0000000000..c1e6cfe61d
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/system/boot/systemd/logind.nix
@@ -0,0 +1,114 @@
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+let
+ cfg = config.services.logind;
+
+ logindHandlerType = types.enum [
+ "ignore" "poweroff" "reboot" "halt" "kexec" "suspend"
+ "hibernate" "hybrid-sleep" "suspend-then-hibernate" "lock"
+ ];
+in
+{
+ options = {
+ services.logind.extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ example = "IdleAction=lock";
+ description = ''
+ Extra config options for systemd-logind. See
+
+ logind.conf(5) for available options.
+ '';
+ };
+
+ services.logind.killUserProcesses = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Specifies whether the processes of a user should be killed
+ when the user logs out. If true, the scope unit corresponding
+ to the session and all processes inside that scope will be
+ terminated. If false, the scope is "abandoned" (see
+
+ systemd.scope(5)), and processes are not killed.
+
+
+
+ See logind.conf(5)
+ for more details.
+ '';
+ };
+
+ services.logind.lidSwitch = mkOption {
+ default = "suspend";
+ example = "ignore";
+ type = logindHandlerType;
+
+ description = ''
+ Specifies what to be done when the laptop lid is closed.
+ '';
+ };
+
+ services.logind.lidSwitchDocked = mkOption {
+ default = "ignore";
+ example = "suspend";
+ type = logindHandlerType;
+
+ description = ''
+ Specifies what to be done when the laptop lid is closed
+ and another screen is added.
+ '';
+ };
+
+ services.logind.lidSwitchExternalPower = mkOption {
+ default = cfg.lidSwitch;
+ defaultText = literalExpression "services.logind.lidSwitch";
+ example = "ignore";
+ type = logindHandlerType;
+
+ description = ''
+ Specifies what to do when the laptop lid is closed and the system is
+ on external power. By default use the same action as specified in
+ services.logind.lidSwitch.
+ '';
+ };
+ };
+
+ config = {
+ systemd.additionalUpstreamSystemUnits = [
+ "systemd-logind.service"
+ "autovt@.service"
+ "systemd-user-sessions.service"
+ "dbus-org.freedesktop.import1.service"
+ "dbus-org.freedesktop.machine1.service"
+ "dbus-org.freedesktop.login1.service"
+ "user@.service"
+ "user-runtime-dir@.service"
+ ];
+
+ environment.etc = {
+ "systemd/logind.conf".text = ''
+ [Login]
+ KillUserProcesses=${if cfg.killUserProcesses then "yes" else "no"}
+ HandleLidSwitch=${cfg.lidSwitch}
+ HandleLidSwitchDocked=${cfg.lidSwitchDocked}
+ HandleLidSwitchExternalPower=${cfg.lidSwitchExternalPower}
+ ${cfg.extraConfig}
+ '';
+ };
+
+ # Restarting systemd-logind breaks X11
+ # - upstream commit: https://cgit.freedesktop.org/xorg/xserver/commit/?id=dc48bd653c7e101
+ # - systemd announcement: https://github.com/systemd/systemd/blob/22043e4317ecd2bc7834b48a6d364de76bb26d91/NEWS#L103-L112
+ # - this might be addressed in the future by xorg
+ #systemd.services.systemd-logind.restartTriggers = [ config.environment.etc."systemd/logind.conf".source ];
+ systemd.services.systemd-logind.restartIfChanged = false;
+ systemd.services.systemd-logind.stopIfChanged = false;
+
+ # The user-runtime-dir@ service is managed by systemd-logind we should not touch it or else we break the users' sessions.
+ systemd.services."user-runtime-dir@".stopIfChanged = false;
+ systemd.services."user-runtime-dir@".restartIfChanged = false;
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/systemd-nspawn.nix b/third_party/nixpkgs/nixos/modules/system/boot/systemd/nspawn.nix
similarity index 100%
rename from third_party/nixpkgs/nixos/modules/system/boot/systemd-nspawn.nix
rename to third_party/nixpkgs/nixos/modules/system/boot/systemd/nspawn.nix
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/systemd/tmpfiles.nix b/third_party/nixpkgs/nixos/modules/system/boot/systemd/tmpfiles.nix
new file mode 100644
index 0000000000..57d44c8591
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/system/boot/systemd/tmpfiles.nix
@@ -0,0 +1,104 @@
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+let
+ cfg = config.systemd.tmpfiles;
+ systemd = config.systemd.package;
+in
+{
+ options = {
+ systemd.tmpfiles.rules = mkOption {
+ type = types.listOf types.str;
+ default = [];
+ example = [ "d /tmp 1777 root root 10d" ];
+ description = ''
+ Rules for creation, deletion and cleaning of volatile and temporary files
+ automatically. See
+ tmpfiles.d5
+ for the exact format.
+ '';
+ };
+
+ systemd.tmpfiles.packages = mkOption {
+ type = types.listOf types.package;
+ default = [];
+ example = literalExpression "[ pkgs.lvm2 ]";
+ apply = map getLib;
+ description = ''
+ List of packages containing systemd-tmpfiles rules.
+
+ All files ending in .conf found in
+ pkg/lib/tmpfiles.d
+ will be included.
+ If this folder does not exist or does not contain any files an error will be returned instead.
+
+ If a lib output is available, rules are searched there and only there.
+ If there is no lib output it will fall back to out
+ and if that does not exist either, the default output will be used.
+ '';
+ };
+ };
+
+ config = {
+ systemd.additionalUpstreamSystemUnits = [
+ "systemd-tmpfiles-clean.service"
+ "systemd-tmpfiles-clean.timer"
+ "systemd-tmpfiles-setup.service"
+ "systemd-tmpfiles-setup-dev.service"
+ ];
+
+ systemd.additionalUpstreamUserUnits = [
+ "systemd-tmpfiles-clean.service"
+ "systemd-tmpfiles-clean.timer"
+ "systemd-tmpfiles-setup.service"
+ ];
+
+ environment.etc = {
+ "tmpfiles.d".source = (pkgs.symlinkJoin {
+ name = "tmpfiles.d";
+ paths = map (p: p + "/lib/tmpfiles.d") cfg.packages;
+ postBuild = ''
+ for i in $(cat $pathsPath); do
+ (test -d "$i" && test $(ls "$i"/*.conf | wc -l) -ge 1) || (
+ echo "ERROR: The path '$i' from systemd.tmpfiles.packages contains no *.conf files."
+ exit 1
+ )
+ done
+ '' + concatMapStrings (name: optionalString (hasPrefix "tmpfiles.d/" name) ''
+ rm -f $out/${removePrefix "tmpfiles.d/" name}
+ '') config.system.build.etc.passthru.targets;
+ }) + "/*";
+ };
+
+ systemd.tmpfiles.packages = [
+ # Default tmpfiles rules provided by systemd
+ (pkgs.runCommand "systemd-default-tmpfiles" {} ''
+ mkdir -p $out/lib/tmpfiles.d
+ cd $out/lib/tmpfiles.d
+
+ ln -s "${systemd}/example/tmpfiles.d/home.conf"
+ ln -s "${systemd}/example/tmpfiles.d/journal-nocow.conf"
+ ln -s "${systemd}/example/tmpfiles.d/static-nodes-permissions.conf"
+ ln -s "${systemd}/example/tmpfiles.d/systemd.conf"
+ ln -s "${systemd}/example/tmpfiles.d/systemd-nologin.conf"
+ ln -s "${systemd}/example/tmpfiles.d/systemd-nspawn.conf"
+ ln -s "${systemd}/example/tmpfiles.d/systemd-tmp.conf"
+ ln -s "${systemd}/example/tmpfiles.d/tmp.conf"
+ ln -s "${systemd}/example/tmpfiles.d/var.conf"
+ ln -s "${systemd}/example/tmpfiles.d/x11.conf"
+ '')
+ # User-specified tmpfiles rules
+ (pkgs.writeTextFile {
+ name = "nixos-tmpfiles.d";
+ destination = "/lib/tmpfiles.d/00-nixos.conf";
+ text = ''
+ # This file is created automatically and should not be modified.
+ # Please change the option ‘systemd.tmpfiles.rules’ instead.
+
+ ${concatStringsSep "\n" cfg.rules}
+ '';
+ })
+ ];
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/system/boot/systemd/user.nix b/third_party/nixpkgs/nixos/modules/system/boot/systemd/user.nix
new file mode 100644
index 0000000000..e30f83f345
--- /dev/null
+++ b/third_party/nixpkgs/nixos/modules/system/boot/systemd/user.nix
@@ -0,0 +1,158 @@
+{ config, lib, pkgs, utils, ... }:
+with utils;
+with systemdUtils.unitOptions;
+with lib;
+
+let
+ cfg = config.systemd.user;
+
+ systemd = config.systemd.package;
+
+ inherit
+ (systemdUtils.lib)
+ makeUnit
+ generateUnits
+ makeJobScript
+ unitConfig
+ serviceConfig
+ commonUnitText
+ targetToUnit
+ serviceToUnit
+ socketToUnit
+ timerToUnit
+ pathToUnit;
+
+ upstreamUserUnits = [
+ "app.slice"
+ "background.slice"
+ "basic.target"
+ "bluetooth.target"
+ "default.target"
+ "exit.target"
+ "graphical-session-pre.target"
+ "graphical-session.target"
+ "paths.target"
+ "printer.target"
+ "session.slice"
+ "shutdown.target"
+ "smartcard.target"
+ "sockets.target"
+ "sound.target"
+ "systemd-exit.service"
+ "timers.target"
+ "xdg-desktop-autostart.target"
+ ] ++ config.systemd.additionalUpstreamUserUnits;
+in {
+ options = {
+ systemd.user.extraConfig = mkOption {
+ default = "";
+ type = types.lines;
+ example = "DefaultCPUAccounting=yes";
+ description = ''
+ Extra config options for systemd user instances. See man systemd-user.conf for
+ available options.
+ '';
+ };
+
+ systemd.user.units = mkOption {
+ description = "Definition of systemd per-user units.";
+ default = {};
+ type = with types; attrsOf (submodule (
+ { name, config, ... }:
+ { options = concreteUnitOptions;
+ config = {
+ unit = mkDefault (makeUnit name config);
+ };
+ }));
+ };
+
+ systemd.user.paths = mkOption {
+ default = {};
+ type = with types; attrsOf (submodule [ { options = pathOptions; } unitConfig ]);
+ description = "Definition of systemd per-user path units.";
+ };
+
+ systemd.user.services = mkOption {
+ default = {};
+ type = with types; attrsOf (submodule [ { options = serviceOptions; } unitConfig serviceConfig ] );
+ description = "Definition of systemd per-user service units.";
+ };
+
+ systemd.user.slices = mkOption {
+ default = {};
+ type = with types; attrsOf (submodule [ { options = sliceOptions; } unitConfig ] );
+ description = "Definition of systemd per-user slice units.";
+ };
+
+ systemd.user.sockets = mkOption {
+ default = {};
+ type = with types; attrsOf (submodule [ { options = socketOptions; } unitConfig ] );
+ description = "Definition of systemd per-user socket units.";
+ };
+
+ systemd.user.targets = mkOption {
+ default = {};
+ type = with types; attrsOf (submodule [ { options = targetOptions; } unitConfig] );
+ description = "Definition of systemd per-user target units.";
+ };
+
+ systemd.user.timers = mkOption {
+ default = {};
+ type = with types; attrsOf (submodule [ { options = timerOptions; } unitConfig ] );
+ description = "Definition of systemd per-user timer units.";
+ };
+
+ systemd.additionalUpstreamUserUnits = mkOption {
+ default = [];
+ type = types.listOf types.str;
+ example = [];
+ description = ''
+ Additional units shipped with systemd that should be enabled for per-user systemd instances.
+ '';
+ internal = true;
+ };
+ };
+
+ config = {
+ systemd.additionalUpstreamSystemUnits = [
+ "user.slice"
+ ];
+
+ environment.etc = {
+ "systemd/user".source = generateUnits "user" cfg.units upstreamUserUnits [];
+
+ "systemd/user.conf".text = ''
+ [Manager]
+ ${cfg.extraConfig}
+ '';
+ };
+
+ systemd.user.units =
+ mapAttrs' (n: v: nameValuePair "${n}.path" (pathToUnit n v)) cfg.paths
+ // mapAttrs' (n: v: nameValuePair "${n}.service" (serviceToUnit n v)) cfg.services
+ // mapAttrs' (n: v: nameValuePair "${n}.slice" (sliceToUnit n v)) cfg.slices
+ // mapAttrs' (n: v: nameValuePair "${n}.socket" (socketToUnit n v)) cfg.sockets
+ // mapAttrs' (n: v: nameValuePair "${n}.target" (targetToUnit n v)) cfg.targets
+ // mapAttrs' (n: v: nameValuePair "${n}.timer" (timerToUnit n v)) cfg.timers;
+
+ # Generate timer units for all services that have a ‘startAt’ value.
+ systemd.user.timers =
+ mapAttrs (name: service: {
+ wantedBy = ["timers.target"];
+ timerConfig.OnCalendar = service.startAt;
+ })
+ (filterAttrs (name: service: service.startAt != []) cfg.services);
+
+ # Provide the systemd-user PAM service, required to run systemd
+ # user instances.
+ security.pam.services.systemd-user =
+ { # Ensure that pam_systemd gets included. This is special-cased
+ # in systemd to provide XDG_RUNTIME_DIR.
+ startSession = true;
+ };
+
+ # Some overrides to upstream units.
+ systemd.services."user@".restartIfChanged = false;
+ systemd.services.systemd-user-sessions.restartIfChanged = false; # Restart kills all active sessions.
+ };
+}
diff --git a/third_party/nixpkgs/nixos/modules/tasks/auto-upgrade.nix b/third_party/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
index b931b27ad8..1404dcbaf7 100644
--- a/third_party/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
+++ b/third_party/nixpkgs/nixos/modules/tasks/auto-upgrade.nix
@@ -80,6 +80,7 @@ in {
Reboot the system into the new generation instead of a switch
if the new generation uses a different kernel, kernel modules
or initrd than the booted system.
+ See for configuring the times at which a reboot is allowed.
'';
};
@@ -96,6 +97,32 @@ in {
'';
};
+ rebootWindow = mkOption {
+ description = ''
+ Define a lower and upper time value (in HH:MM format) which
+ constitute a time window during which reboots are allowed after an upgrade.
+ This option only has an effect when is enabled.
+ The default value of null means that reboots are allowed at any time.
+ '';
+ default = null;
+ example = { lower = "01:00"; upper = "05:00"; };
+ type = with types; nullOr (submodule {
+ options = {
+ lower = mkOption {
+ description = "Lower limit of the reboot window";
+ type = types.strMatching "[[:digit:]]{2}:[[:digit:]]{2}";
+ example = "01:00";
+ };
+
+ upper = mkOption {
+ description = "Upper limit of the reboot window";
+ type = types.strMatching "[[:digit:]]{2}:[[:digit:]]{2}";
+ example = "05:00";
+ };
+ };
+ });
+ };
+
};
};
@@ -110,12 +137,10 @@ in {
}];
system.autoUpgrade.flags = (if cfg.flake == null then
- [ "--no-build-output" ] ++ (if cfg.channel == null then
- [ "--upgrade" ]
- else [
+ [ "--no-build-output" ] ++ optionals (cfg.channel != null) [
"-I"
"nixpkgs=${cfg.channel}/nixexprs.tar.xz"
- ])
+ ]
else
[ "--flake ${cfg.flake}" ]);
@@ -143,19 +168,52 @@ in {
];
script = let
- nixos-rebuild =
- "${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
+ nixos-rebuild = "${config.system.build.nixos-rebuild}/bin/nixos-rebuild";
+ date = "${pkgs.coreutils}/bin/date";
+ readlink = "${pkgs.coreutils}/bin/readlink";
+ shutdown = "${pkgs.systemd}/bin/shutdown";
+ upgradeFlag = optional (cfg.channel == null) "--upgrade";
in if cfg.allowReboot then ''
- ${nixos-rebuild} boot ${toString cfg.flags}
- booted="$(readlink /run/booted-system/{initrd,kernel,kernel-modules})"
- built="$(readlink /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})"
- if [ "$booted" = "$built" ]; then
+ ${nixos-rebuild} boot ${toString (cfg.flags ++ upgradeFlag)}
+ booted="$(${readlink} /run/booted-system/{initrd,kernel,kernel-modules})"
+ built="$(${readlink} /nix/var/nix/profiles/system/{initrd,kernel,kernel-modules})"
+
+ ${optionalString (cfg.rebootWindow != null) ''
+ current_time="$(${date} +%H:%M)"
+
+ lower="${cfg.rebootWindow.lower}"
+ upper="${cfg.rebootWindow.upper}"
+
+ if [[ "''${lower}" < "''${upper}" ]]; then
+ if [[ "''${current_time}" > "''${lower}" ]] && \
+ [[ "''${current_time}" < "''${upper}" ]]; then
+ do_reboot="true"
+ else
+ do_reboot="false"
+ fi
+ else
+ # lower > upper, so we are crossing midnight (e.g. lower=23h, upper=6h)
+ # we want to reboot if cur > 23h or cur < 6h
+ if [[ "''${current_time}" < "''${upper}" ]] || \
+ [[ "''${current_time}" > "''${lower}" ]]; then
+ do_reboot="true"
+ else
+ do_reboot="false"
+ fi
+ fi
+ ''}
+
+ if [ "''${booted}" = "''${built}" ]; then
${nixos-rebuild} switch ${toString cfg.flags}
+ ${optionalString (cfg.rebootWindow != null) ''
+ elif [ "''${do_reboot}" != true ]; then
+ echo "Outside of configured reboot window, skipping."
+ ''}
else
- /run/current-system/sw/bin/shutdown -r +1
+ ${shutdown} -r +1
fi
'' else ''
- ${nixos-rebuild} switch ${toString cfg.flags}
+ ${nixos-rebuild} switch ${toString (cfg.flags ++ upgradeFlag)}
'';
startAt = cfg.dates;
@@ -167,3 +225,4 @@ in {
};
}
+
diff --git a/third_party/nixpkgs/nixos/modules/tasks/filesystems.nix b/third_party/nixpkgs/nixos/modules/tasks/filesystems.nix
index f3da677119..d68edd8d7d 100644
--- a/third_party/nixpkgs/nixos/modules/tasks/filesystems.nix
+++ b/third_party/nixpkgs/nixos/modules/tasks/filesystems.nix
@@ -215,6 +215,35 @@ in
'';
};
+ boot.devSize = mkOption {
+ default = "5%";
+ example = "32m";
+ type = types.str;
+ description = ''
+ Size limit for the /dev tmpfs. Look at mount(8), tmpfs size option,
+ for the accepted syntax.
+ '';
+ };
+
+ boot.devShmSize = mkOption {
+ default = "50%";
+ example = "256m";
+ type = types.str;
+ description = ''
+ Size limit for the /dev/shm tmpfs. Look at mount(8), tmpfs size option,
+ for the accepted syntax.
+ '';
+ };
+
+ boot.runSize = mkOption {
+ default = "25%";
+ example = "256m";
+ type = types.str;
+ description = ''
+ Size limit for the /run tmpfs. Look at mount(8), tmpfs size option,
+ for the accepted syntax.
+ '';
+ };
};
diff --git a/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix b/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix
index 19f2be2c4a..b0f160c1db 100644
--- a/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix
+++ b/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-scripted.nix
@@ -535,6 +535,7 @@ let
createGreDevice = n: v: nameValuePair "${n}-netdev"
(let
deps = deviceDependency v.dev;
+ ttlarg = if lib.hasPrefix "ip6" v.type then "hoplimit" else "ttl";
in
{ description = "GRE Tunnel Interface ${n}";
wantedBy = [ "network-setup.service" (subsystemDevice n) ];
@@ -551,6 +552,7 @@ let
ip link add name "${n}" type ${v.type} \
${optionalString (v.remote != null) "remote \"${v.remote}\""} \
${optionalString (v.local != null) "local \"${v.local}\""} \
+ ${optionalString (v.ttl != null) "${ttlarg} ${toString v.ttl}"} \
${optionalString (v.dev != null) "dev \"${v.dev}\""}
ip link set "${n}" up
'';
diff --git a/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix b/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix
index 8a5e1b5af1..8654539b66 100644
--- a/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix
+++ b/third_party/nixpkgs/nixos/modules/tasks/network-interfaces-systemd.nix
@@ -318,6 +318,8 @@ in
Remote = gre.remote;
}) // (optionalAttrs (gre.local != null) {
Local = gre.local;
+ }) // (optionalAttrs (gre.ttl != null) {
+ TTL = gre.ttl;
});
};
networks = mkIf (gre.dev != null) {
diff --git a/third_party/nixpkgs/nixos/modules/tasks/network-interfaces.nix b/third_party/nixpkgs/nixos/modules/tasks/network-interfaces.nix
index 06117ab451..8ca4ad7b7d 100644
--- a/third_party/nixpkgs/nixos/modules/tasks/network-interfaces.nix
+++ b/third_party/nixpkgs/nixos/modules/tasks/network-interfaces.nix
@@ -1020,6 +1020,14 @@ in
local = "10.0.0.22";
dev = "enp4s0f0";
type = "tap";
+ ttl = 255;
+ };
+ gre6Tunnel = {
+ remote = "fd7a:5634::1";
+ local = "fd7a:5634::2";
+ dev = "enp4s0f0";
+ type = "tun6";
+ ttl = 255;
};
}
'';
@@ -1057,11 +1065,25 @@ in
'';
};
+ ttl = mkOption {
+ type = types.nullOr types.int;
+ default = null;
+ example = 255;
+ description = ''
+ The time-to-live/hoplimit of the connection to the remote tunnel endpoint.
+ '';
+ };
+
type = mkOption {
- type = with types; enum [ "tun" "tap" ];
+ type = with types; enum [ "tun" "tap" "tun6" "tap6" ];
default = "tap";
example = "tap";
- apply = v: if v == "tun" then "gre" else "gretap";
+ apply = v: {
+ tun = "gre";
+ tap = "gretap";
+ tun6 = "ip6gre";
+ tap6 = "ip6gretap";
+ }.${v};
description = ''
Whether the tunnel routes layer 2 (tap) or layer 3 (tun) traffic.
'';
@@ -1429,7 +1451,7 @@ in
sysctl-value = tempaddrValues.${cfg.tempAddresses}.sysctl;
in ''
# enable and prefer IPv6 privacy addresses by default
- ACTION=="add", SUBSYSTEM=="net", RUN+="${pkgs.bash}/bin/sh -c 'echo ${sysctl-value} > /proc/sys/net/ipv6/conf/%k/use_tempaddr'"
+ ACTION=="add", SUBSYSTEM=="net", RUN+="${pkgs.bash}/bin/sh -c 'echo ${sysctl-value} > /proc/sys/net/ipv6/conf/$name/use_tempaddr'"
'';
})
(pkgs.writeTextFile rec {
diff --git a/third_party/nixpkgs/nixos/modules/virtualisation/oci-containers.nix b/third_party/nixpkgs/nixos/modules/virtualisation/oci-containers.nix
index 5af9baff8b..f404817278 100644
--- a/third_party/nixpkgs/nixos/modules/virtualisation/oci-containers.nix
+++ b/third_party/nixpkgs/nixos/modules/virtualisation/oci-containers.nix
@@ -22,11 +22,13 @@ let
type = with types; nullOr package;
default = null;
description = ''
- Path to an image file to load instead of pulling from a registry.
- If defined, do not pull from registry.
+ Path to an image file to load before running the image. This can
+ be used to bypass pulling the image from the registry.
- You still need to set the image attribute, as it
- will be used as the image name for docker to start a container.
+ The image attribute must match the name and
+ tag of the image contained in this file, as they will be used to
+ run the container with that image. If they do not match, the
+ image will be pulled from the registry as usual.
'';
example = literalExpression "pkgs.dockerTools.buildImage {...};";
};
diff --git a/third_party/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix b/third_party/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
index 5143893589..dacbb64a2d 100644
--- a/third_party/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
+++ b/third_party/nixpkgs/nixos/modules/virtualisation/qemu-vm.nix
@@ -796,7 +796,7 @@ in
# allow `system.build.toplevel' to be included. (If we had a direct
# reference to ${regInfo} here, then we would get a cyclic
# dependency.)
- boot.postBootCommands =
+ boot.postBootCommands = lib.mkIf config.nix.enable
''
if [[ "$(cat /proc/cmdline)" =~ regInfo=([^ ]*) ]]; then
${config.nix.package.out}/bin/nix-store --load-db < ''${BASH_REMATCH[1]}
diff --git a/third_party/nixpkgs/nixos/modules/virtualisation/waydroid.nix b/third_party/nixpkgs/nixos/modules/virtualisation/waydroid.nix
index 4fc798ff39..2c0b658948 100644
--- a/third_party/nixpkgs/nixos/modules/virtualisation/waydroid.nix
+++ b/third_party/nixpkgs/nixos/modules/virtualisation/waydroid.nix
@@ -56,8 +56,6 @@ in
wantedBy = [ "multi-user.target" ];
- path = with pkgs; [ getent iptables iproute kmod nftables util-linux which ];
-
unitConfig = {
ConditionPathExists = "/var/lib/waydroid/lxc/waydroid";
};
@@ -68,6 +66,10 @@ in
ExecStopPost = "${pkgs.waydroid}/bin/waydroid session stop";
};
};
+
+ systemd.tmpfiles.rules = [
+ "d /var/lib/misc 0755 root root -" # for dnsmasq.leases
+ ];
};
}
diff --git a/third_party/nixpkgs/nixos/tests/all-tests.nix b/third_party/nixpkgs/nixos/tests/all-tests.nix
index 953261e172..11a0166935 100644
--- a/third_party/nixpkgs/nixos/tests/all-tests.nix
+++ b/third_party/nixpkgs/nixos/tests/all-tests.nix
@@ -132,6 +132,7 @@ in
domination = handleTest ./domination.nix {};
dovecot = handleTest ./dovecot.nix {};
drbd = handleTest ./drbd.nix {};
+ earlyoom = handleTestOn ["x86_64-linux"] ./earlyoom.nix {};
ec2-config = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-config or {};
ec2-nixops = (handleTestOn ["x86_64-linux"] ./ec2.nix {}).boot-ec2-nixops or {};
ecryptfs = handleTest ./ecryptfs.nix {};
@@ -189,9 +190,9 @@ in
grocy = handleTest ./grocy.nix {};
grub = handleTest ./grub.nix {};
gvisor = handleTest ./gvisor.nix {};
- hadoop.all = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./hadoop/hadoop.nix {};
- hadoop.hdfs = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./hadoop/hdfs.nix {};
- hadoop.yarn = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./hadoop/yarn.nix {};
+ hadoop = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop; };
+ hadoop_3_2 = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop_3_2; };
+ hadoop2 = import ./hadoop { inherit handleTestOn; package=pkgs.hadoop2; };
haka = handleTest ./haka.nix {};
haproxy = handleTest ./haproxy.nix {};
hardened = handleTest ./hardened.nix {};
@@ -286,6 +287,7 @@ in
mailhog = handleTest ./mailhog.nix {};
man = handleTest ./man.nix {};
mariadb-galera = handleTest ./mysql/mariadb-galera.nix {};
+ mastodon = handleTestOn ["x86_64-linux" "i686-linux" "aarch64-linux"] ./web-apps/mastodon.nix {};
matomo = handleTest ./matomo.nix {};
matrix-appservice-irc = handleTest ./matrix-appservice-irc.nix {};
matrix-conduit = handleTest ./matrix-conduit.nix {};
@@ -307,6 +309,7 @@ in
molly-brown = handleTest ./molly-brown.nix {};
mongodb = handleTest ./mongodb.nix {};
moodle = handleTest ./moodle.nix {};
+ moonraker = handleTest ./moonraker.nix {};
morty = handleTest ./morty.nix {};
mosquitto = handleTest ./mosquitto.nix {};
moosefs = handleTest ./moosefs.nix {};
@@ -329,6 +332,7 @@ in
nat.standalone = handleTest ./nat.nix { withFirewall = false; };
nats = handleTest ./nats.nix {};
navidrome = handleTest ./navidrome.nix {};
+ nbd = handleTest ./nbd.nix {};
ncdns = handleTest ./ncdns.nix {};
ndppd = handleTest ./ndppd.nix {};
nebula = handleTest ./nebula.nix {};
@@ -354,6 +358,7 @@ in
nginx-sso = handleTest ./nginx-sso.nix {};
nginx-variants = handleTest ./nginx-variants.nix {};
nitter = handleTest ./nitter.nix {};
+ nix-ld = handleTest ./nix-ld {};
nix-serve = handleTest ./nix-serve.nix {};
nix-serve-ssh = handleTest ./nix-serve-ssh.nix {};
nixops = handleTest ./nixops/default.nix {};
@@ -383,14 +388,15 @@ in
os-prober = handleTestOn ["x86_64-linux"] ./os-prober.nix {};
osrm-backend = handleTest ./osrm-backend.nix {};
overlayfs = handleTest ./overlayfs.nix {};
+ pacemaker = handleTest ./pacemaker.nix {};
packagekit = handleTest ./packagekit.nix {};
pam-file-contents = handleTest ./pam/pam-file-contents.nix {};
pam-oath-login = handleTest ./pam/pam-oath-login.nix {};
pam-u2f = handleTest ./pam/pam-u2f.nix {};
- pam-ussh = handleTest ./pam/pam-ussh.nix {};
pantalaimon = handleTest ./matrix/pantalaimon.nix {};
pantheon = handleTest ./pantheon.nix {};
paperless-ng = handleTest ./paperless-ng.nix {};
+ paperless-ngx = handleTest ./paperless-ngx.nix {};
parsedmarc = handleTest ./parsedmarc {};
pdns-recursor = handleTest ./pdns-recursor.nix {};
peerflix = handleTest ./peerflix.nix {};
@@ -433,6 +439,7 @@ in
prometheus = handleTest ./prometheus.nix {};
prometheus-exporters = handleTest ./prometheus-exporters.nix {};
prosody = handleTest ./xmpp/prosody.nix {};
+ prosody-mysql = handleTest ./xmpp/prosody-mysql.nix {};
proxy = handleTest ./proxy.nix {};
prowlarr = handleTest ./prowlarr.nix {};
pt2-clone = handleTest ./pt2-clone.nix {};
@@ -466,6 +473,7 @@ in
seafile = handleTest ./seafile.nix {};
searx = handleTest ./searx.nix {};
service-runner = handleTest ./service-runner.nix {};
+ sfxr-qt = handleTest ./sfxr-qt.nix {};
shadow = handleTest ./shadow.nix {};
shadowsocks = handleTest ./shadowsocks {};
shattered-pixel-dungeon = handleTest ./shattered-pixel-dungeon.nix {};
@@ -483,7 +491,7 @@ in
sonarr = handleTest ./sonarr.nix {};
sourcehut = handleTest ./sourcehut.nix {};
spacecookie = handleTest ./spacecookie.nix {};
- spark = handleTestOn ["x86_64-linux"] ./spark {};
+ spark = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./spark {};
sslh = handleTest ./sslh.nix {};
sssd = handleTestOn ["x86_64-linux"] ./sssd.nix {};
sssd-ldap = handleTestOn ["x86_64-linux"] ./sssd-ldap.nix {};
@@ -503,6 +511,7 @@ in
systemd-boot = handleTest ./systemd-boot.nix {};
systemd-confinement = handleTest ./systemd-confinement.nix {};
systemd-cryptenroll = handleTest ./systemd-cryptenroll.nix {};
+ systemd-escaping = handleTest ./systemd-escaping.nix {};
systemd-journal = handleTest ./systemd-journal.nix {};
systemd-machinectl = handleTest ./systemd-machinectl.nix {};
systemd-networkd = handleTest ./systemd-networkd.nix {};
@@ -512,18 +521,20 @@ in
systemd-networkd-vrf = handleTest ./systemd-networkd-vrf.nix {};
systemd-nspawn = handleTest ./systemd-nspawn.nix {};
systemd-timesyncd = handleTest ./systemd-timesyncd.nix {};
- systemd-unit-path = handleTest ./systemd-unit-path.nix {};
+ systemd-misc = handleTest ./systemd-misc.nix {};
taskserver = handleTest ./taskserver.nix {};
teeworlds = handleTest ./teeworlds.nix {};
telegraf = handleTest ./telegraf.nix {};
teleport = handleTest ./teleport.nix {};
thelounge = handleTest ./thelounge.nix {};
+ terminal-emulators = handleTest ./terminal-emulators.nix {};
tiddlywiki = handleTest ./tiddlywiki.nix {};
tigervnc = handleTest ./tigervnc.nix {};
timezone = handleTest ./timezone.nix {};
tinc = handleTest ./tinc {};
tinydns = handleTest ./tinydns.nix {};
tinywl = handleTest ./tinywl.nix {};
+ tomcat = handleTest ./tomcat.nix {};
tor = handleTest ./tor.nix {};
# traefik test relies on docker-containers
traefik = handleTestOn ["x86_64-linux"] ./traefik.nix {};
diff --git a/third_party/nixpkgs/nixos/tests/avahi.nix b/third_party/nixpkgs/nixos/tests/avahi.nix
index ebb4683832..c53a959032 100644
--- a/third_party/nixpkgs/nixos/tests/avahi.nix
+++ b/third_party/nixpkgs/nixos/tests/avahi.nix
@@ -59,7 +59,7 @@ import ./make-test-python.nix {
two.succeed("test `wc -l < out` -gt 0")
# More DNS-SD.
- one.execute('avahi-publish -s "This is a test" _test._tcp 123 one=1 &')
+ one.execute('avahi-publish -s "This is a test" _test._tcp 123 one=1 >&2 &')
one.sleep(5)
two.succeed("avahi-browse -r -t _test._tcp | tee out >&2")
two.succeed("test `wc -l < out` -gt 0")
diff --git a/third_party/nixpkgs/nixos/tests/bcachefs.nix b/third_party/nixpkgs/nixos/tests/bcachefs.nix
index 211195586e..44997a7468 100644
--- a/third_party/nixpkgs/nixos/tests/bcachefs.nix
+++ b/third_party/nixpkgs/nixos/tests/bcachefs.nix
@@ -6,7 +6,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
virtualisation.emptyDiskImages = [ 4096 ];
networking.hostId = "deadbeef";
boot.supportedFilesystems = [ "bcachefs" ];
- environment.systemPackages = with pkgs; [ parted ];
+ environment.systemPackages = with pkgs; [ parted keyutils ];
};
testScript = ''
@@ -20,10 +20,9 @@ import ./make-test-python.nix ({ pkgs, ... }: {
"parted --script /dev/vdb mklabel msdos",
"parted --script /dev/vdb -- mkpart primary 1024M 50% mkpart primary 50% -1s",
"udevadm settle",
- # Due to #32279, we cannot use encryption for this test yet
- # "echo password | bcachefs format --encrypted --metadata_replicas 2 --label vtest /dev/vdb1 /dev/vdb2",
- # "echo password | bcachefs unlock /dev/vdb1",
- "bcachefs format --metadata_replicas 2 --label vtest /dev/vdb1 /dev/vdb2",
+ "keyctl link @u @s",
+ "echo password | bcachefs format --encrypted --metadata_replicas 2 --label vtest /dev/vdb1 /dev/vdb2",
+ "echo password | bcachefs unlock /dev/vdb1",
"mount -t bcachefs /dev/vdb1:/dev/vdb2 /tmp/mnt",
"udevadm settle",
"bcachefs fs usage /tmp/mnt",
diff --git a/third_party/nixpkgs/nixos/tests/boot.nix b/third_party/nixpkgs/nixos/tests/boot.nix
index cf55656671..ec2a9f6527 100644
--- a/third_party/nixpkgs/nixos/tests/boot.nix
+++ b/third_party/nixpkgs/nixos/tests/boot.nix
@@ -38,7 +38,6 @@ let
} // extraConfig);
in
makeTest {
- inherit iso;
name = "boot-" + name;
nodes = { };
testScript =
diff --git a/third_party/nixpkgs/nixos/tests/caddy.nix b/third_party/nixpkgs/nixos/tests/caddy.nix
index 0902904b20..16436ab528 100644
--- a/third_party/nixpkgs/nixos/tests/caddy.nix
+++ b/third_party/nixpkgs/nixos/tests/caddy.nix
@@ -7,7 +7,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
nodes = {
webserver = { pkgs, lib, ... }: {
services.caddy.enable = true;
- services.caddy.config = ''
+ services.caddy.extraConfig = ''
http://localhost {
encode gzip
@@ -22,7 +22,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
'';
specialisation.etag.configuration = {
- services.caddy.config = lib.mkForce ''
+ services.caddy.extraConfig = lib.mkForce ''
http://localhost {
encode gzip
@@ -38,7 +38,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
};
specialisation.config-reload.configuration = {
- services.caddy.config = ''
+ services.caddy.extraConfig = ''
http://localhost:8080 {
}
'';
diff --git a/third_party/nixpkgs/nixos/tests/ceph-multi-node.nix b/third_party/nixpkgs/nixos/tests/ceph-multi-node.nix
index 29e7c279d6..556546beee 100644
--- a/third_party/nixpkgs/nixos/tests/ceph-multi-node.nix
+++ b/third_party/nixpkgs/nixos/tests/ceph-multi-node.nix
@@ -48,7 +48,7 @@ let
sudo
ceph
xfsprogs
- netcat-openbsd
+ libressl.nc
];
boot.kernelModules = [ "xfs" ];
diff --git a/third_party/nixpkgs/nixos/tests/chromium.nix b/third_party/nixpkgs/nixos/tests/chromium.nix
index 8965646bc5..3815dca762 100644
--- a/third_party/nixpkgs/nixos/tests/chromium.nix
+++ b/third_party/nixpkgs/nixos/tests/chromium.nix
@@ -15,26 +15,9 @@
with import ../lib/testing-python.nix { inherit system pkgs; };
with pkgs.lib;
-mapAttrs (channel: chromiumPkg: makeTest rec {
- name = "chromium-${channel}";
- meta = {
- maintainers = with maintainers; [ aszlig primeos ];
- # https://github.com/NixOS/hydra/issues/591#issuecomment-435125621
- inherit (chromiumPkg.meta) timeout;
- };
-
- enableOCR = true;
-
+let
user = "alice";
- machine.imports = [ ./common/user-account.nix ./common/x11.nix ];
- machine.virtualisation.memorySize = 2047;
- machine.test-support.displayManager.auto.user = user;
- machine.environment = {
- systemPackages = [ chromiumPkg ];
- variables."XAUTHORITY" = "/home/alice/.Xauthority";
- };
-
startupHTML = pkgs.writeText "chromium-startup.html" ''
@@ -50,6 +33,25 @@ mapAttrs (channel: chromiumPkg: makeTest rec {