Project import generated by Copybara.

GitOrigin-RevId: 710fed5a2483f945b14f4a58af2cd3676b42d8c8
This commit is contained in:
Default email 2022-03-30 11:31:56 +02:00
parent 6f81c9d464
commit 8a45d4525b
2809 changed files with 66884 additions and 51650 deletions

View file

@ -10,9 +10,6 @@
# IMPORTANT NOTE: in order to actually get pinged, commit access is required. # 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 # 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. # 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 # This file
/.github/CODEOWNERS @edolstra /.github/CODEOWNERS @edolstra
@ -39,10 +36,10 @@
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer /pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer /pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
/pkgs/top-level/release-cross.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/stdenv/cross @Ericson2314 @matthewbauer
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej /pkgs/build-support/cc-wrapper @Ericson2314
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej /pkgs/build-support/bintools-wrapper @Ericson2314
/pkgs/build-support/setup-hooks @Ericson2314 /pkgs/build-support/setup-hooks @Ericson2314
/pkgs/build-support/setup-hooks/auto-patchelf.sh @aszlig /pkgs/build-support/setup-hooks/auto-patchelf.sh @aszlig
@ -77,6 +74,12 @@
# NixOS integration test driver # NixOS integration test driver
/nixos/lib/test-driver @tfc /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 # Updaters
## update.nix ## update.nix
/maintainers/scripts/update.nix @jtojnar /maintainers/scripts/update.nix @jtojnar
@ -91,8 +94,7 @@
/pkgs/development/python-modules @FRidh @jonringer /pkgs/development/python-modules @FRidh @jonringer
/doc/languages-frameworks/python.section.md @FRidh /doc/languages-frameworks/python.section.md @FRidh
/pkgs/development/tools/poetry2nix @adisbladis /pkgs/development/tools/poetry2nix @adisbladis
/pkgs/development/interpreters/python/hooks @FRidh @jonringer @DavHau /pkgs/development/interpreters/python/hooks @FRidh @jonringer
/pkgs/development/interpreters/python/conda @DavHau
# Haskell # Haskell
/doc/languages-frameworks/haskell.section.md @cdepillabout @sternenseemann @maralorn @expipiplus1 /doc/languages-frameworks/haskell.section.md @cdepillabout @sternenseemann @maralorn @expipiplus1
@ -109,8 +111,8 @@
/pkgs/development/perl-modules @stigtsp @zakame /pkgs/development/perl-modules @stigtsp @zakame
# R # R
/pkgs/applications/science/math/R @jbedo @bcdarwin /pkgs/applications/science/math/R @jbedo
/pkgs/development/r-modules @jbedo @bcdarwin /pkgs/development/r-modules @jbedo
# Ruby # Ruby
/pkgs/development/interpreters/ruby @marsam /pkgs/development/interpreters/ruby @marsam
@ -121,10 +123,6 @@
/pkgs/build-support/rust @zowoq /pkgs/build-support/rust @zowoq
/doc/languages-frameworks/rust.section.md @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 # C compilers
/pkgs/development/compilers/gcc @matthewbauer /pkgs/development/compilers/gcc @matthewbauer
/pkgs/development/compilers/llvm @matthewbauer /pkgs/development/compilers/llvm @matthewbauer
@ -133,15 +131,6 @@
/pkgs/top-level/unix-tools.nix @matthewbauer /pkgs/top-level/unix-tools.nix @matthewbauer
/pkgs/development/tools/xcbuild @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 # Audio
/nixos/modules/services/audio/botamusique.nix @mweinelt /nixos/modules/services/audio/botamusique.nix @mweinelt
/nixos/modules/services/audio/snapserver.nix @mweinelt /nixos/modules/services/audio/snapserver.nix @mweinelt
@ -209,7 +198,7 @@
/pkgs/development/idris-modules @Infinisil /pkgs/development/idris-modules @Infinisil
# Bazel # 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 for e-mail and dns services
/nixos/modules/services/mail/mailman.nix @peti /nixos/modules/services/mail/mailman.nix @peti
@ -237,22 +226,22 @@
/nixos/tests/prometheus-exporters.nix @WilliButz /nixos/tests/prometheus-exporters.nix @WilliButz
# PHP interpreter, packages, extensions, tests and documentation # PHP interpreter, packages, extensions, tests and documentation
/doc/languages-frameworks/php.section.md @NixOS/php @aanderse @etu @globin @ma27 @talyz /doc/languages-frameworks/php.section.md @aanderse @etu @globin @ma27 @talyz
/nixos/tests/php @NixOS/php @aanderse @etu @globin @ma27 @talyz /nixos/tests/php @aanderse @etu @globin @ma27 @talyz
/pkgs/build-support/build-pecl.nix @NixOS/php @aanderse @etu @globin @ma27 @talyz /pkgs/build-support/build-pecl.nix @aanderse @etu @globin @ma27 @talyz
/pkgs/development/interpreters/php @jtojnar @NixOS/php @aanderse @etu @globin @ma27 @talyz /pkgs/development/interpreters/php @jtojnar @aanderse @etu @globin @ma27 @talyz
/pkgs/development/php-packages @NixOS/php @aanderse @etu @globin @ma27 @talyz /pkgs/development/php-packages @aanderse @etu @globin @ma27 @talyz
/pkgs/top-level/php-packages.nix @jtojnar @NixOS/php @aanderse @etu @globin @ma27 @talyz /pkgs/top-level/php-packages.nix @jtojnar @aanderse @etu @globin @ma27 @talyz
# Podman, CRI-O modules and related # Podman, CRI-O modules and related
/nixos/modules/virtualisation/containers.nix @NixOS/podman @zowoq @adisbladis /nixos/modules/virtualisation/containers.nix @zowoq @adisbladis
/nixos/modules/virtualisation/cri-o.nix @NixOS/podman @zowoq @adisbladis /nixos/modules/virtualisation/cri-o.nix @zowoq @adisbladis
/nixos/modules/virtualisation/podman @NixOS/podman @zowoq @adisbladis /nixos/modules/virtualisation/podman @zowoq @adisbladis
/nixos/tests/cri-o.nix @NixOS/podman @zowoq @adisbladis /nixos/tests/cri-o.nix @zowoq @adisbladis
/nixos/tests/podman @NixOS/podman @zowoq @adisbladis /nixos/tests/podman @zowoq @adisbladis
# Docker tools # Docker tools
/pkgs/build-support/docker @roberth @utdemir /pkgs/build-support/docker @roberth
/nixos/tests/docker-tools-overlay.nix @roberth /nixos/tests/docker-tools-overlay.nix @roberth
/nixos/tests/docker-tools.nix @roberth /nixos/tests/docker-tools.nix @roberth
/doc/builders/images/dockertools.xml @roberth /doc/builders/images/dockertools.xml @roberth
@ -267,8 +256,8 @@
/pkgs/development/go-packages @kalbasit @Mic92 @zowoq /pkgs/development/go-packages @kalbasit @Mic92 @zowoq
# GNOME # GNOME
/pkgs/desktops/gnome @NixOS/GNOME @jtojnar @hedning /pkgs/desktops/gnome @jtojnar @hedning
/pkgs/desktops/gnome/extensions @piegamesde @NixOS/GNOME @jtojnar @hedning /pkgs/desktops/gnome/extensions @piegamesde @jtojnar @hedning
# Cinnamon # Cinnamon
/pkgs/desktops/cinnamon @mkg20001 /pkgs/desktops/cinnamon @mkg20001
@ -289,10 +278,10 @@
# Matrix # Matrix
/pkgs/servers/heisenbridge @piegamesde /pkgs/servers/heisenbridge @piegamesde
/pkgs/servers/matrix-conduit @piegamesde @pstn /pkgs/servers/matrix-conduit @piegamesde
/pkgs/servers/matrix-synapse/matrix-appservice-irc @piegamesde /pkgs/servers/matrix-synapse/matrix-appservice-irc @piegamesde
/nixos/modules/services/misc/heisenbridge.nix @piegamesde /nixos/modules/services/misc/heisenbridge.nix @piegamesde
/nixos/modules/services/misc/matrix-appservice-irc.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-appservice-irc.nix @piegamesde
/nixos/tests/matrix-conduit.nix @piegamesde @pstn /nixos/tests/matrix-conduit.nix @piegamesde

View file

@ -5,10 +5,6 @@
- pkgs/development/libraries/agda/**/* - pkgs/development/libraries/agda/**/*
- pkgs/top-level/agda-packages.nix - pkgs/top-level/agda-packages.nix
"6.topic: bsd":
- pkgs/os-specific/bsd/**/*
- pkgs/stdenv/freebsd/**/*
"6.topic: cinnamon": "6.topic: cinnamon":
- pkgs/desktops/cinnamon/**/* - pkgs/desktops/cinnamon/**/*

View file

@ -2,6 +2,12 @@ name: Backport
on: on:
pull_request_target: pull_request_target:
types: [closed, labeled] 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: jobs:
backport: backport:
name: Backport Pull Request name: Backport Pull Request

View file

@ -16,5 +16,10 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: cachix/install-nix-action@v16 - 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 # explicit list of supportedSystems is needed until aarch64-darwin becomes part of the trunk jobset
- run: nix-build pkgs/top-level/release.nix -A tarball.nixpkgs-basic-release-checks --arg supportedSystems '[ "aarch64-darwin" "aarch64-linux" "x86_64-linux" "x86_64-darwin" ]' - run: nix-build pkgs/top-level/release.nix -A tarball.nixpkgs-basic-release-checks --arg supportedSystems '[ "aarch64-darwin" "aarch64-linux" "x86_64-linux" "x86_64-darwin" ]'

View file

@ -22,7 +22,7 @@ jobs:
if: steps.ismerge.outputs.ismerge != 'true' if: steps.ismerge.outputs.ismerge != 'true'
- name: Warn if the commit was a direct push - name: Warn if the commit was a direct push
if: steps.ismerge.outputs.ismerge != 'true' if: steps.ismerge.outputs.ismerge != 'true'
uses: peter-evans/commit-comment@v1 uses: peter-evans/commit-comment@v2
with: with:
body: | body: |
@${{ github.actor }}, you pushed a commit directly to master/release branch @${{ github.actor }}, you pushed a commit directly to master/release branch

View file

@ -4,6 +4,11 @@ on:
pull_request_target: pull_request_target:
types: [edited, opened, synchronize, reopened] 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: permissions:
contents: read contents: read
pull-requests: write pull-requests: write

View file

@ -24,7 +24,7 @@ jobs:
extra_nix_config: sandbox = true extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v10 - uses: cachix/cachix-action@v10
with: 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 name: nixpkgs-ci
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- name: Building NixOS manual - name: Building NixOS manual

View file

@ -24,7 +24,7 @@ jobs:
extra_nix_config: sandbox = true extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v10 - uses: cachix/cachix-action@v10
with: 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 name: nixpkgs-ci
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}' signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- name: Building Nixpkgs manual - name: Building Nixpkgs manual

View file

@ -3,6 +3,11 @@ name: "set pending status"
on: on:
pull_request_target: 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: jobs:
action: action:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View file

@ -49,7 +49,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Comment on failure - name: Comment on failure
uses: peter-evans/create-or-update-comment@v1 uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }} if: ${{ failure() }}
with: with:
issue-number: 105153 issue-number: 105153

View file

@ -43,7 +43,7 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Comment on failure - name: Comment on failure
uses: peter-evans/create-or-update-comment@v1 uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }} if: ${{ failure() }}
with: with:
issue-number: 105153 issue-number: 105153

View file

@ -39,7 +39,7 @@ jobs:
title: ${{ steps.setup.outputs.title }} title: ${{ steps.setup.outputs.title }}
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
- name: comment on failure - name: comment on failure
uses: peter-evans/create-or-update-comment@v1 uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }} if: ${{ failure() }}
with: with:
issue-number: 153416 issue-number: 153416

View file

@ -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. 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` {#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. `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.

View file

@ -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. 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`.

View file

@ -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`: 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. - `stripLen`: Remove the first `stripLen` components of pathnames in the patch.
- `extraPrefix`: Prefix pathnames by this string. - `extraPrefix`: Prefix pathnames by this string.
- `excludes`: Exclude files matching this pattern. - `excludes`: Exclude files matching these patterns (applies after the above arguments).
- `includes`: Include only files matching this pattern. - `includes`: Include only files matching these patterns (applies after the above arguments).
- `revert`: Revert the patch. - `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. 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.

View file

@ -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. - [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 module tests, if any, are succeeding.
- Ensure that the introduced options are correct. - 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. - Description, default and example should be provided.
- Ensure that option changes are backward compatible. - 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 removed options are declared with `mkRemovedOptionModule`
- Ensure that changes that are not backward compatible are mentioned in release notes. - Ensure that changes that are not backward compatible are mentioned in release notes.
- Ensure that documentations affected by the change is updated. - 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 module tests, if any, are succeeding.
- Ensure that the introduced options are correct. - 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. - Description, default and example should be provided.
- Ensure that module `meta` field is present - Ensure that module `meta` field is present
- Maintainers should be declared in `meta.maintainers`. - Maintainers should be declared in `meta.maintainers`.

View file

@ -1474,7 +1474,7 @@ lib.attrsets.zipAttrsWith
<section xml:id="function-library-lib.attrsets.zipAttrs"> <section xml:id="function-library-lib.attrsets.zipAttrs">
<title><function>lib.attrsets.zipAttrs</function></title> <title><function>lib.attrsets.zipAttrs</function></title>
<subtitle><literal>zipAttrsWith :: [ AttrSet ] -> AttrSet</literal> <subtitle><literal>zipAttrs :: [ AttrSet ] -> AttrSet</literal>
</subtitle> </subtitle>
<xi:include href="./locations.xml" xpointer="lib.attrsets.zipAttrs" /> <xi:include href="./locations.xml" xpointer="lib.attrsets.zipAttrs" />

View file

@ -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 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 The `pkgs/development/node-packages` folder contains a generated collection of
[NPM packages](https://npmjs.com/) that can be installed with the Nix package [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: To add a package from NPM to nixpkgs:
1. Modify `pkgs/development/node-packages/node-packages.json` to add, update 1. Modify `pkgs/development/node-packages/node-packages.json` to add, update
or remove package entries to have it included in `nodePackages` and or remove package entries to have it included in `nodePackages` and
`nodePackages_latest`. `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: 3. Build your new package to test your changes:
`cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`. `cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`.
To build against the latest stable Current Node.js version (e.g. 14.x): 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` [README.md](https://github.com/svanderburg/node2nix) file of the `node2nix`
tool. 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} ## Tool specific instructions {#javascript-tool-specific}
### node2nix {#javascript-node2nix} ### node2nix {#javascript-node2nix}

View file

@ -38,8 +38,12 @@ Here is a simple package example.
- It uses the `fetchFromGitHub` fetcher to get its source. - It uses the `fetchFromGitHub` fetcher to get its source.
- `useDune2 = true` ensures that the latest version of Dune is used for the - `duneVersion = "2"` ensures that Dune version 2 is used for the
build (this may become the default value in a future release). 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 - 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 `dune runtest -p angstrom` after the build (`dune build -p angstrom`) is
@ -67,7 +71,7 @@ Here is a simple package example.
buildDunePackage rec { buildDunePackage rec {
pname = "angstrom"; pname = "angstrom";
version = "0.15.0"; version = "0.15.0";
useDune2 = true; duneVersion = "2";
minimalOCamlVersion = "4.04"; minimalOCamlVersion = "4.04";

View file

@ -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. - 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 ```nix
texlive.combine { texlive.combine {

View file

@ -18,7 +18,7 @@ Adding custom .vimrc lines can be done using the following code:
```nix ```nix
vim_configurable.customize { 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"; name = "vim-with-plugins";
vimrcConfig.customRC = '' 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`. 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: For Neovim the `configure` argument can be overridden to achieve the same:
@ -286,7 +289,7 @@ Sample output1:
"reload" = buildVimPluginFrom2Nix { # created by nix#NixDerivation "reload" = buildVimPluginFrom2Nix { # created by nix#NixDerivation
name = "reload"; name = "reload";
src = fetchgit { src = fetchgit {
url = "git://github.com/xolox/vim-reload"; url = "https://github.com/xolox/vim-reload";
rev = "0a601a668727f5b675cb1ddc19f6861f3f7ab9e1"; rev = "0a601a668727f5b675cb1ddc19f6861f3f7ab9e1";
sha256 = "0vb832l9yxj919f5hfg6qj6bn9ni57gnjd3bj7zpq7d4iv2s4wdh"; sha256 = "0vb832l9yxj919f5hfg6qj6bn9ni57gnjd3bj7zpq7d4iv2s4wdh";
}; };

View file

@ -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. 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`. 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. 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 ```nix
{ stdenv, blas, lapack, ... }: { stdenv, blas, lapack, ... }:

View file

@ -4,8 +4,8 @@
let let
inherit (builtins) head tail length; inherit (builtins) head tail length;
inherit (lib.trivial) id; inherit (lib.trivial) id;
inherit (lib.strings) concatStringsSep sanitizeDerivationName; inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName;
inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all; inherit (lib.lists) foldr foldl' concatMap concatLists elemAt all partition groupBy take foldl;
in in
rec { rec {
@ -78,6 +78,103 @@ rec {
in attrByPath attrPath (abort errorMsg); 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. /* Return the specified attributes from a set.
Example: Example:
@ -477,6 +574,20 @@ rec {
overrideExisting = old: new: overrideExisting = old: new:
mapAttrs (name: value: new.${name} or value) old; 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 []
=> "<root attribute path>"
*/
showAttrPath = path:
if path == [] then "<root attribute path>"
else concatMapStringsSep "." escapeNixIdentifier path;
/* Get a package output. /* Get a package output.
If no output is found, fallback to `.out` and then to the default. If no output is found, fallback to `.out` and then to the default.

View file

@ -66,9 +66,10 @@ let
stringLength sub substring tail trace; stringLength sub substring tail trace;
inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor
bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max
importJSON importTOML warn warnIf throwIfNot checkListOfEnum importJSON importTOML warn warnIf warnIfNot throwIf throwIfNot checkListOfEnum
info showWarnings nixpkgsVersion version info showWarnings nixpkgsVersion version isInOldestRelease
mod compare splitByAndCompare functionArgs setFunctionArgs isFunction mod compare splitByAndCompare
functionArgs setFunctionArgs isFunction toFunction
toHexString toBaseDigits; toHexString toBaseDigits;
inherit (self.fixedPoints) fix fix' converge extends composeExtensions inherit (self.fixedPoints) fix fix' converge extends composeExtensions
composeManyExtensions makeExtensible makeExtensibleWithCustomName; composeManyExtensions makeExtensible makeExtensibleWithCustomName;
@ -78,9 +79,10 @@ let
mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond
genAttrs isDerivation toDerivation optionalAttrs genAttrs isDerivation toDerivation optionalAttrs
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
recursiveUpdate matchAttrs overrideExisting getOutput getBin recursiveUpdate matchAttrs overrideExisting showAttrPath getOutput getBin
getLib getDev getMan chooseDevOutputs zipWithNames zip getLib getDev getMan chooseDevOutputs zipWithNames zip
recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets; recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets
updateManyAttrsByPath;
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
concatMap flatten remove findSingle findFirst any all count concatMap flatten remove findSingle findFirst any all count
optional optionals toList range partition zipListsWith zipLists optional optionals toList range partition zipListsWith zipLists
@ -112,14 +114,15 @@ let
commitIdFromGitRepo cleanSourceWith pathHasContext commitIdFromGitRepo cleanSourceWith pathHasContext
canCleanSource pathIsRegularFile pathIsGitRepo; canCleanSource pathIsRegularFile pathIsGitRepo;
inherit (self.modules) evalModules setDefaultModuleLocation inherit (self.modules) evalModules setDefaultModuleLocation
unifyModuleSyntax applyIfFunction mergeModules unifyModuleSyntax applyModuleArgsIfFunction mergeModules
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
pushDownProperties dischargeProperties filterOverrides pushDownProperties dischargeProperties filterOverrides
sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride
mkOptionDefault mkDefault mkImageMediaOverride mkForce mkVMOverride mkOptionDefault mkDefault mkImageMediaOverride mkForce mkVMOverride
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule mkRenamedOptionModule mkRenamedOptionModuleWith
mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule mkDerivedConfig doRename; mkAliasOptionModule mkDerivedConfig doRename;
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption

View file

@ -389,6 +389,11 @@ in mkLicense lset) ({
free = false; free = false;
}; };
generaluser = {
fullName = "GeneralUser GS License v2.0";
url = "http://www.schristiancollins.com/generaluser.php"; # license included in sources
};
gpl1Only = { gpl1Only = {
spdxId = "GPL-1.0-only"; spdxId = "GPL-1.0-only";
fullName = "GNU General Public License v1.0 only"; fullName = "GNU General Public License v1.0 only";
@ -607,6 +612,11 @@ in mkLicense lset) ({
fullName = "Enlightenment License (e16)"; fullName = "Enlightenment License (e16)";
}; };
mit0 = {
spdxId = "MIT-0";
fullName = "MIT No Attribution";
};
mpl10 = { mpl10 = {
spdxId = "MPL-1.0"; spdxId = "MPL-1.0";
fullName = "Mozilla Public License 1.0"; fullName = "Mozilla Public License 1.0";

View file

@ -4,6 +4,7 @@
let let
inherit (lib.strings) toInt; inherit (lib.strings) toInt;
inherit (lib.trivial) compare min; inherit (lib.trivial) compare min;
inherit (lib.attrsets) mapAttrs;
in in
rec { rec {
@ -340,15 +341,15 @@ rec {
groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ] groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = 12; false = 3; } => { true = 12; false = 3; }
*/ */
groupBy' = op: nul: pred: lst: groupBy' = op: nul: pred: lst: mapAttrs (name: foldl op nul) (groupBy pred lst);
foldl' (r: e:
groupBy = builtins.groupBy or (
pred: foldl' (r: e:
let let
key = pred e; key = pred e;
in in
r // { ${key} = op (r.${key} or nul) e; } r // { ${key} = (r.${key} or []) ++ [e]; }
) {} lst; ) {});
groupBy = groupBy' (sum: e: sum ++ [e]) [];
/* Merges two lists of the same size together. If the sizes aren't the same /* 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 the merging stops at the shortest. How both lists are merged is defined

View file

@ -9,7 +9,7 @@ let
catAttrs catAttrs
concatLists concatLists
concatMap concatMap
count concatStringsSep
elem elem
filter filter
findFirst findFirst
@ -47,6 +47,20 @@ let
showOption showOption
unknownModule 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 in
rec { rec {
@ -268,11 +282,11 @@ rec {
# Like unifyModuleSyntax, but also imports paths and calls functions if necessary # Like unifyModuleSyntax, but also imports paths and calls functions if necessary
loadModule = args: fallbackFile: fallbackKey: m: loadModule = args: fallbackFile: fallbackKey: m:
if isFunction m || isAttrs m then 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 else if isList m then
let defs = [{ file = fallbackFile; value = m; }]; in 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}" 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 Collects all modules recursively into the form
@ -369,7 +383,7 @@ rec {
config = addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"])); 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 let
# Module arguments are resolved in a strict manner when attribute set # Module arguments are resolved in a strict manner when attribute set
# deconstruction is used. As the arguments are now defined with the # deconstruction is used. As the arguments are now defined with the
@ -474,26 +488,61 @@ rec {
[{ inherit (module) file; inherit value; }] [{ inherit (module) file; inherit value; }]
) configs; ) 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: resultsByName = mapAttrs (name: decls:
# We're descending into attribute name. # We're descending into attribute name.
let let
loc = prefix ++ [name]; loc = prefix ++ [name];
defns = defnsByName.${name} or []; defns = defnsByName.${name} or [];
defns' = defnsByName'.${name} or []; defns' = defnsByName'.${name} or [];
nrOptions = count (m: isOption m.options) decls; optionDecls = filter (m: isOption m.options) decls;
in in
if nrOptions == length decls then if length optionDecls == length decls then
let opt = fixupOptionType loc (mergeOptionDecls loc decls); let opt = fixupOptionType loc (mergeOptionDecls loc decls);
in { in {
matchedOptions = evalOptionValue loc opt defns'; matchedOptions = evalOptionValue loc opt defns';
unmatchedDefns = []; unmatchedDefns = [];
} }
else if nrOptions != 0 then 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 "<name>" 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 let
firstOption = findFirst (m: isOption m.options) "" decls;
firstNonOption = findFirst (m: !isOption m.options) "" decls; firstNonOption = findFirst (m: !isOption m.options) "" decls;
nonOptions = filter (m: !isOption m.options) decls;
in in
throw "The option `${showOption loc}' in `${firstOption._file}' is a prefix of options in `${firstNonOption._file}'." 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 "<no description>"}' does not support nested options.\n${
showRawDecls loc nonOptions
}"
else else
mergeModules' loc decls defns) declsByName; 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}." throw "The option `${showOption loc}' in `${opt._file}' is already declared in ${showFiles res.declarations}."
else else
let 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; getSubModules = opt.options.type.getSubModules or null;
submodules = submodules =
if getSubModules != null then map (setDefaultModuleLocation opt._file) getSubModules ++ res.options 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; else res.options;
in opt.options // res // in opt.options // res //
{ declarations = res.declarations ++ [opt._file]; { declarations = res.declarations ++ [opt._file];
@ -753,25 +794,12 @@ rec {
compare = a: b: (a.priority or 1000) < (b.priority or 1000); compare = a: b: (a.priority or 1000) < (b.priority or 1000);
in sort compare defs'; in sort compare defs';
/* Hack for backward compatibility: convert options of type # This calls substSubModules, whose entire purpose is only to ensure that
optionSet to options of type submodule. FIXME: remove # option declarations in submodules have accurate position information.
eventually. */ # TODO: Merge this into mergeOptionDecls
fixupOptionType = loc: opt: 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 if opt.type.getSubModules or null == null
then opt // { type = f (opt.type or types.unspecified); } then opt // { type = opt.type or types.unspecified; }
else opt // { type = opt.type.substSubModules opt.options; options = []; }; else opt // { type = opt.type.substSubModules opt.options; options = []; };
@ -904,6 +932,26 @@ rec {
use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'."; 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" /* 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 option is defined; the defined values can be used in the "mergeFn" to set
the "to" value. the "to" value.

View file

@ -79,8 +79,6 @@ rec {
visible ? null, visible ? null,
# Whether the option can be set only once # Whether the option can be set only once
readOnly ? null, readOnly ? null,
# Deprecated, used by types.optionSet.
options ? null
} @ attrs: } @ attrs:
attrs // { _type = "option"; }; attrs // { _type = "option"; };
@ -231,7 +229,7 @@ rec {
then true then true
else opt.visible or true; else opt.visible or true;
readOnly = opt.readOnly or false; 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 ? example) { example = scrubOptionValue opt.example; }
// optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; } // optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; }

View file

@ -105,7 +105,8 @@ rec {
else if final.isAarch64 then "arm64" else if final.isAarch64 then "arm64"
else if final.isx86_32 then "i386" else if final.isx86_32 then "i386"
else if final.isx86_64 then "x86_64" 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.isPower then "powerpc"
else if final.isRiscV then "riscv" else if final.isRiscV then "riscv"
else if final.isS390 then "s390" else if final.isS390 then "s390"

View file

@ -26,7 +26,7 @@ let
# Linux # Linux
"aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-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" "powerpc64-linux" "powerpc64le-linux" "riscv32-linux"
"riscv64-linux" "s390-linux" "s390x-linux" "x86_64-linux" "riscv64-linux" "s390-linux" "s390x-linux" "x86_64-linux"
@ -87,7 +87,11 @@ in {
darwin = filterDoubles predicates.isDarwin; darwin = filterDoubles predicates.isDarwin;
freebsd = filterDoubles predicates.isFreeBSD; freebsd = filterDoubles predicates.isFreeBSD;
# Should be better, but MinGW is unclear. # 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; illumos = filterDoubles predicates.isSunOS;
linux = filterDoubles predicates.isLinux; linux = filterDoubles predicates.isLinux;
netbsd = filterDoubles predicates.isNetBSD; netbsd = filterDoubles predicates.isNetBSD;

View file

@ -93,6 +93,26 @@ rec {
config = "mipsel-unknown-linux-gnu"; config = "mipsel-unknown-linux-gnu";
} // platforms.fuloong2f_n32; } // 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 // { muslpi = raspberryPi // {
config = "armv6l-unknown-linux-musleabihf"; config = "armv6l-unknown-linux-musleabihf";
}; };

View file

@ -17,6 +17,10 @@ rec {
isAarch32 = { cpu = { family = "arm"; bits = 32; }; }; isAarch32 = { cpu = { family = "arm"; bits = 32; }; };
isAarch64 = { cpu = { family = "arm"; bits = 64; }; }; isAarch64 = { cpu = { family = "arm"; bits = 64; }; };
isMips = { cpu = { family = "mips"; }; }; 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"; }; }; isMmix = { cpu = { family = "mmix"; }; };
isRiscV = { cpu = { family = "riscv"; }; }; isRiscV = { cpu = { family = "riscv"; }; };
isSparc = { cpu = { family = "sparc"; }; }; isSparc = { cpu = { family = "sparc"; }; };
@ -57,7 +61,7 @@ rec {
isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ]; isAndroid = [ { abi = abis.android; } { abi = abis.androideabi; } ];
isGnu = with abis; map (a: { abi = a; }) [ gnuabi64 gnu gnueabi gnueabihf ]; 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 ]; isUClibc = with abis; map (a: { abi = a; }) [ uclibc uclibceabi uclibceabihf ];
isEfi = map (family: { cpu.family = family; }) isEfi = map (family: { cpu.family = family; })

View file

@ -359,6 +359,13 @@ rec {
]; ];
}; };
gnuabi64 = { abi = "64"; }; 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"; }; musleabi = { float = "soft"; };
musleabihf = { float = "hard"; }; musleabihf = { float = "hard"; };

View file

@ -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 }: { lib }:
rec { rec {
pc = { 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 ## 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: select = platform:
# x86 # x86
/**/ if platform.isx86 then pc /**/ if platform.isx86 then pc

View file

@ -761,4 +761,156 @@ runTests {
{ a = 3; b = 30; c = 300; } { 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 = "<root attribute path>";
};
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;
};
};
} }

View file

@ -62,6 +62,13 @@ checkConfigError() {
checkConfigOutput '^false$' config.enable ./declare-enable.nix checkConfigOutput '^false$' config.enable ./declare-enable.nix
checkConfigError 'The option .* does not exist. Definition values:\n\s*- In .*: true' config.enable ./define-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. # Check integer types.
# unsigned # unsigned
checkConfigOutput '^42$' config.value ./declare-int-unsigned-value.nix ./define-value-int-positive.nix 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 checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix
checkConfigOutput "bar" config.priorities ./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 # Test that types.optionType merges types correctly
checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix checkConfigOutput '^10$' config.theOption.int ./optionTypeMerging.nix
checkConfigOutput '^"hello"$' config.theOption.str ./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 # 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 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 <<EOF cat <<EOF
====== module tests ====== ====== module tests ======
$pass Pass $pass Pass

View file

@ -0,0 +1,14 @@
{ lib, ... }: {
options.dummy = lib.mkOption { type = lib.types.anything; default = {}; };
freeformType =
let
a = lib.types.attrsOf (lib.types.submodule { options.bar = lib.mkOption { }; });
in
# modifying types like this breaks type merging.
# This test makes sure that type merging is not performed when only a single declaration exists.
# Don't modify types in practice!
a // {
merge = loc: defs: { freeformItems = a.merge loc defs; };
};
config.foo.bar = "ok";
}

View file

@ -0,0 +1,10 @@
{ lib, ... }:
let
inherit (lib) mkOption types;
in
{
options.bare-submodule.deep = mkOption {
type = types.int;
default = 2;
};
}

View file

@ -0,0 +1,10 @@
{ lib, ... }:
let
inherit (lib) mkOption types;
in
{
options.bare-submodule.deep = mkOption {
type = types.int;
default = 2;
};
}

View file

@ -0,0 +1,19 @@
{ config, lib, ... }:
let
inherit (lib) mkOption types;
in
{
options.bare-submodule = mkOption {
type = types.submoduleWith {
shorthandOnlyDefinesConfig = config.shorthandOnlyDefinesConfig;
modules = [
{
options.nested = mkOption {
type = types.int;
default = 1;
};
}
];
};
};
}

View file

@ -0,0 +1,18 @@
{ config, lib, ... }:
let
inherit (lib) mkOption types;
in
{
options.bare-submodule = mkOption {
type = types.submoduleWith {
modules = [ ];
shorthandOnlyDefinesConfig = config.shorthandOnlyDefinesConfig;
};
default = {};
};
# config-dependent options: won't recommend, but useful for making this test parameterized
options.shorthandOnlyDefinesConfig = mkOption {
default = false;
};
}

View file

@ -0,0 +1,12 @@
{ lib, ... }:
{
options.set = lib.mkOption {
default = { };
example = { a = 1; };
type = lib.types.attrsOf lib.types.int;
description = ''
Some descriptive text
'';
};
}

View file

@ -0,0 +1,4 @@
{
bare-submodule.nested = 42;
bare-submodule.deep = 420;
}

View file

@ -0,0 +1 @@
{ shorthandOnlyDefinesConfig = true; }

View file

@ -17,7 +17,7 @@ with lib.systems.doubles; lib.runTests {
testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ]; testarm = mseteq arm [ "armv5tel-linux" "armv6l-linux" "armv6l-netbsd" "armv6l-none" "armv7a-linux" "armv7a-netbsd" "armv7l-linux" "armv7l-netbsd" "arm-none" "armv7a-darwin" ];
testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ]; testi686 = mseteq i686 [ "i686-linux" "i686-freebsd" "i686-genode" "i686-netbsd" "i686-openbsd" "i686-cygwin" "i686-windows" "i686-none" "i686-darwin" ];
testmips = mseteq mips [ "mipsel-linux" "mipsel-netbsd" ]; testmips = mseteq mips [ "mips64el-linux" "mipsel-linux" "mipsel-netbsd" ];
testmmix = mseteq mmix [ "mmix-mmixware" ]; testmmix = mseteq mmix [ "mmix-mmixware" ];
testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ]; testx86_64 = mseteq x86_64 [ "x86_64-linux" "x86_64-darwin" "x86_64-freebsd" "x86_64-genode" "x86_64-redox" "x86_64-openbsd" "x86_64-netbsd" "x86_64-cygwin" "x86_64-solaris" "x86_64-windows" "x86_64-none" ];
@ -28,7 +28,7 @@ with lib.systems.doubles; lib.runTests {
testredox = mseteq redox [ "x86_64-redox" ]; testredox = mseteq redox [ "x86_64-redox" ];
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */); testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
testillumos = mseteq illumos [ "x86_64-solaris" ]; testillumos = mseteq illumos [ "x86_64-solaris" ];
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" "s390x-linux" ]; testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mips64el-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" "s390x-linux" ];
testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ]; testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "m68k-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ]; testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ]; testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];

View file

@ -166,6 +166,30 @@ rec {
/* Returns the current nixpkgs release number as string. */ /* Returns the current nixpkgs release number as string. */
release = lib.strings.fileContents ../.version; release = lib.strings.fileContents ../.version;
/* The latest release that is supported, at the time of release branch-off,
if applicable.
Ideally, out-of-tree modules should be able to evaluate cleanly with all
supported Nixpkgs versions (master, release and old release until EOL).
So if possible, deprecation warnings should take effect only when all
out-of-tree expressions/libs/modules can upgrade to the new way without
losing support for supported Nixpkgs versions.
This release number allows deprecation warnings to be implemented such that
they take effect as soon as the oldest release reaches end of life. */
oldestSupportedRelease =
# Update on master only. Do not backport.
2111;
/* Whether a feature is supported in all supported releases (at the time of
release branch-off, if applicable). See `oldestSupportedRelease`. */
isInOldestRelease =
/* Release number of feature introduction as an integer, e.g. 2111 for 21.11.
Set it to the upcoming release, matching the nixpkgs/.version file.
*/
release:
release <= lib.trivial.oldestSupportedRelease;
/* Returns the current nixpkgs release code name. /* Returns the current nixpkgs release code name.
On each release the first letter is bumped and a new animal is chosen On each release the first letter is bumped and a new animal is chosen
@ -323,7 +347,14 @@ rec {
Type: bool -> string -> a -> a Type: bool -> 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 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; 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. /* Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.
Example: Example:
@ -403,6 +441,25 @@ rec {
isFunction = f: builtins.isFunction f || isFunction = f: builtins.isFunction f ||
(f ? __functor && isFunction (f.__functor 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 /* Convert the given positive integer to a string of its hexadecimal
representation. For example: representation. For example:

View file

@ -368,13 +368,21 @@ rec {
emptyValue = { value = {}; }; 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 { package = mkOptionType {
name = "package"; name = "package";
check = x: isDerivation x || isStorePath x; check = x: isDerivation x || isStorePath x;
merge = loc: defs: merge = loc: defs:
let res = mergeOneOption 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 // { shellPackage = package // {
@ -535,7 +543,9 @@ rec {
description = "optionType"; description = "optionType";
check = value: value._type or null == "option-type"; check = value: value._type or null == "option-type";
merge = loc: defs: merge = loc: defs:
let if length defs == 1
then (head defs).value
else let
# Prepares the type definitions for mergeOptionDecls, which # Prepares the type definitions for mergeOptionDecls, which
# annotates submodules types with file locations # annotates submodules types with file locations
optionModules = map ({ value, file }: optionModules = map ({ value, file }:
@ -562,14 +572,18 @@ rec {
let let
inherit (lib.modules) evalModules; inherit (lib.modules) evalModules;
coerce = unify: value: if isFunction value shorthandToModule = if shorthandOnlyDefinesConfig == false
then setFunctionArgs (args: unify (value args)) (functionArgs value) then value: value
else unify (if shorthandOnlyDefinesConfig then { config = value; } else value); else value: { config = value; };
allModules = defs: imap1 (n: { value, file }: allModules = defs: imap1 (n: { value, file }:
if isAttrs value || isFunction value then if isFunction value
# Annotate the value with the location of its definition for better error messages then setFunctionArgs
coerce (lib.modules.unifyModuleSyntax file "${toString file}-${toString n}") value (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 else value
) defs; ) defs;
@ -637,7 +651,11 @@ rec {
then lhs.specialArgs // rhs.specialArgs then lhs.specialArgs // rhs.specialArgs
else throw "A submoduleWith option is declared multiple times with the same specialArgs \"${toString (attrNames intersecting)}\""; else throw "A submoduleWith option is declared multiple times with the same specialArgs \"${toString (attrNames intersecting)}\"";
shorthandOnlyDefinesConfig = 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 then lhs.shorthandOnlyDefinesConfig
else throw "A submoduleWith option is declared multiple times with conflicting shorthandOnlyDefinesConfig values"; else throw "A submoduleWith option is declared multiple times with conflicting shorthandOnlyDefinesConfig values";
}; };
@ -731,14 +749,6 @@ rec {
nestedTypes.finalType = finalType; 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. # Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; }; addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };

View file

@ -929,6 +929,12 @@
githubId = 1296771; githubId = 1296771;
name = "Anders Riutta"; name = "Anders Riutta";
}; };
arjan-s = {
email = "github@anymore.nl";
github = "arjan-s";
githubId = 10400299;
name = "Arjan Schrijver";
};
arkivm = { arkivm = {
email = "vikram186@gmail.com"; email = "vikram186@gmail.com";
github = "arkivm"; github = "arkivm";
@ -1295,6 +1301,12 @@
githubId = 127523; githubId = 127523;
name = "Herman Fries"; name = "Herman Fries";
}; };
BarinovMaxim = {
name = "Barinov Maxim";
email = "barinov274@gmail.com";
github = "barinov274";
githubId = 54442153;
};
barrucadu = { barrucadu = {
email = "mike@barrucadu.co.uk"; email = "mike@barrucadu.co.uk";
github = "barrucadu"; github = "barrucadu";
@ -1688,6 +1700,12 @@
githubId = 355401; githubId = 355401;
name = "Brian Hicks"; name = "Brian Hicks";
}; };
brianmcgee = {
name = "Brian McGee";
email = "brian@41north.dev";
github = "brianmcgee";
githubId = 1173648;
};
Br1ght0ne = { Br1ght0ne = {
email = "brightone@protonmail.com"; email = "brightone@protonmail.com";
github = "Br1ght0ne"; github = "Br1ght0ne";
@ -1895,6 +1913,12 @@
githubId = 82591; githubId = 82591;
name = "Carl Sverre"; name = "Carl Sverre";
}; };
carpinchomug = {
email = "aki.suda@protonmail.com";
github = "carpinchomug";
githubId = 101536256;
name = "Akiyoshi Suda";
};
cartr = { cartr = {
email = "carter.sande@duodecima.technology"; email = "carter.sande@duodecima.technology";
github = "cartr"; github = "cartr";
@ -2181,6 +2205,12 @@
githubId = 42220376; githubId = 42220376;
name = "Charlotte Van Petegem"; name = "Charlotte Van Petegem";
}; };
cigrainger = {
name = "Christopher Grainger";
email = "chris@amplified.ai";
github = "cigrainger";
githubId = 3984794;
};
ciil = { ciil = {
email = "simon@lackerbauer.com"; email = "simon@lackerbauer.com";
github = "ciil"; github = "ciil";
@ -2800,6 +2830,12 @@
githubId = 49904992; githubId = 49904992;
name = "Dawid Sowa"; name = "Dawid Sowa";
}; };
dbeckwith = {
email = "djbsnx@gmail.com";
github = "dbeckwith";
githubId = 1279939;
name = "Daniel Beckwith";
};
dbirks = { dbirks = {
email = "david@birks.dev"; email = "david@birks.dev";
github = "dbirks"; github = "dbirks";
@ -4217,7 +4253,12 @@
githubId = 119691; githubId = 119691;
name = "Michael Gough"; name = "Michael Gough";
}; };
freax13 = {
email = "erbse.13@gmx.de";
github = "freax13";
githubId = 14952658;
name = "Tom Dohrmann";
};
fredeb = { fredeb = {
email = "im@fredeb.dev"; email = "im@fredeb.dev";
github = "fredeeb"; github = "fredeeb";
@ -5625,6 +5666,12 @@
github = "jduan"; github = "jduan";
githubId = 452450; githubId = 452450;
}; };
jdupak = {
name = "Jakub Dupak";
email = "dev@jakubdupak.com";
github = "jdupak";
githubId = 22683640;
};
jecaro = { jecaro = {
email = "jeancharles.quillet@gmail.com"; email = "jeancharles.quillet@gmail.com";
github = "jecaro"; github = "jecaro";
@ -5845,6 +5892,12 @@
githubId = 587870; githubId = 587870;
name = "Jonathan Mettes"; name = "Jonathan Mettes";
}; };
jmgilman = {
email = "joshuagilman@gmail.com";
github = "jmgilman";
githubId = 2308444;
name = "Joshua Gilman";
};
jo1gi = { jo1gi = {
email = "joakimholm@protonmail.com"; email = "joakimholm@protonmail.com";
github = "jo1gi"; github = "jo1gi";
@ -7217,6 +7270,29 @@
githubId = 1267527; githubId = 1267527;
name = "Daniel Firth"; 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 = { lopsided98 = {
email = "benwolsieffer@gmail.com"; email = "benwolsieffer@gmail.com";
github = "lopsided98"; github = "lopsided98";
@ -8686,6 +8762,12 @@
fingerprint = "4BFF 0614 03A2 47F0 AA0B 4BC4 916D 8B67 2418 92AE"; 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 = { nbren12 = {
email = "nbren12@gmail.com"; email = "nbren12@gmail.com";
github = "nbren12"; github = "nbren12";
@ -9260,6 +9342,12 @@
githubId = 23431373; githubId = 23431373;
name = "Christoph Neidahl"; name = "Christoph Neidahl";
}; };
opeik = {
email = "sandro@stikic.com";
github = "opeik";
githubId = 11566773;
name = "Sandro Stikić";
};
orbekk = { orbekk = {
email = "kjetil.orbekk@gmail.com"; email = "kjetil.orbekk@gmail.com";
github = "orbekk"; github = "orbekk";
@ -9862,6 +9950,12 @@
fingerprint = "48AD DE10 F27B AFB4 7BB0 CCAF 2D25 95A0 0D08 ACE0"; fingerprint = "48AD DE10 F27B AFB4 7BB0 CCAF 2D25 95A0 0D08 ACE0";
}]; }];
}; };
ppenguin = {
name = "Jeroen Versteeg";
email = "hieronymusv@gmail.com";
github = "ppenguin";
githubId = 17690377;
};
ppom = { ppom = {
name = "Paco Pompeani"; name = "Paco Pompeani";
email = "paco@ecomail.io"; email = "paco@ecomail.io";
@ -10218,6 +10312,16 @@
githubId = 16487165; githubId = 16487165;
name = "Rafael Basso"; 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 = { rbrewer = {
email = "rwb123@gmail.com"; email = "rwb123@gmail.com";
github = "rbrewer123"; github = "rbrewer123";
@ -10344,6 +10448,18 @@
githubId = 22803888; githubId = 22803888;
name = "Lu Hongxu"; 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 = { rgrunbla = {
email = "remy@grunblatt.org"; email = "remy@grunblatt.org";
github = "rgrunbla"; github = "rgrunbla";
@ -11195,6 +11311,12 @@
githubId = 293035; githubId = 293035;
name = "Shawn Dellysse"; name = "Shawn Dellysse";
}; };
shawn8901 = {
email = "shawn8901@googlemail.com";
github = "shawn8901";
githubId = 12239057;
name = "Shawn8901";
};
shazow = { shazow = {
email = "andrey.petrov@shazow.net"; email = "andrey.petrov@shazow.net";
github = "shazow"; github = "shazow";
@ -11670,6 +11792,17 @@
githubId = 55607356; githubId = 55607356;
name = "Stephan Heßelmann"; 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 = { stelcodes = {
email = "stel@stel.codes"; email = "stel@stel.codes";
github = "stelcodes"; github = "stelcodes";
@ -12677,6 +12810,12 @@
githubId = 1983821; githubId = 1983821;
name = "Eric Wolf"; name = "Eric Wolf";
}; };
uakci = {
name = "uakci";
email = "uakci@uakci.pl";
github = "uakci";
githubId = 6961268;
};
udono = { udono = {
email = "udono@virtual-things.biz"; email = "udono@virtual-things.biz";
github = "udono"; github = "udono";
@ -13104,6 +13243,12 @@
githubId = 34962284; githubId = 34962284;
name = "wchresta"; name = "wchresta";
}; };
wdavidw = {
name = "David Worms";
email = "david@adaltas.com";
github = "wdavidw";
githubId = 46896;
};
wedens = { wedens = {
email = "kirill.wedens@gmail.com"; email = "kirill.wedens@gmail.com";
name = "wedens"; name = "wedens";

View file

@ -20,7 +20,7 @@ HACKAGE2NIX="${HACKAGE2NIX:-hackage2nix}"
# See: https://github.com/NixOS/nixpkgs/pull/122023 # See: https://github.com/NixOS/nixpkgs/pull/122023
export LC_ALL=C.UTF-8 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)" unpacked_hackage="$(nix-build -E "$extraction_derivation" --no-out-link)"
config_dir=pkgs/development/haskell-modules/configuration-hackage2nix config_dir=pkgs/development/haskell-modules/configuration-hackage2nix

View file

@ -81,6 +81,6 @@ rapidjson,https://github.com/xpol/lua-rapidjson.git,,,,,
readline,,,,,, readline,,,,,,
say,https://github.com/Olivine-Labs/say.git,,,,, say,https://github.com/Olivine-Labs/say.git,,,,,
std._debug,https://github.com/lua-stdlib/_debug.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 stdlib,,,,41.2.2,,vyp
vstruct,https://github.com/ToxicFrog/vstruct.git,,,,, vstruct,https://github.com/ToxicFrog/vstruct.git,,,,,

1 name src ref server version luaversion maintainers
81 readline
82 say https://github.com/Olivine-Labs/say.git
83 std._debug https://github.com/lua-stdlib/_debug.git
84 std.normalize git://github.com/lua-stdlib/normalize.git https://github.com/lua-stdlib/normalize.git
85 stdlib 41.2.2 vyp
86 vstruct https://github.com/ToxicFrog/vstruct.git

View file

@ -28,6 +28,11 @@ def process_args() -> argparse.Namespace:
default=1, default=1,
help="operate on aliases older than $year-$month", 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("--file", required=True, type=Path, help="alias file")
arg_parser.add_argument( arg_parser.add_argument(
"--dry-run", action="store_true", help="don't modify files, only print results" "--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( def get_date_lists(
txt: list[str], cutoffdate: datetimedate txt: list[str], cutoffdate: datetimedate, only_throws: bool
) -> tuple[list[str], list[str], list[str]]: ) -> tuple[list[str], list[str], list[str]]:
"""get a list of lines in which the date is older than $cutoffdate""" """get a list of lines in which the date is older than $cutoffdate"""
date_older_list: list[str] = [] date_older_list: list[str] = []
@ -57,7 +62,11 @@ def get_date_lists(
except ValueError: except ValueError:
continue 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 continue
if "=" not in line: if "=" not in line:
@ -67,7 +76,7 @@ def get_date_lists(
print(f"RESOLVE MANUALLY {line}") print(f"RESOLVE MANUALLY {line}")
elif "throw" in line: elif "throw" in line:
date_older_throw_list.append(line) date_older_throw_list.append(line)
else: elif not only_throws:
date_older_list.append(line) date_older_list.append(line)
return ( return (
@ -160,6 +169,7 @@ def main() -> None:
"""main""" """main"""
args = process_args() args = process_args()
only_throws = args.only_throws
aliasfile = Path(args.file).absolute() aliasfile = Path(args.file).absolute()
cutoffdate = (datetime.strptime(f"{args.year}-{args.month}-01", "%Y-%m-%d")).date() 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_throw_list: list[str] = []
date_older_list, date_sep_line_list, date_older_throw_list = get_date_lists( 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: list[tuple[str, str]] = []
converted_to_throw = convert_to_throw(date_older_list)
if date_older_list: if date_older_list:
converted_to_throw = convert_to_throw(date_older_list)
print(" Will be converted to throws. ".center(100, "-")) print(" Will be converted to throws. ".center(100, "-"))
for l_n in date_older_list: for l_n in date_older_list:
print(l_n) print(l_n)

View file

@ -117,6 +117,7 @@ with lib.maintainers; {
gnome = { gnome = {
members = [ members = [
bobby285271
hedning hedning
jtojnar jtojnar
dasj19 dasj19

View file

@ -27,9 +27,10 @@ The function `mkOption` accepts the following arguments.
`type` `type`
: The type of the option (see [](#sec-option-types)). It may be : The type of the option (see [](#sec-option-types)). This
omitted, but that's not advisable since it may lead to errors that argument is mandatory for nixpkgs modules. Setting this is highly
are hard to diagnose. recommended for the sake of documentation and type checking. In case it is
not set, a fallback type with unspecified behavior is used.
`default` `default`

View file

@ -22,7 +22,8 @@ merging is handled.
`types.package` `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` `types.anything`

View file

@ -17,7 +17,8 @@ checks:
them and comparing their contents. If they are different but only them and comparing their contents. If they are different but only
`X-Reload-Triggers` in the `[Unit]` section is changed, **reload** the unit. `X-Reload-Triggers` in the `[Unit]` section is changed, **reload** the unit.
The NixOS module system allows setting these triggers with the option The NixOS module system allows setting these triggers with the option
[systemd.services.\<name\>.reloadTriggers](#opt-systemd.services). If the [systemd.services.\<name\>.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: unit files differ in any way, the following actions are performed:
- `.path` and `.slice` units are ignored. There is no need to restart them - `.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 - The rest of the units (mostly `.service` units) are then **reload**ed if
`X-ReloadIfChanged` in the `[Service]` section is set to `true` (exposed `X-ReloadIfChanged` in the `[Service]` section is set to `true` (exposed
via [systemd.services.\<name\>.reloadIfChanged](#opt-systemd.services)). via [systemd.services.\<name\>.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 - 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 skipped. These flags are `X-RestartIfChanged` in the `[Service]` section

View file

@ -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.timers` (the list of commands to be executed periodically by
`systemd`). `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](#exec-escaping-example) for an example. When using these
functions system environment substitution should *not* be disabled explicitly.
::: {#locate-example .example} ::: {#locate-example .example}
::: {.title} ::: {.title}
**Example: NixOS Module for the "locate" Service** **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} ```{=docbook}
<xi:include href="option-declarations.section.xml" /> <xi:include href="option-declarations.section.xml" />
<xi:include href="option-types.section.xml" /> <xi:include href="option-types.section.xml" />

View file

@ -158,6 +158,12 @@ The following methods are available on machine objects:
e.g., `send_chars("foobar\n")` will type the string `foobar` e.g., `send_chars("foobar\n")` will type the string `foobar`
followed by the Enter key. 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`
: Execute a shell command, returning a list `(status, stdout)`. : 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 Killing the interactive session with `Ctrl-d` or `Ctrl-c` also ends
the guest session. 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 To test user units declared by `systemd.user.services` the optional
`user` argument can be used: `user` argument can be used:

View file

@ -38,9 +38,11 @@ options = {
<listitem> <listitem>
<para> <para>
The type of the option (see The type of the option (see
<xref linkend="sec-option-types" />). It may be omitted, but <xref linkend="sec-option-types" />). This argument is
thats not advisable since it may lead to errors that are hard mandatory for nixpkgs modules. Setting this is highly
to diagnose. recommended for the sake of documentation and type checking.
In case it is not set, a fallback type with unspecified
behavior is used.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View file

@ -43,7 +43,9 @@
</term> </term>
<listitem> <listitem>
<para> <para>
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.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View file

@ -38,8 +38,9 @@
<emphasis role="strong">reload</emphasis> the unit. The NixOS <emphasis role="strong">reload</emphasis> the unit. The NixOS
module system allows setting these triggers with the option module system allows setting these triggers with the option
<link linkend="opt-systemd.services">systemd.services.&lt;name&gt;.reloadTriggers</link>. <link linkend="opt-systemd.services">systemd.services.&lt;name&gt;.reloadTriggers</link>.
If the unit files differ in any way, the following actions are There are some additional keys in the <literal>[Unit]</literal>
performed: section that are ignored as well. If the unit files differ in
any way, the following actions are performed:
</para> </para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
@ -71,6 +72,11 @@
<literal>[Service]</literal> section is set to <literal>[Service]</literal> section is set to
<literal>true</literal> (exposed via <literal>true</literal> (exposed via
<link linkend="opt-systemd.services">systemd.services.&lt;name&gt;.reloadIfChanged</link>). <link linkend="opt-systemd.services">systemd.services.&lt;name&gt;.reloadIfChanged</link>).
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
<emphasis role="strong">start</emphasis>ed instead of
reloaded.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>

View file

@ -122,6 +122,25 @@
services) and <literal>systemd.timers</literal> (the list of services) and <literal>systemd.timers</literal> (the list of
commands to be executed periodically by <literal>systemd</literal>). commands to be executed periodically by <literal>systemd</literal>).
</para> </para>
<para>
Care must be taken when writing systemd services using
<literal>Exec*</literal> directives. By default systemd performs
substitution on <literal>%&lt;char&gt;</literal> specifiers in these
directives, expands environment variables from
<literal>$FOO</literal> and <literal>${FOO}</literal>, splits
arguments on whitespace, and splits commands on
<literal>;</literal>. All of these must be escaped to avoid
unexpected substitution or splitting when interpolating into an
<literal>Exec*</literal> directive, e.g. when using an
<literal>extraArgs</literal> option to pass additional arguments to
the service. The functions
<literal>utils.escapeSystemdExecArg</literal> and
<literal>utils.escapeSystemdExecArgs</literal> are provided for
this, see <link linkend="exec-escaping-example">Example: Escaping in
Exec directives</link> for an example. When using these functions
system environment substitution should <emphasis>not</emphasis> be
disabled explicitly.
</para>
<anchor xml:id="locate-example" /> <anchor xml:id="locate-example" />
<para> <para>
<emphasis role="strong">Example: NixOS Module for the <emphasis role="strong">Example: NixOS Module for the
@ -183,6 +202,36 @@ in {
}; };
}; };
} }
</programlisting>
<anchor xml:id="exec-escaping-example" />
<para>
<emphasis role="strong">Example: Escaping in Exec
directives</emphasis>
</para>
<programlisting language="bash">
{ config, lib, pkgs, utils, ... }:
with lib;
let
cfg = config.services.echo;
echoAll = pkgs.writeScript &quot;echo-all&quot; ''
#! ${pkgs.runtimeShell}
for s in &quot;$@&quot;; do
printf '%s\n' &quot;$s&quot;
done
'';
args = [ &quot;a%Nything&quot; &quot;lang=\${LANG}&quot; &quot;;&quot; &quot;/bin/sh -c date&quot; ];
in {
systemd.services.echo =
{ description = &quot;Echo to the journal&quot;;
wantedBy = [ &quot;multi-user.target&quot; ];
serviceConfig.Type = &quot;oneshot&quot;;
serviceConfig.ExecStart = ''
${echoAll} ${utils.escapeSystemdExecArgs args}
'';
};
}
</programlisting> </programlisting>
<xi:include href="option-declarations.section.xml" /> <xi:include href="option-declarations.section.xml" />
<xi:include href="option-types.section.xml" /> <xi:include href="option-types.section.xml" />

View file

@ -261,6 +261,19 @@ start_all()
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<literal>send_console</literal>
</term>
<listitem>
<para>
Send keys to the kernel console. This allows interaction
with the systemd emergency mode, for example. Takes a string
that is sent, e.g.,
<literal>send_console(&quot;\n\nsystemctl default\n&quot;)</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<literal>execute</literal> <literal>execute</literal>
@ -502,6 +515,21 @@ machine.systemctl(&quot;list-jobs --no-pager&quot;, &quot;any-user&quot;) # spaw
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<literal>console_interact</literal>
</term>
<listitem>
<para>
Allows you to directly interact with QEMUs stdin. This
should only be used during test development, not in
production tests. Output from QEMU is only read line-wise.
<literal>Ctrl-c</literal> kills QEMU and
<literal>Ctrl-d</literal> closes console and returns to the
test runner.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
<para> <para>
To test user units declared by To test user units declared by

View file

@ -35,7 +35,17 @@
This means, <literal>ip[6]tables</literal>, This means, <literal>ip[6]tables</literal>,
<literal>arptables</literal> and <literal>ebtables</literal> <literal>arptables</literal> and <literal>ebtables</literal>
commands will actually show rules from some specific tables in commands will actually show rules from some specific tables in
the <literal>nf_tables</literal> kernel subsystem. the <literal>nf_tables</literal> kernel subsystem. In case
youre migrating from an older release without rebooting,
there might be cases where you end up with iptable rules
configured both in the legacy <literal>iptables</literal>
kernel backend, as well as in the <literal>nf_tables</literal>
backend. This can lead to confusing firewall behaviour. An
<literal>iptables-save</literal> after switching will complain
about <quote>iptables-legacy tables present</quote>. Its
probably best to reboot after the upgrade, or manually
removing all legacy iptables rules (via the
<literal>iptables-legacy</literal> package).
</para> </para>
</listitem> </listitem>
<listitem> <listitem>

View file

@ -15,6 +15,14 @@
<section xml:id="sec-release-22.05-highlights"> <section xml:id="sec-release-22.05-highlights">
<title>Highlights</title> <title>Highlights</title>
<itemizedlist> <itemizedlist>
<listitem>
<para>
The <literal>firefox</literal> browser on
<literal>x86_64-linux</literal> is now making use of
profile-guided optimization resulting in a much more
responsive browsing experience.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<literal>security.acme.defaults</literal> has been added to <literal>security.acme.defaults</literal> has been added to
@ -25,6 +33,16 @@
<literal>services.nginx.virtualHosts.*.enableACME</literal>). <literal>services.nginx.virtualHosts.*.enableACME</literal>).
</para> </para>
</listitem> </listitem>
<listitem>
<para>
GNOME has been upgraded to 42. Please take a look at their
<link xlink:href="https://release.gnome.org/42/">Release
Notes</link> for details. Notably, it replaces gedit with
GNOME Text Editor, GNOME Terminal with GNOME Console (formerly
Kings Cross), and GNOME Screenshot with a tool built into the
Shell.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
PHP 8.1 is now available PHP 8.1 is now available
@ -62,6 +80,14 @@
notes</link> for details. notes</link> for details.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Module authors can use
<literal>mkRenamedOptionModuleWith</literal> to automate the
deprecation cycle without annoying out-of-tree module authors
and their users.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>
<section xml:id="sec-release-22.05-new-services"> <section xml:id="sec-release-22.05-new-services">
@ -109,7 +135,7 @@
<para> <para>
<link xlink:href="https://frrouting.org/">FRRouting</link>, a <link xlink:href="https://frrouting.org/">FRRouting</link>, a
popular suite of Internet routing protocol daemons (BGP, BFD, 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
<link linkend="opt-services.frr.babel.enable">services.frr</link> <link linkend="opt-services.frr.babel.enable">services.frr</link>
</para> </para>
</listitem> </listitem>
@ -187,6 +213,14 @@
<link xlink:href="options.html#opt-services.mtr-exporter.enable">services.mtr-exporter</link>. <link xlink:href="options.html#opt-services.mtr-exporter.enable">services.mtr-exporter</link>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<link xlink:href="https://github.com/prometheus-pve/prometheus-pve-exporter">prometheus-pve-exporter</link>,
a tool that exposes information from the Proxmox VE API for
use by Prometheus. Available as
<link xlink:href="options.html#opt-services.prometheus.exporters.pve">services.prometheus.exporters.pve</link>.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<link xlink:href="https://tetrd.app">tetrd</link>, share your <link xlink:href="https://tetrd.app">tetrd</link>, share your
@ -241,6 +275,17 @@
<link linkend="opt-services.prosody-filer.enable">services.prosody-filer</link>. <link linkend="opt-services.prosody-filer.enable">services.prosody-filer</link>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<link xlink:href="https://github.com/rfjakob/systembus-notify">systembus-notify</link>,
allow system level notifications to reach the users. Available
as
<link xlink:href="opt-services.systembus-notify.enable">services.systembus-notify</link>.
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.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<link xlink:href="https://github.com/audreyt/ethercalc">ethercalc</link>, <link xlink:href="https://github.com/audreyt/ethercalc">ethercalc</link>,
@ -248,6 +293,20 @@
<link xlink:href="options.html#opt-services.ethercalc.enable">services.ethercalc</link>. <link xlink:href="options.html#opt-services.ethercalc.enable">services.ethercalc</link>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<link xlink:href="https://nbd.sourceforge.io/">nbd</link>, a
Network Block Device server. Available as
<link xlink:href="options.html#opt-services.nbd.server.enable">services.nbd</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/Mic92/nix-ld">nix-ld</link>,
Run unpatched dynamic binaries on NixOS. Available as
<link xlink:href="options.html#opt-programs.nix-ld.enable">programs.nix-ld</link>.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<link xlink:href="https://timetagger.app">timetagger</link>, <link xlink:href="https://timetagger.app">timetagger</link>,
@ -280,6 +339,12 @@
with many features. with many features.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<link xlink:href="https://clusterlabs.org/pacemaker/">pacemaker</link>
cluster resource manager
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>
<section xml:id="sec-release-22.05-incompatibilities"> <section xml:id="sec-release-22.05-incompatibilities">
@ -378,6 +443,24 @@
in your configuration. in your configuration.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<literal>fonts.fonts</literal> no longer includes ancient
bitmap fonts when both
<literal>config.services.xserver.enable</literal> and
<literal>config.nixpkgs.config.allowUnfree</literal> are
enabled. If you still want these fonts, use:
</para>
<programlisting language="bash">
{
fonts.fonts = [
pkgs.xorg.fontbhlucidatypewriter100dpi
pkgs.xorg.fontbhlucidatypewriter75dpi
pkgs.xorg.fontbh100dpi
];
}
</programlisting>
</listitem>
<listitem> <listitem>
<para> <para>
The DHCP server (<literal>services.dhcpd4</literal>, The DHCP server (<literal>services.dhcpd4</literal>,
@ -402,6 +485,15 @@
its reliance on python2. its reliance on python2.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<literal>services.ipfs.extraFlags</literal> is now escaped
with <literal>utils.escapeSystemdExecArgs</literal>. If you
rely on systemd interpolating <literal>extraFlags</literal> in
the service <literal>ExecStart</literal>, this will no longer
work.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The <literal>matrix-synapse</literal> service The <literal>matrix-synapse</literal> service
@ -417,6 +509,12 @@
still supported, because you can set arbitrary values in this still supported, because you can set arbitrary values in this
freeform type. freeform type.
</para> </para>
<para>
The <literal>listeners.*.bind_address</literal> option was
renamed to <literal>bind_addresses</literal> in order to match
the upstream <literal>homeserver.yaml</literal> option name.
It is now also a list of strings instead of a string.
</para>
<para> <para>
An example to make the required migration clearer: An example to make the required migration clearer:
</para> </para>
@ -478,7 +576,7 @@
listeners = [ { listeners = [ {
port = 8448; port = 8448;
bind_address = [ bind_addresses = [
&quot;::&quot; &quot;::&quot;
&quot;0.0.0.0&quot; &quot;0.0.0.0&quot;
]; ];
@ -509,7 +607,14 @@
Additionally a few option defaults have been synced up with Additionally a few option defaults have been synced up with
upstream default values, for example the upstream default values, for example the
<literal>max_upload_size</literal> grew from <literal>max_upload_size</literal> grew from
<literal>10M</literal> to <literal>50M</literal>. <literal>10M</literal> to <literal>50M</literal>. For the same
reason, the default <literal>media_store_path</literal> was
changed from <literal>${dataDir}/media</literal> to
<literal>${dataDir}/media_store</literal> if
<literal>system.stateVersion</literal> is at least
<literal>22.05</literal>. Files will need to be manually moved
to the new location if the <literal>stateVersion</literal> is
updated.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -519,6 +624,25 @@
because Python 2 is being retired from nixpkgs. because Python 2 is being retired from nixpkgs.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Services in the <literal>hadoop</literal> module previously
set <literal>openFirewall</literal> to true by default. This
has now been changed to false. Node definitions for multi-node
clusters would need <literal>openFirewall = true;</literal> to
be added to to hadoop services when upgrading from NixOS
21.11.
</para>
</listitem>
<listitem>
<para>
<literal>services.hadoop.yarn.nodemanager</literal> now uses
cgroup-based CPU limit enforcement by default. Additionally,
the option <literal>useCGroups</literal> was added to
nodemanagers as an easy way to switch back to the old
behavior.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The <literal>wafHook</literal> hook now honors The <literal>wafHook</literal> hook now honors
@ -564,6 +688,23 @@
6.x</link> and renamed to <literal>gnome-secrets</literal>. 6.x</link> and renamed to <literal>gnome-secrets</literal>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<literal>services.gnome.experimental-features.realtime-scheduling</literal>
option has been removed, as GNOME Shell now
<link xlink:href="https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2060">uses
rtkit</link>. Use
<literal>security.rtkit.enable = true;</literal> instead. As
before, you will need to have it enabled using GSettings.
</para>
</listitem>
<listitem>
<para>
<literal>services.telepathy</literal> will no longer be
enabled by default for GNOME desktops, one should enable it in
their configs if using Empathy or Polari.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
If you previously used If you previously used
@ -691,6 +832,60 @@
unmaintained unmaintained
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<literal>pkgs._7zz</literal> is now correctly licensed as
LGPL3+ and BSD3 with optional unfree unRAR licensed code
</para>
</listitem>
<listitem>
<para>
The <literal>vim.customize</literal> function produced by
<literal>vimUtils.makeCustomizable</literal> now has a
slightly different interface:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
The wrapper now includes everything in the given Vim
derivation if <literal>name</literal> is
<literal>&quot;vim&quot;</literal> (the default). This
makes the <literal>wrapManual</literal> argument obsolete,
but this behavior can be overriden by setting the
<literal>standalone</literal> argument.
</para>
</listitem>
<listitem>
<para>
All the executables present in the given derivation (or,
in <literal>standalone</literal> mode, only the
<literal>*vim</literal> ones) are wrapped. This makes the
<literal>wrapGui</literal> argument obsolete.
</para>
</listitem>
<listitem>
<para>
The <literal>vimExecutableName</literal> and
<literal>gvimExecutableName</literal> arguments were
replaced by a single <literal>executableName</literal>
argument in which the shell variable
<literal>$exe</literal> can be used to refer to the
wrapped executables name.
</para>
</listitem>
</itemizedlist>
<para>
See the comments in
<literal>pkgs/applications/editors/vim/plugins/vim-utils.nix</literal>
for more details.
</para>
<para>
<literal>vimUtils.vimWithRC</literal> was removed. You should
instead use <literal>customize</literal> on a Vim derivation,
which now accepts <literal>vimrcFile</literal> and
<literal>gvimrcFile</literal> arguments.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<literal>tilp2</literal> was removed together with its module <literal>tilp2</literal> was removed together with its module
@ -723,6 +918,16 @@
<literal>true</literal>. <literal>true</literal>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The <literal>miller</literal> package has been upgraded from
5.10.3 to
<link xlink:href="https://github.com/johnkerl/miller/releases/tag/v6.2.0">6.2.0</link>.
See
<link xlink:href="https://miller.readthedocs.io/en/latest/new-in-miller-6">Whats
new in Miller 6</link>.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
MultiMC has been replaced with the fork PolyMC due to upstream MultiMC has been replaced with the fork PolyMC due to upstream
@ -748,6 +953,16 @@
<literal>systemd.nspawn.&lt;name&gt;.execConfig.PrivateUsers = false</literal> <literal>systemd.nspawn.&lt;name&gt;.execConfig.PrivateUsers = false</literal>
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The Tor SOCKS proxy is now actually disabled if
<literal>services.tor.client.enable</literal> is set to
<literal>false</literal> (the default). If you are using this
functionality but didnt change the setting or set it to
<literal>false</literal>, you now need to set it to
<literal>true</literal>.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The terraform 0.12 compatibility has been removed and the The terraform 0.12 compatibility has been removed and the
@ -811,6 +1026,58 @@
include serif fonts. include serif fonts.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<literal>pkgs.epgstation</literal> has been upgraded from v1
to v2, resulting in incompatible changes in the database
scheme and configuration format.
</para>
</listitem>
<listitem>
<para>
Some top-level settings under
<link linkend="opt-services.epgstation.enable">services.epgstation</link>
is now deprecated because it was redudant due to the same
options being present in
<link linkend="opt-services.epgstation.settings">services.epgstation.settings</link>.
</para>
</listitem>
<listitem>
<para>
The option <literal>services.epgstation.basicAuth</literal>
was removed because basic authentication support was dropped
by upstream.
</para>
</listitem>
<listitem>
<para>
The option
<link linkend="opt-services.epgstation.database.passwordFile">services.epgstation.database.passwordFile</link>
no longer has a default value. Make sure to set this option
explicitly before upgrading. Change the database password if
necessary.
</para>
</listitem>
<listitem>
<para>
The
<link linkend="opt-services.epgstation.settings">services.epgstation.settings</link>
option now expects options for <literal>config.yml</literal>
in EPGStation v2.
</para>
</listitem>
<listitem>
<para>
Existing data for the
<link linkend="opt-services.epgstation.enable">services.epgstation</link>
module would have to be backed up prior to the upgrade. To
back up exising data to
<literal>/tmp/epgstation.bak</literal>, run
<literal>sudo -u epgstation epgstation run backup /tmp/epgstation.bak</literal>.
To import that data after to the upgrade, run
<literal>sudo -u epgstation epgstation run v1migrate /tmp/epgstation.bak</literal>
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<literal>switch-to-configuration</literal> (the script that is <literal>switch-to-configuration</literal> (the script that is
@ -1050,7 +1317,8 @@
Legacy options have been mapped to the corresponding Legacy options have been mapped to the corresponding
options under under options under under
<link xlink:href="options.html#opt-nix.settings">nix.settings</link> <link xlink:href="options.html#opt-nix.settings">nix.settings</link>
but may be deprecated in the future. and will be deprecated when NixOS 21.11 reaches end of
life.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -1071,6 +1339,33 @@
using the PyPy interpreter were added. using the PyPy interpreter were added.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
Some improvements have been made to the
<literal>hadoop</literal> module:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
A <literal>gatewayRole</literal> option has been added,
for deploying hadoop cluster configuration files to a node
that does not have any active services
</para>
</listitem>
<listitem>
<para>
Support for older versions of hadoop have been added to
the module
</para>
</listitem>
<listitem>
<para>
Overriding and extending site XML files has been made
easier
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem> <listitem>
<para> <para>
If you are using Wayland you can choose to use the Ozone 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. compatibilty, but will be removed at a later date.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The <literal>unifi</literal> package was switched from
<literal>unifi6</literal> to <literal>unifi7</literal>. Direct
downgrades from Unifi 7 to Unifi 6 are not possible and
require restoring from a backup made by Unifi 6.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<literal>programs.zsh.autosuggestions.strategy</literal> now <literal>programs.zsh.autosuggestions.strategy</literal> now
@ -1108,6 +1411,15 @@
using this default will print a warning when rebuilt. using this default will print a warning when rebuilt.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The <literal>services.unifi-video.openPorts</literal> option
default value of <literal>true</literal> is now deprecated and
will be changed to <literal>false</literal> in 22.11.
Configurations using this default will print a warning when
rebuilt.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
<literal>security.acme</literal> certificates will now <literal>security.acme</literal> certificates will now
@ -1171,10 +1483,10 @@
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
A new option The options <literal>boot.extraModprobeConfig</literal> and
<literal>boot.initrd.extraModprobeConfig</literal> has been <literal>boot.blacklistedKernelModules</literal> now also take
added which can be used to configure kernel modules that are effect in the initrd by copying the file
loaded in the initrd. <literal>/etc/modprobe.d/nixos.conf</literal> into the initrd.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -1184,6 +1496,52 @@
instead of <literal>configuration.nix</literal>. instead of <literal>configuration.nix</literal>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
ORY Kratos was updated to version 0.8.3-alpha.1.pre.0, which
introduces some breaking changes:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
If you are relying on the SQLite images, update your
Docker Pull commands as follows:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
<literal>docker pull oryd/kratos:{version}</literal>
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
Additionally, all passwords now have to be at least 8
characters long.
</para>
</listitem>
<listitem>
<para>
For more details, see:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
<link xlink:href="https://github.com/ory/kratos/releases/tag/v0.8.1-alpha.1">Release
Notes for v0.8.1-alpha-1</link>
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/ory/kratos/releases/tag/v0.8.2-alpha.1">Release
Notes for v0.8.2-alpha-1</link>
</para>
</listitem>
</itemizedlist>
</listitem>
</itemizedlist>
</listitem>
<listitem> <listitem>
<para> <para>
<literal>fetchFromSourcehut</literal> now allows fetching <literal>fetchFromSourcehut</literal> now allows fetching
@ -1212,6 +1570,15 @@
<literal>pkgs.theLoungePlugins.themes</literal>. <literal>pkgs.theLoungePlugins.themes</literal>.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The option
<literal>services.xserver.videoDriver = [ &quot;nvidia&quot; ];</literal>
will now also install
<link xlink:href="https://github.com/elFarto/nvidia-vaapi-driver">nvidia
VA-API drivers</link> by default.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The <literal>firmwareLinuxNonfree</literal> package has been The <literal>firmwareLinuxNonfree</literal> package has been
@ -1271,15 +1638,6 @@
been added by default. been added by default.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<literal>security.pam.ussh</literal> has been added, which
allows authorizing PAM sessions based on SSH
<emphasis>certificates</emphasis> held within an SSH agent,
using
<link xlink:href="https://github.com/uber/pam-ussh">pam-ussh</link>.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The <literal>zrepl</literal> package has been updated from The <literal>zrepl</literal> package has been updated from
@ -1316,6 +1674,12 @@
warning. warning.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
<literal>services.autorandr</literal> now allows for adding
hooks and profiles declaratively.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
The <literal>pomerium-cli</literal> command has been moved out The <literal>pomerium-cli</literal> command has been moved out
@ -1354,6 +1718,52 @@
desktop environments as needed. desktop environments as needed.
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The <literal>hadoop</literal> package has added support for
<literal>aarch64-linux</literal> and
<literal>aarch64-darwin</literal> as of 3.3.1
(<link xlink:href="https://github.com/NixOS/nixpkgs/pull/158613">#158613</link>).
</para>
</listitem>
<listitem>
<para>
The <literal>R</literal> package now builds again on
<literal>aarch64-darwin</literal>
(<link xlink:href="https://github.com/NixOS/nixpkgs/pull/158992">#158992</link>).
</para>
</listitem>
<listitem>
<para>
The <literal>spark3</literal> package has been updated from
3.1.2 to 3.2.1
(<link xlink:href="https://github.com/NixOS/nixpkgs/pull/160075">#160075</link>):
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
Testing has been enabled for
<literal>aarch64-linux</literal> in addition to
<literal>x86_64-linux</literal>.
</para>
</listitem>
<listitem>
<para>
The <literal>spark3</literal> package is now usable on
<literal>aarch64-darwin</literal> as a result of
<link xlink:href="https://github.com/NixOS/nixpkgs/pull/158613">#158613</link>
and
<link xlink:href="https://github.com/NixOS/nixpkgs/pull/158992">#158992</link>.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
The <literal>programs.nncp</literal> options were added for
generating host-global NNCP configuration.
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>
</section> </section>

View file

@ -91,6 +91,10 @@
<option>--flake</option> <replaceable>flake-uri</replaceable> <option>--flake</option> <replaceable>flake-uri</replaceable>
</arg> </arg>
<arg>
<option>--no-flake</option>
</arg>
<arg> <arg>
<option>--override-input</option> <replaceable>input-name</replaceable> <replaceable>flake-uri</replaceable> <option>--override-input</option> <replaceable>input-name</replaceable> <replaceable>flake-uri</replaceable>
</arg> </arg>
@ -594,6 +598,20 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>--no-flake</option>
</term>
<listitem>
<para>
Do not imply <option>--flake</option> if
<filename>/etc/nixos/flake.nix</filename> exists. With this
option, it is possible to build non-flake NixOS configurations
even if the current NixOS systems uses flakes.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
<para> <para>

View file

@ -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). [Fedora](https://fedoraproject.org/wiki/Changes/iptables-nft-default).
This means, `ip[6]tables`, `arptables` and `ebtables` commands will actually This means, `ip[6]tables`, `arptables` and `ebtables` commands will actually
show rules from some specific tables in the `nf_tables` kernel subsystem. 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 - systemd got an `nftables` backend, and configures (networkd) rules in their
own `io.systemd.*` tables. Check `nft list ruleset` to see these rules, not own `io.systemd.*` tables. Check `nft list ruleset` to see these rules, not

View file

@ -6,11 +6,17 @@ In addition to numerous new and upgraded packages, this release has the followin
## Highlights {#sec-release-22.05-highlights} ## 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 - `security.acme.defaults` has been added to simplify configuring
settings for many certificates at once. This also opens up the settings for many certificates at once. This also opens up the
the option to use DNS-01 validation when using `enableACME` on the option to use DNS-01 validation when using `enableACME` on
web server virtual hosts (e.g. `services.nginx.virtualHosts.*.enableACME`). 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 Kings Cross), and GNOME Screenshot with a tool built into the Shell.
- PHP 8.1 is now available - 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). - 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. - [`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} ## 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). - [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). - [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). - [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). - [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). - [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). - [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). - [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 - [ethercalc](https://github.com/audreyt/ethercalc), an online collaborative
spreadsheet. Available as [services.ethercalc](options.html#opt-services.ethercalc.enable). 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). - [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). - [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. - [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
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
## Backward Incompatibilities {#sec-release-22.05-incompatibilities} ## 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. 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. 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 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 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. 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. - 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. - 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 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 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. 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: An example to make the required migration clearer:
Before: Before:
@ -194,7 +230,7 @@ In addition to numerous new and upgraded packages, this release has the followin
listeners = [ { listeners = [ {
port = 8448; port = 8448;
bind_address = [ bind_addresses = [
"::" "::"
"0.0.0.0" "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`. 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. - 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`. - 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. - `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`. - 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`. - 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. - 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.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 - `tilp2` was removed together with its module
- The F-PROT antivirus (`fprot` package) and its service module were removed because it - 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.<name>.ipv4.routes` and `networking.interfaces.<name>.ipv6.routes` are no longer ignored when using networkd instead of the default scripted network backend by setting `networking.useNetworkd` to `true`. - The options `networking.interfaces.<name>.ipv4.routes` and `networking.interfaces.<name>.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`. - 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.<name>.execConfig.PrivateUsers = false` - `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.<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 `terraform.withPlugins` and `terraform-providers.mkProvider` implementations simplified. Providers now need to be stored under - 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/<registry>/<owner>/<name>/<version>/<os>_<arch>/terraform-provider-<name>_v<version>` (which mkProvider does). `$out/libexec/terraform-providers/<registry>/<owner>/<name>/<version>/<os>_<arch>/terraform-provider-<name>_v<version>` (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 `pkgs.noto-fonts-cjk` is currently an alias of `pkgs.noto-fonts-cjk-sans` and
doesn't include serif fonts. 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 - `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. * 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`. * 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. 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): - 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. * [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. - 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 - 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 in Chrome and several Electron apps by setting the environment variable
`NIXOS_OZONE_WL=1` (for example via `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 combined `influxdb2` package is still provided in this release for
backwards compatibilty, but will be removed at a later date. 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. - `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. - 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. 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 - `security.acme` certificates will now correctly check for CA
revokation before reaching their minimum age. 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. - 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`. - `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 - `fetchFromSourcehut` now allows fetching repositories recursively
using `fetchgit` or `fetchhg` if the argument `fetchSubmodules` using `fetchgit` or `fetchhg` if the argument `fetchSubmodules`
is set to `true`. 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.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`. - 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. - 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 - `services.logrotate.enable` now defaults to true if any rotate path has
been defined, and some paths have been added by default. 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 `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. - 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. Reason is that the old name has been deprecated upstream.
Using the old option name will still work, but produce a warning. 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` command has been moved out of the `pomerium` package into
the `pomerium-cli` package, following upstream's repository split. If you are the `pomerium-cli` package, following upstream's repository split. If you are
using the `pomerium-cli` command, you should now install the `pomerium-cli` 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 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.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. --> <!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

View file

@ -66,14 +66,21 @@ for (k, v) in overrides.items():
elif ov is not None or cur.get(ok, None) is None: elif ov is not None or cur.get(ok, None) is None:
cur[ok] = ov cur[ok] = ov
severity = "error" if warningsAreErrors else "warning"
# check that every option has a description # check that every option has a description
hasWarnings = False hasWarnings = False
for (k, v) in options.items(): for (k, v) in options.items():
if v.value.get('description', None) is None: if v.value.get('description', None) is None:
severity = "error" if warningsAreErrors else "warning"
hasWarnings = True hasWarnings = True
print(f"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys.stderr) 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." 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: if hasWarnings and warningsAreErrors:
print( print(
"\x1b[1;31m" + "\x1b[1;31m" +

View file

@ -5,6 +5,7 @@ with lib;
let let
cfg = config.systemd; cfg = config.systemd;
lndir = "${pkgs.buildPackages.xorg.lndir}/bin/lndir"; lndir = "${pkgs.buildPackages.xorg.lndir}/bin/lndir";
systemd = cfg.package;
in rec { in rec {
shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s); shellEscape = s: (replaceChars [ "\\" ] [ "\\\\" ] s);
@ -22,8 +23,9 @@ in rec {
inherit (unit) text; inherit (unit) text;
} }
'' ''
mkdir -p $out name=${shellEscape name}
echo -n "$text" > $out/${shellEscape name} mkdir -p "$out/$(dirname "$name")"
echo -n "$text" > "$out/$name"
'' ''
else else
pkgs.runCommand "unit-${mkPathSafeName name}-disabled" pkgs.runCommand "unit-${mkPathSafeName name}-disabled"
@ -31,8 +33,9 @@ in rec {
allowSubstitutes = false; allowSubstitutes = false;
} }
'' ''
mkdir -p $out name=${shellEscape name}
ln -s /dev/null $out/${shellEscape name} mkdir -p "$out/$(dirname "$name")"
ln -s /dev/null "$out/$name"
''; '';
boolValues = [true false "yes" "no"]; 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}
'';
};
} }

View file

@ -55,6 +55,7 @@ class Driver:
tmp_dir = get_tmp_dir() tmp_dir = get_tmp_dir()
with rootlog.nested("start all VLans"): with rootlog.nested("start all VLans"):
vlans = list(set(vlans))
self.vlans = [VLan(nr, tmp_dir) for nr in vlans] self.vlans = [VLan(nr, tmp_dir) for nr in vlans]
def cmd(scripts: List[str]) -> Iterator[NixStartScript]: def cmd(scripts: List[str]) -> Iterator[NixStartScript]:

View file

@ -198,7 +198,7 @@ class StartCommand:
) -> subprocess.Popen: ) -> subprocess.Popen:
return subprocess.Popen( return subprocess.Popen(
self.cmd(monitor_socket_path, shell_socket_path), self.cmd(monitor_socket_path, shell_socket_path),
stdin=subprocess.DEVNULL, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
shell=True, shell=True,
@ -558,6 +558,28 @@ class Machine:
pass_fds=[self.shell.fileno()], 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: def succeed(self, *commands: str, timeout: Optional[int] = None) -> str:
"""Execute each command and check that it succeeds.""" """Execute each command and check that it succeeds."""
output = "" output = ""
@ -834,6 +856,12 @@ class Machine:
self.send_monitor_command("sendkey {}".format(key)) self.send_monitor_command("sendkey {}".format(key))
time.sleep(0.01) 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: def start(self) -> None:
if self.booted: if self.booted:
return return

View file

@ -146,26 +146,28 @@ rec {
# Make a full-blown test # Make a full-blown test
makeTest = makeTest =
{ testScript { machine ? null
, nodes ? {}
, testScript
, enableOCR ? false , enableOCR ? false
, name ? "unnamed" , name ? "unnamed"
# Skip linting (mainly intended for faster dev cycles) # Skip linting (mainly intended for faster dev cycles)
, skipLint ? false , skipLint ? false
, passthru ? {} , passthru ? {}
, meta ? {}
, # For meta.position , # For meta.position
pos ? # position used in error messages and for meta.position pos ? # position used in error messages and for meta.position
(if t.meta.description or null != null (if meta.description or null != null
then builtins.unsafeGetAttrPos "description" t.meta then builtins.unsafeGetAttrPos "description" meta
else builtins.unsafeGetAttrPos "testScript" t) else builtins.unsafeGetAttrPos "testScript" t)
, ...
} @ t: } @ t:
let let
nodes = qemu_pkg: mkNodes = qemu_pkg:
let let
testScript' = testScript' =
# Call the test script with the computed nodes. # Call the test script with the computed nodes.
if lib.isFunction testScript if lib.isFunction testScript
then testScript { nodes = nodes qemu_pkg; } then testScript { nodes = mkNodes qemu_pkg; }
else testScript; else testScript;
build-vms = import ./build-vms.nix { build-vms = import ./build-vms.nix {
@ -205,33 +207,29 @@ rec {
}; };
in in
build-vms.buildVirtualNetwork ( build-vms.buildVirtualNetwork (
t.nodes or (if t ? machine then { machine = t.machine; } else { }) nodes // lib.optionalAttrs (machine != null) { inherit machine; }
); );
driver = setupDriverForTest { driver = setupDriverForTest {
inherit testScript enableOCR skipLint passthru; inherit testScript enableOCR skipLint passthru;
testName = name; testName = name;
qemu_pkg = pkgs.qemu_test; qemu_pkg = pkgs.qemu_test;
nodes = nodes pkgs.qemu_test; nodes = mkNodes pkgs.qemu_test;
}; };
driverInteractive = setupDriverForTest { driverInteractive = setupDriverForTest {
inherit testScript enableOCR skipLint passthru; inherit testScript enableOCR skipLint passthru;
testName = name; testName = name;
qemu_pkg = pkgs.qemu; qemu_pkg = pkgs.qemu;
nodes = nodes pkgs.qemu; nodes = mkNodes pkgs.qemu;
interactive = true; interactive = true;
}; };
test = test = lib.addMetaAttrs meta (runTests { inherit driver pos driverInteractive; });
let
passMeta = drv: drv // lib.optionalAttrs (t ? meta) {
meta = (drv.meta or { }) // t.meta;
};
in passMeta (runTests { inherit driver pos driverInteractive; });
in in
test // { test // {
inherit test driver driverInteractive nodes; inherit test driver driverInteractive;
inherit (driver) nodes;
}; };
abortForFunction = functionName: abort ''The ${functionName} function was abortForFunction = functionName: abort ''The ${functionName} function was

View file

@ -45,6 +45,26 @@ rec {
replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"] replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"]
(removePrefix "/" s); (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 # Returns a system path for a given shell package
toShellPath = shell: toShellPath = shell:
if types.shellPackage.check shell then if types.shellPackage.check shell then

View file

@ -39,11 +39,6 @@ let
defaultXFonts = defaultXFonts =
[ (if hasHidpi then fontcursormisc_hidpi else pkgs.xorg.fontcursormisc) [ (if hasHidpi then fontcursormisc_hidpi else pkgs.xorg.fontcursormisc)
pkgs.xorg.fontmiscmisc 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 in

View file

@ -47,8 +47,8 @@ in
enable = mkOption { enable = mkOption {
type = types.bool; type = types.bool;
default = false; default = !(config.environment.etc ? "resolv.conf");
internal = true; defaultText = literalExpression ''!(config.environment.etc ? "resolv.conf")'';
description = '' description = ''
DNS configuration is managed by resolvconf. DNS configuration is managed by resolvconf.
''; '';
@ -110,8 +110,6 @@ in
config = mkMerge [ config = mkMerge [
{ {
networking.resolvconf.enable = !(config.environment.etc ? "resolv.conf");
environment.etc."resolvconf.conf".text = environment.etc."resolvconf.conf".text =
if !cfg.enable then if !cfg.enable then
# Force-stop any attempts to use resolvconf # Force-stop any attempts to use resolvconf

View file

@ -244,7 +244,7 @@ in
modules = optional (igpuDriver == "amdgpu") [ pkgs.xorg.xf86videoamdgpu ]; modules = optional (igpuDriver == "amdgpu") [ pkgs.xorg.xf86videoamdgpu ];
deviceSection = '' deviceSection = ''
BusID "${igpuBusId}" BusID "${igpuBusId}"
${optionalString syncCfg.enable ''Option "AccelMethod" "none"''} ${optionalString (syncCfg.enable && igpuDriver != "amdgpu") ''Option "AccelMethod" "none"''}
''; '';
} ++ singleton { } ++ singleton {
name = "nvidia"; name = "nvidia";
@ -270,9 +270,15 @@ in
Option "AllowNVIDIAGPUScreens" 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. # 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 ${pkgs.xorg.xrandr}/bin/xrandr --auto
''; '';
@ -284,10 +290,14 @@ in
environment.etc."egl/egl_external_platform.d".source = environment.etc."egl/egl_external_platform.d".source =
"/run/opengl-driver/share/egl/egl_external_platform.d/"; "/run/opengl-driver/share/egl/egl_external_platform.d/";
hardware.opengl.package = mkIf (!offloadCfg.enable) nvidia_x11.out; hardware.opengl.extraPackages = [
hardware.opengl.package32 = mkIf (!offloadCfg.enable) nvidia_x11.lib32; nvidia_x11.out
hardware.opengl.extraPackages = optional offloadCfg.enable nvidia_x11.out; pkgs.nvidia-vaapi-driver
hardware.opengl.extraPackages32 = optional offloadCfg.enable nvidia_x11.lib32; ];
hardware.opengl.extraPackages32 = [
nvidia_x11.lib32
pkgs.pkgsi686Linux.nvidia-vaapi-driver
];
environment.systemPackages = [ nvidia_x11.bin ] environment.systemPackages = [ nvidia_x11.bin ]
++ optionals cfg.nvidiaSettings [ nvidia_x11.settings ] ++ optionals cfg.nvidiaSettings [ nvidia_x11.settings ]

View file

@ -91,29 +91,9 @@ let
SERIAL 0 115200 SERIAL 0 115200
TIMEOUT ${builtins.toString syslinuxTimeout} TIMEOUT ${builtins.toString syslinuxTimeout}
UI vesamenu.c32 UI vesamenu.c32
MENU TITLE NixOS
MENU BACKGROUND /isolinux/background.png 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 ${config.isoImage.syslinuxTheme}
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
DEFAULT boot 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 { isoImage.appendToMenuLabel = mkOption {
default = " Installer"; default = " Installer";
example = " Live System"; example = " Live System";

View file

@ -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 # modified from https://github.com/archlinux/arch-install-scripts/blob/bb04ab435a5a89cd5e5ee821783477bc80db797f/arch-chroot.in#L26-L52
chroot_add_resolv_conf() { 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 [[ -e /etc/resolv.conf ]] || return 0
# Handle resolv.conf as a symlink to somewhere else. # 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 # 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. # it's a symlink. For simplicity, ignore the case of nested symlinks.
# We also ignore the possibility if `../`s escaping the root. # We also ignore the possibility of `../`s escaping the root.
resolv_conf=$(readlink "$chrootdir/etc/resolv.conf") resolvConf="$(readlink "$resolvConf")"
if [[ $resolv_conf = /* ]]; then if [[ "$resolvConf" = /* ]]; then
resolv_conf=$chrootdir$resolv_conf resolvConf="$chrootDir$resolvConf"
else else
resolv_conf=$chrootdir/etc/$resolv_conf resolvConf="$chrootDir/etc/$resolvConf"
fi fi
fi fi
# ensure file exists to bind mount over # ensure file exists to bind mount over
if [[ ! -f $resolv_conf ]]; then if [[ ! -f "$resolvConf" ]]; then
install -Dm644 /dev/null "$resolv_conf" || return 1 install -Dm644 /dev/null "$resolvConf" || return 1
fi 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 # If silent, write both stdout and stderr of activation script to /dev/null

View file

@ -51,7 +51,9 @@ for (my $n = 0; $n < scalar @ARGV; $n++) {
$n++; $n++;
$rootDir = $ARGV[$n]; $rootDir = $ARGV[$n];
die "$0: --root requires an argument\n" unless defined $rootDir; 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 =~ s/\/*$//; # remove trailing slashes
$rootDir = File::Spec->rel2abs($rootDir); # resolve absolute path
} }
elsif ($arg eq "--force") { elsif ($arg eq "--force") {
$force = 1; $force = 1;
@ -616,7 +618,12 @@ EOF
if ($showHardwareConfig) { if ($showHardwareConfig) {
print STDOUT $hwConfig; print STDOUT $hwConfig;
} else { } else {
if ($outDir eq "/etc/nixos") {
$outDir = "$rootDir$outDir"; $outDir = "$rootDir$outDir";
} else {
$outDir = File::Spec->rel2abs($outDir);
$outDir =~ s/\/*$//; # remove trailing slashes
}
my $fn = "$outDir/hardware-configuration.nix"; my $fn = "$outDir/hardware-configuration.nix";
print STDERR "writing $fn...\n"; print STDERR "writing $fn...\n";

View file

@ -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 '' system.nixos-generate-config.configuration = mkDefault ''
# Edit this configuration file to define what should be installed on # Edit this configuration file to define what should be installed on

View file

@ -183,7 +183,11 @@ in
pruneNames = mkOption { pruneNames = mkOption {
type = listOf str; type = listOf str;
default = [ ".bzr" ".cache" ".git" ".hg" ".svn" ]; default = lib.optionals (!isFindutils) [ ".bzr" ".cache" ".git" ".hg" ".svn" ];
defaultText = literalDocBook ''
<literal>[ ".bzr" ".cache" ".git" ".hg" ".svn" ]</literal>, if
supported by the locate implementation (i.e. mlocate or plocate).
'';
description = '' description = ''
Directory components which should exclude paths containing them from indexing Directory components which should exclude paths containing them from indexing
''; '';

View file

@ -8,8 +8,12 @@ let
concatStringsSep mapAttrsToList toLower concatStringsSep mapAttrsToList toLower
literalExpression mkRenamedOptionModule mkDefault mkOption trivial types; 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: attrsToText = attrs:
concatStringsSep "\n" (mapAttrsToList (n: v: ''${n}="${toString v}"'') attrs); concatStringsSep "\n" (
mapAttrsToList (n: v: ''${n}=${escapeIfNeccessary (toString v)}'') attrs
);
in in
{ {

View file

@ -118,6 +118,8 @@
./misc/version.nix ./misc/version.nix
./misc/wordlist.nix ./misc/wordlist.nix
./misc/nixops-autoluks.nix ./misc/nixops-autoluks.nix
./programs/_1password.nix
./programs/_1password-gui.nix
./programs/adb.nix ./programs/adb.nix
./programs/appgate-sdp.nix ./programs/appgate-sdp.nix
./programs/atop.nix ./programs/atop.nix
@ -180,8 +182,11 @@
./programs/msmtp.nix ./programs/msmtp.nix
./programs/mtr.nix ./programs/mtr.nix
./programs/nano.nix ./programs/nano.nix
./programs/nbd.nix
./programs/nix-ld.nix
./programs/neovim.nix ./programs/neovim.nix
./programs/nm-applet.nix ./programs/nm-applet.nix
./programs/nncp.nix
./programs/npm.nix ./programs/npm.nix
./programs/noisetorch.nix ./programs/noisetorch.nix
./programs/oblogout.nix ./programs/oblogout.nix
@ -301,6 +306,7 @@
./services/backup/znapzend.nix ./services/backup/znapzend.nix
./services/blockchain/ethereum/geth.nix ./services/blockchain/ethereum/geth.nix
./services/backup/zrepl.nix ./services/backup/zrepl.nix
./services/cluster/corosync/default.nix
./services/cluster/hadoop/default.nix ./services/cluster/hadoop/default.nix
./services/cluster/k3s/default.nix ./services/cluster/k3s/default.nix
./services/cluster/kubernetes/addons/dns.nix ./services/cluster/kubernetes/addons/dns.nix
@ -313,6 +319,7 @@
./services/cluster/kubernetes/pki.nix ./services/cluster/kubernetes/pki.nix
./services/cluster/kubernetes/proxy.nix ./services/cluster/kubernetes/proxy.nix
./services/cluster/kubernetes/scheduler.nix ./services/cluster/kubernetes/scheduler.nix
./services/cluster/pacemaker/default.nix
./services/cluster/spark/default.nix ./services/cluster/spark/default.nix
./services/computing/boinc/client.nix ./services/computing/boinc/client.nix
./services/computing/foldingathome/client.nix ./services/computing/foldingathome/client.nix
@ -773,6 +780,7 @@
./services/networking/headscale.nix ./services/networking/headscale.nix
./services/networking/hostapd.nix ./services/networking/hostapd.nix
./services/networking/htpdate.nix ./services/networking/htpdate.nix
./services/networking/https-dns-proxy.nix
./services/networking/hylafax/default.nix ./services/networking/hylafax/default.nix
./services/networking/i2pd.nix ./services/networking/i2pd.nix
./services/networking/i2p.nix ./services/networking/i2p.nix
@ -819,6 +827,7 @@
./services/networking/nar-serve.nix ./services/networking/nar-serve.nix
./services/networking/nat.nix ./services/networking/nat.nix
./services/networking/nats.nix ./services/networking/nats.nix
./services/networking/nbd.nix
./services/networking/ndppd.nix ./services/networking/ndppd.nix
./services/networking/nebula.nix ./services/networking/nebula.nix
./services/networking/networkmanager.nix ./services/networking/networkmanager.nix
@ -985,6 +994,7 @@
./services/system/nscd.nix ./services/system/nscd.nix
./services/system/saslauthd.nix ./services/system/saslauthd.nix
./services/system/self-deploy.nix ./services/system/self-deploy.nix
./services/system/systembus-notify.nix
./services/system/uptimed.nix ./services/system/uptimed.nix
./services/torrent/deluge.nix ./services/torrent/deluge.nix
./services/torrent/flexget.nix ./services/torrent/flexget.nix
@ -1163,7 +1173,12 @@
./system/boot/stage-1.nix ./system/boot/stage-1.nix
./system/boot/stage-2.nix ./system/boot/stage-2.nix
./system/boot/systemd.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/timesyncd.nix
./system/boot/tmp.nix ./system/boot/tmp.nix
./system/etc/etc-activation.nix ./system/etc/etc-activation.nix

View file

@ -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;
};
};
};
}

View file

@ -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;
};
};
};
}

View file

@ -1,8 +1,12 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib;
let let
cfg = config.programs.captive-browser; cfg = config.programs.captive-browser;
inherit (lib)
concatStringsSep escapeShellArgs optionalString
literalExpression mkEnableOption mkIf mkOption mkOptionDefault types;
browserDefault = chromium: concatStringsSep " " [ browserDefault = chromium: concatStringsSep " " [
''env XDG_CONFIG_HOME="$PREV_CONFIG_HOME"'' ''env XDG_CONFIG_HOME="$PREV_CONFIG_HOME"''
''${chromium}/bin/chromium'' ''${chromium}/bin/chromium''
@ -15,6 +19,15 @@ let
''-no-default-browser-check'' ''-no-default-browser-check''
''http://cache.nixos.org/'' ''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 in
{ {
###### interface ###### interface
@ -84,6 +97,11 @@ in
###### implementation ###### implementation
config = mkIf cfg.enable { 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 = programs.captive-browser.dhcp-dns =
let let

View file

@ -40,13 +40,15 @@ in
KDEDIRS = [ "" ]; KDEDIRS = [ "" ];
QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ]; QT_PLUGIN_PATH = [ "/lib/qt4/plugins" "/lib/kde4/plugins" ];
QTWEBKIT_PLUGIN_PATH = [ "/lib/mozilla/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_CONFIG_DIRS = [ "/etc/xdg" ];
XDG_DATA_DIRS = [ "/share" ]; XDG_DATA_DIRS = [ "/share" ];
MOZ_PLUGIN_PATH = [ "/lib/mozilla/plugins" ]; MOZ_PLUGIN_PATH = [ "/lib/mozilla/plugins" ];
LIBEXEC_PATH = [ "/lib/libexec" ]; LIBEXEC_PATH = [ "/lib/libexec" ];
}; };
environment.pathsToLink = [ "/lib/gtk-2.0" "/lib/gtk-3.0" "/lib/gtk-4.0" ];
environment.extraInit = environment.extraInit =
'' ''
unset ASPELL_CONF unset ASPELL_CONF

View file

@ -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" ];
};
}

View file

@ -0,0 +1,12 @@
{ pkgs, lib, config, ... }:
{
meta.maintainers = [ lib.maintainers.mic92 ];
options = {
programs.nix-ld.enable = lib.mkEnableOption ''nix-ld, Documentation: <link xlink:href="https://github.com/Mic92/nix-ld"/>'';
};
config = lib.mkIf config.programs.nix-ld.enable {
systemd.tmpfiles.rules = [
"L+ ${pkgs.nix-ld.ldPath} - - - - ${pkgs.nix-ld}/libexec/nix-ld"
];
};
}

View file

@ -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
<xref linkend="opt-programs.nncp.settings"/>.
'';
};
settings = mkOption {
type = settingsFormat.type;
description = ''
NNCP configuration, see
<link xlink:href="http://www.nncpgo.org/Configuration.html"/>.
At runtime these settings will be overlayed by the contents of
<xref linkend="opt-programs.nncp.secrets"/> into the file
<literal>${nncpCfgFile}</literal>. Node keypairs go in
<literal>secrets</literal>, do not specify them in
<literal>settings</literal> as they will be leaked into
<literal>/nix/store</literal>!
'';
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 ];
}

View file

@ -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 <option>security.pam.ussh</option> options.
Note that the <option>security.pam.ussh.enable</option> must also be
set for this option to take effect.
'';
};
yubicoAuth = mkOption { yubicoAuth = mkOption {
default = config.security.pam.yubico.enable; default = config.security.pam.yubico.enable;
defaultText = literalExpression "config.security.pam.yubico.enable"; defaultText = literalExpression "config.security.pam.yubico.enable";
@ -488,9 +475,6 @@ let
optionalString cfg.usbAuth '' optionalString cfg.usbAuth ''
auth sufficient ${pkgs.pam_usb}/lib/security/pam_usb.so 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 '' (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} 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 (<literal>pam-ussh</literal>) module.
This is similar to <literal>pam-ssh-agent</literal>, 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 <literal>usshAuth</literal>).
More information can be found <link
xlink:href="https://github.com/uber/pam-ussh">here</link>.
'';
};
caFile = mkOption {
default = null;
type = with types; nullOr path;
description = ''
By default <literal>pam-ussh</literal> reads the trusted user CA keys
from <filename>/etc/ssh/trusted_user_ca</filename>.
This should be set the same as your <literal>TrustedUserCAKeys</literal>
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 <literal>pam-ussh</literal> 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 <literal>authorizedPrincipalsFile</literal>.
'';
};
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 <literal>pam-ussh</literal> 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 <literal>authorizedPrincipals</literal>.
'';
};
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
<citerefentry>
<refentrytitle>pam.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry>
for better understanding of this option.
'';
};
};
security.pam.yubico = { security.pam.yubico = {
enable = mkOption { enable = mkOption {
default = false; default = false;
@ -1216,9 +1110,6 @@ in
optionalString (isEnabled (cfg: cfg.usbAuth)) '' optionalString (isEnabled (cfg: cfg.usbAuth)) ''
mr ${pkgs.pam_usb}/lib/security/pam_usb.so, 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)) '' optionalString (isEnabled (cfg: cfg.oathAuth)) ''
"mr ${pkgs.oathToolkit}/lib/security/pam_oath.so, "mr ${pkgs.oathToolkit}/lib/security/pam_oath.so,
'' + '' +

View file

@ -245,7 +245,7 @@ in
environment.systemPackages = [ sudo ]; environment.systemPackages = [ sudo ];
security.pam.services.sudo = { sshAgentAuth = true; usshAuth = true; }; security.pam.services.sudo = { sshAgentAuth = true; };
environment.etc.sudoers = environment.etc.sudoers =
{ source = { source =

View file

@ -1,21 +1,23 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib;
let let
inherit (lib) mkEnableOption mkIf mkOption optionalString types;
dataDir = "/var/lib/squeezelite"; dataDir = "/var/lib/squeezelite";
cfg = config.services.squeezelite; cfg = config.services.squeezelite;
pkg = if cfg.pulseAudio then pkgs.squeezelite-pulse else pkgs.squeezelite;
bin = "${pkg}/bin/${pkg.pname}";
in { in
{
###### interface ###### interface
options = { options.services.squeezelite = {
services.squeezelite= {
enable = mkEnableOption "Squeezelite, a software Squeezebox emulator"; enable = mkEnableOption "Squeezelite, a software Squeezebox emulator";
pulseAudio = mkEnableOption "pulseaudio support";
extraArguments = mkOption { extraArguments = mkOption {
default = ""; default = "";
type = types.str; type = types.str;
@ -23,28 +25,22 @@ in {
Additional command line arguments to pass to Squeezelite. Additional command line arguments to pass to Squeezelite.
''; '';
}; };
};
}; };
###### implementation ###### implementation
config = mkIf cfg.enable { config = mkIf cfg.enable {
systemd.services.squeezelite = { systemd.services.squeezelite = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
after = [ "network.target" "sound.target" ]; after = [ "network.target" "sound.target" ];
description = "Software Squeezebox emulator"; description = "Software Squeezebox emulator";
serviceConfig = { serviceConfig = {
DynamicUser = true; 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; StateDirectory = builtins.baseNameOf dataDir;
SupplementaryGroups = "audio"; SupplementaryGroups = "audio";
}; };
}; };
}; };
} }

View file

@ -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}"
'';
};
}

View file

@ -1,6 +1,6 @@
{ cfg, pkgs, lib }: { cfg, pkgs, lib }:
let let
propertyXml = name: value: '' propertyXml = name: value: lib.optionalString (value != null) ''
<property> <property>
<name>${name}</name> <name>${name}</name>
<value>${builtins.toString value}</value> <value>${builtins.toString value}</value>
@ -29,16 +29,16 @@ let
export HADOOP_LOG_DIR=/tmp/hadoop/$USER export HADOOP_LOG_DIR=/tmp/hadoop/$USER
''; '';
in in
pkgs.runCommand "hadoop-conf" {} '' pkgs.runCommand "hadoop-conf" {} (with cfg; ''
mkdir -p $out/ mkdir -p $out/
cp ${siteXml "core-site.xml" cfg.coreSite}/* $out/ cp ${siteXml "core-site.xml" (coreSite // coreSiteInternal)}/* $out/
cp ${siteXml "hdfs-site.xml" cfg.hdfsSite}/* $out/ cp ${siteXml "hdfs-site.xml" (hdfsSiteDefault // hdfsSite // hdfsSiteInternal)}/* $out/
cp ${siteXml "mapred-site.xml" cfg.mapredSite}/* $out/ cp ${siteXml "mapred-site.xml" (mapredSiteDefault // mapredSite)}/* $out/
cp ${siteXml "yarn-site.xml" cfg.yarnSite}/* $out/ cp ${siteXml "yarn-site.xml" (yarnSiteDefault // yarnSite // yarnSiteInternal)}/* $out/
cp ${siteXml "httpfs-site.xml" cfg.httpfsSite}/* $out/ cp ${siteXml "httpfs-site.xml" httpfsSite}/* $out/
cp ${cfgFile "container-executor.cfg" cfg.containerExecutorCfg}/* $out/ cp ${cfgFile "container-executor.cfg" containerExecutorCfg}/* $out/
cp ${pkgs.writeTextDir "hadoop-user-functions.sh" userFunctions}/* $out/ cp ${pkgs.writeTextDir "hadoop-user-functions.sh" userFunctions}/* $out/
cp ${pkgs.writeTextDir "hadoop-env.sh" hadoopEnv}/* $out/ cp ${pkgs.writeTextDir "hadoop-env.sh" hadoopEnv}/* $out/
cp ${cfg.log4jProperties} $out/log4j.properties cp ${log4jProperties} $out/log4j.properties
${lib.concatMapStringsSep "\n" (dir: "cp -r ${dir}/* $out/") cfg.extraConfDirs} ${lib.concatMapStringsSep "\n" (dir: "cp -r ${dir}/* $out/") extraConfDirs}
'' '')

View file

@ -21,24 +21,50 @@ with lib;
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/core-default.xml"/> <link xlink:href="https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/core-default.xml"/>
''; '';
}; };
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 = { default = {
"dfs.namenode.rpc-bind-host" = "0.0.0.0"; "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; type = types.attrsOf types.anything;
description = ''
Default options for hdfs-site.xml
'';
};
hdfsSite = mkOption {
default = {};
type = types.attrsOf types.anything;
example = literalExpression '' example = literalExpression ''
{ {
"dfs.nameservices" = "namenode1"; "dfs.nameservices" = "namenode1";
} }
''; '';
description = '' description = ''
Hadoop hdfs-site.xml definition Additional options and overrides for hdfs-site.xml
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml"/> <link xlink:href="https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/hdfs-default.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 = { default = {
"mapreduce.framework.name" = "yarn"; "mapreduce.framework.name" = "yarn";
"yarn.app.mapreduce.am.env" = "HADOOP_MAPRED_HOME=${cfg.package}/lib/${cfg.package.untarDir}"; "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; type = types.attrsOf types.anything;
description = ''
Default options for mapred-site.xml
'';
};
mapredSite = mkOption {
default = {};
type = types.attrsOf types.anything;
example = literalExpression '' example = literalExpression ''
options.services.hadoop.mapredSite.default // { {
"mapreduce.map.java.opts" = "-Xmx900m -XX:+UseParallelGC"; "mapreduce.map.java.opts" = "-Xmx900m -XX:+UseParallelGC";
} }
''; '';
description = '' description = ''
Hadoop mapred-site.xml definition Additional options and overrides for mapred-site.xml
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml"/> <link xlink:href="https://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml"/>
''; '';
}; };
yarnSite = mkOption { yarnSiteDefault = mkOption {
default = { default = {
"yarn.nodemanager.admin-env" = "PATH=$PATH"; "yarn.nodemanager.admin-env" = "PATH=$PATH";
"yarn.nodemanager.aux-services" = "mapreduce_shuffle"; "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.linux-container-executor.path" = "/run/wrappers/yarn-nodemanager/bin/container-executor";
"yarn.nodemanager.log-dirs" = "/var/log/hadoop/yarn/nodemanager"; "yarn.nodemanager.log-dirs" = "/var/log/hadoop/yarn/nodemanager";
"yarn.resourcemanager.bind-host" = "0.0.0.0"; "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; type = types.attrsOf types.anything;
description = ''
Default options for yarn-site.xml
'';
};
yarnSite = mkOption {
default = {};
type = types.attrsOf types.anything;
example = literalExpression '' example = literalExpression ''
options.services.hadoop.yarnSite.default // { {
"yarn.resourcemanager.hostname" = "''${config.networking.hostName}"; "yarn.resourcemanager.hostname" = "''${config.networking.hostName}";
} }
''; '';
description = '' description = ''
Hadoop yarn-site.xml definition Additional options and overrides for yarn-site.xml
<link xlink:href="https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-common/yarn-default.xml"/> <link xlink:href="https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-common/yarn-default.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 { httpfsSite = mkOption {
default = { }; default = { };
@ -123,6 +171,7 @@ with lib;
"yarn.nodemanager.linux-container-executor.group"="hadoop"; "yarn.nodemanager.linux-container-executor.group"="hadoop";
"min.user.id"=1000; "min.user.id"=1000;
"feature.terminal.enabled"=1; "feature.terminal.enabled"=1;
"feature.mount-cgroup.enabled" = 1;
}; };
type = types.attrsOf types.anything; type = types.attrsOf types.anything;
example = literalExpression '' example = literalExpression ''
@ -148,6 +197,8 @@ with lib;
description = "Directories containing additional config files to be added to HADOOP_CONF_DIR"; description = "Directories containing additional config files to be added to HADOOP_CONF_DIR";
}; };
gatewayRole.enable = mkEnableOption "gateway role for deploying hadoop configs";
package = mkOption { package = mkOption {
type = types.package; type = types.package;
default = pkgs.hadoop; default = pkgs.hadoop;
@ -157,10 +208,7 @@ with lib;
}; };
config = mkMerge [ config = mkIf cfg.gatewayRole.enable {
(mkIf (builtins.hasAttr "yarn" config.users.users ||
builtins.hasAttr "hdfs" config.users.users ||
builtins.hasAttr "httpfs" config.users.users) {
users.groups.hadoop = { users.groups.hadoop = {
gid = config.ids.gids.hadoop; gid = config.ids.gids.hadoop;
}; };
@ -169,8 +217,7 @@ with lib;
etc."hadoop-conf".source = let etc."hadoop-conf".source = let
hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/"; hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
in "${hadoopConf}"; in "${hadoopConf}";
variables.HADOOP_CONF_DIR = "/etc/hadoop-conf/";
};
}; };
})
];
} }

View file

@ -2,7 +2,13 @@
with lib; with lib;
let let
cfg = config.services.hadoop; cfg = config.services.hadoop;
# Config files for hadoop services
hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/"; hadoopConf = "${import ./conf.nix { inherit cfg pkgs lib; }}/";
# Generator for HDFS service options
hadoopServiceOption = { serviceName, firewallOption ? true, extraOpts ? null }: {
enable = mkEnableOption serviceName;
restartIfChanged = mkOption { restartIfChanged = mkOption {
type = types.bool; type = types.bool;
description = '' description = ''
@ -13,179 +19,173 @@ let
''; '';
default = false; 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 in
{ {
options.services.hadoop.hdfs = { options.services.hadoop.hdfs = {
namenode = {
enable = mkEnableOption "Whether to run the HDFS NameNode"; namenode = hadoopServiceOption { serviceName = "HDFS NameNode"; } // {
formatOnInit = mkOption { formatOnInit = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
description = '' description = ''
Format HDFS namenode on first start. This is useful for quickly spinning up ephemeral HDFS clusters with a single namenode. Format HDFS namenode on first start. This is useful for quickly spinning up
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) ephemeral HDFS clusters with a single namenode.
to initialize an HA cluster manually. For HA clusters, initialization involves multiple steps across multiple nodes.
Follow this guide to initialize an HA cluster manually:
<link xlink:href="https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html"/>
''; '';
}; };
inherit restartIfChanged; };
openFirewall = mkOption {
type = types.bool; datanode = hadoopServiceOption { serviceName = "HDFS DataNode"; } // {
default = true; 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 = '' description = ''
Open firewall ports for namenode Storage types ([SSD]/[DISK]/[ARCHIVE]/[RAM_DISK]) for HDFS storage policies.
''; '';
}; };
}; path = mkOption {
datanode = { type = path;
enable = mkEnableOption "Whether to run the HDFS DataNode"; example = [ "/var/lib/hadoop/hdfs/dn" ];
inherit restartIfChanged; description = "Determines where on the local filesystem a data node should store its blocks.";
openFirewall = mkOption {
type = types.bool;
default = true;
description = ''
Open firewall ports for datanode
'';
}; };
}; };
journalnode = { }));
enable = mkEnableOption "Whether to run the HDFS JournalNode";
inherit restartIfChanged;
openFirewall = mkOption {
type = types.bool;
default = true;
description = ''
Open firewall ports for journalnode
'';
}; };
}; };
zkfc = {
enable = mkEnableOption "Whether to run the HDFS ZooKeeper failover controller"; journalnode = hadoopServiceOption { serviceName = "HDFS JournalNode"; };
inherit restartIfChanged;
zkfc = hadoopServiceOption {
serviceName = "HDFS ZooKeeper failover controller";
firewallOption = false;
}; };
httpfs = {
enable = mkEnableOption "Whether to run the HDFS HTTPfs server"; httpfs = hadoopServiceOption { serviceName = "HDFS JournalNode"; } // {
tempPath = mkOption { tempPath = mkOption {
type = types.path; type = types.path;
default = "/tmp/hadoop/httpfs"; default = "/tmp/hadoop/httpfs";
description = '' description = "HTTPFS_TEMP path used by HTTPFS";
HTTPFS_TEMP path used by HTTPFS
'';
};
inherit restartIfChanged;
openFirewall = mkOption {
type = types.bool;
default = true;
description = ''
Open firewall ports for HTTPFS
'';
}; };
}; };
}; };
config = mkMerge [ config = mkMerge [
(mkIf cfg.hdfs.namenode.enable { (hadoopServiceConfig {
systemd.services.hdfs-namenode = { name = "NameNode";
description = "Hadoop HDFS NameNode"; allowedTCPPorts = [
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 [
9870 # namenode.http-address 9870 # namenode.http-address
8020 # namenode.rpc-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 = { (hadoopServiceConfig {
User = "hdfs"; name = "DataNode";
SyslogIdentifier = "hdfs-datanode"; # port numbers for datanode changed between hadoop 2 and 3
ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} datanode"; allowedTCPPorts = if versionAtLeast cfg.package.version "3" then [
Restart = "always";
};
};
networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.datanode.openFirewall [
9864 # datanode.http.address 9864 # datanode.http.address
9866 # datanode.address 9866 # datanode.address
9867 # datanode.ipc.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 = { (hadoopServiceConfig {
User = "hdfs"; name = "JournalNode";
SyslogIdentifier = "hdfs-journalnode"; allowedTCPPorts = [
ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} journalnode";
Restart = "always";
};
};
networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.journalnode.openFirewall [
8480 # dfs.journalnode.http-address 8480 # dfs.journalnode.http-address
8485 # dfs.journalnode.rpc-address 8485 # dfs.journalnode.rpc-address
]); ];
}) })
(mkIf cfg.hdfs.zkfc.enable {
systemd.services.hdfs-zkfc = { (hadoopServiceConfig {
name = "zkfc";
description = "Hadoop HDFS ZooKeeper failover controller"; 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";
};
};
}) })
(mkIf cfg.hdfs.httpfs.enable {
systemd.services.hdfs-httpfs = {
description = "Hadoop httpfs";
wantedBy = [ "multi-user.target" ];
inherit (cfg.hdfs.httpfs) restartIfChanged;
(hadoopServiceConfig {
name = "HTTPFS";
environment.HTTPFS_TEMP = cfg.hdfs.httpfs.tempPath; environment.HTTPFS_TEMP = cfg.hdfs.httpfs.tempPath;
preStart = "mkdir -p $HTTPFS_TEMP";
preStart = ''
mkdir -p $HTTPFS_TEMP
'';
serviceConfig = {
User = "httpfs"; User = "httpfs";
SyslogIdentifier = "hdfs-httpfs"; allowedTCPPorts = [
ExecStart = "${cfg.package}/bin/hdfs --config ${hadoopConf} httpfs";
Restart = "always";
};
};
networking.firewall.allowedTCPPorts = (mkIf cfg.hdfs.httpfs.openFirewall [
14000 # httpfs.http.port 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 = { users.users.hdfs = {
description = "Hadoop HDFS user"; description = "Hadoop HDFS user";
group = "hadoop"; group = "hadoop";
@ -199,5 +199,6 @@ in
isSystemUser = true; isSystemUser = true;
}; };
}) })
]; ];
} }

View file

@ -13,23 +13,77 @@ let
''; '';
default = false; 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 in
{ {
options.services.hadoop.yarn = { options.services.hadoop.yarn = {
resourcemanager = { resourcemanager = {
enable = mkEnableOption "Whether to run the Hadoop YARN ResourceManager"; enable = mkEnableOption "Hadoop YARN ResourceManager";
inherit restartIfChanged; inherit restartIfChanged extraFlags extraEnv;
openFirewall = mkOption { openFirewall = mkOption {
type = types.bool; type = types.bool;
default = true; default = false;
description = '' description = ''
Open firewall ports for resourcemanager Open firewall ports for resourcemanager
''; '';
}; };
}; };
nodemanager = { nodemanager = {
enable = mkEnableOption "Whether to run the Hadoop YARN NodeManager"; enable = mkEnableOption "Hadoop YARN NodeManager";
inherit restartIfChanged; 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 { addBinBash = mkOption {
type = types.bool; type = types.bool;
default = true; default = true;
@ -39,7 +93,7 @@ in
}; };
openFirewall = mkOption { openFirewall = mkOption {
type = types.bool; type = types.bool;
default = true; default = false;
description = '' description = ''
Open firewall ports for nodemanager. Open firewall ports for nodemanager.
Because containers can listen on any ephemeral port, TCP ports 102465535 will be opened. Because containers can listen on any ephemeral port, TCP ports 102465535 will be opened.
@ -49,10 +103,7 @@ in
}; };
config = mkMerge [ config = mkMerge [
(mkIf ( (mkIf cfg.gatewayRole.enable {
cfg.yarn.resourcemanager.enable || cfg.yarn.nodemanager.enable
) {
users.users.yarn = { users.users.yarn = {
description = "Hadoop YARN user"; description = "Hadoop YARN user";
group = "hadoop"; group = "hadoop";
@ -65,15 +116,19 @@ in
description = "Hadoop YARN ResourceManager"; description = "Hadoop YARN ResourceManager";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
inherit (cfg.yarn.resourcemanager) restartIfChanged; inherit (cfg.yarn.resourcemanager) restartIfChanged;
environment = cfg.yarn.resourcemanager.extraEnv;
serviceConfig = { serviceConfig = {
User = "yarn"; User = "yarn";
SyslogIdentifier = "yarn-resourcemanager"; SyslogIdentifier = "yarn-resourcemanager";
ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " + ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " +
" resourcemanager"; " resourcemanager ${escapeShellArgs cfg.yarn.resourcemanager.extraFlags}";
Restart = "always"; Restart = "always";
}; };
}; };
services.hadoop.gatewayRole.enable = true;
networking.firewall.allowedTCPPorts = (mkIf cfg.yarn.resourcemanager.openFirewall [ networking.firewall.allowedTCPPorts = (mkIf cfg.yarn.resourcemanager.openFirewall [
8088 # resourcemanager.webapp.address 8088 # resourcemanager.webapp.address
8030 # resourcemanager.scheduler.address 8030 # resourcemanager.scheduler.address
@ -94,6 +149,7 @@ in
description = "Hadoop YARN NodeManager"; description = "Hadoop YARN NodeManager";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
inherit (cfg.yarn.nodemanager) restartIfChanged; inherit (cfg.yarn.nodemanager) restartIfChanged;
environment = cfg.yarn.nodemanager.extraEnv;
preStart = '' preStart = ''
# create log dir # create log dir
@ -101,8 +157,9 @@ in
chown yarn:hadoop /var/log/hadoop/yarn/nodemanager chown yarn:hadoop /var/log/hadoop/yarn/nodemanager
# set up setuid container executor binary # set up setuid container executor binary
umount /run/wrappers/yarn-nodemanager/cgroup/cpu || true
rm -rf /run/wrappers/yarn-nodemanager/ || 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/ cp ${cfg.package}/lib/${cfg.package.untarDir}/bin/container-executor /run/wrappers/yarn-nodemanager/bin/
chgrp hadoop /run/wrappers/yarn-nodemanager/bin/container-executor chgrp hadoop /run/wrappers/yarn-nodemanager/bin/container-executor
chmod 6050 /run/wrappers/yarn-nodemanager/bin/container-executor chmod 6050 /run/wrappers/yarn-nodemanager/bin/container-executor
@ -114,11 +171,26 @@ in
SyslogIdentifier = "yarn-nodemanager"; SyslogIdentifier = "yarn-nodemanager";
PermissionsStartOnly = true; PermissionsStartOnly = true;
ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " + ExecStart = "${cfg.package}/bin/yarn --config ${hadoopConf} " +
" nodemanager"; " nodemanager ${escapeShellArgs cfg.yarn.nodemanager.extraFlags}";
Restart = "always"; 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 = [ networking.firewall.allowedTCPPortRanges = [
(mkIf (cfg.yarn.nodemanager.openFirewall) {from = 1024; to = 65535;}) (mkIf (cfg.yarn.nodemanager.openFirewall) {from = 1024; to = 65535;})
]; ];

View file

@ -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";
};
};
};
}

View file

@ -64,7 +64,7 @@ in {
description = "Factory Steps"; description = "Factory Steps";
default = []; default = [];
example = [ 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'])" "steps.ShellCommand(command=['trial', 'pyflakes'])"
]; ];
}; };
@ -74,7 +74,7 @@ in {
description = "List of Change Sources."; description = "List of Change Sources.";
default = []; default = [];
example = [ 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)"
]; ];
}; };

Some files were not shown because too many files have changed in this diff Show more