Merge commit '87d34a6b8982e901b8e50096b8e79ebc0e66cda0'

main
Katharina Fey 2 years ago
commit ea8493798b
Signed by: kookie
GPG Key ID: F972AEEA2887D547
  1. 79
      infra/libkookie/nixpkgs/unstable/.github/CODEOWNERS
  2. 6
      infra/libkookie/nixpkgs/unstable/.github/workflows/backport.yml
  3. 19
      infra/libkookie/nixpkgs/unstable/.github/workflows/basic-eval.yml
  4. 2
      infra/libkookie/nixpkgs/unstable/.github/workflows/direct-push.yml
  5. 2
      infra/libkookie/nixpkgs/unstable/.github/workflows/editorconfig.yml
  6. 5
      infra/libkookie/nixpkgs/unstable/.github/workflows/labels.yml
  7. 2
      infra/libkookie/nixpkgs/unstable/.github/workflows/manual-nixos.yml
  8. 2
      infra/libkookie/nixpkgs/unstable/.github/workflows/manual-nixpkgs.yml
  9. 2
      infra/libkookie/nixpkgs/unstable/.github/workflows/nixos-manual.yml
  10. 5
      infra/libkookie/nixpkgs/unstable/.github/workflows/pending-set.yml
  11. 2
      infra/libkookie/nixpkgs/unstable/.github/workflows/periodic-merge-24h.yml
  12. 2
      infra/libkookie/nixpkgs/unstable/.github/workflows/periodic-merge-6h.yml
  13. 4
      infra/libkookie/nixpkgs/unstable/.github/workflows/update-terraform-providers.yml
  14. 43
      infra/libkookie/nixpkgs/unstable/CONTRIBUTING.md
  15. 6
      infra/libkookie/nixpkgs/unstable/doc/builders/fetchers.chapter.md
  16. 1
      infra/libkookie/nixpkgs/unstable/doc/builders/special.xml
  17. 31
      infra/libkookie/nixpkgs/unstable/doc/builders/special/invalidateFetcherByDrvHash.section.md
  18. 82
      infra/libkookie/nixpkgs/unstable/doc/builders/testers.chapter.md
  19. 15
      infra/libkookie/nixpkgs/unstable/doc/contributing/coding-conventions.chapter.md
  20. 6
      infra/libkookie/nixpkgs/unstable/doc/contributing/reviewing-contributions.chapter.md
  21. 10
      infra/libkookie/nixpkgs/unstable/doc/hooks/index.xml
  22. 59
      infra/libkookie/nixpkgs/unstable/doc/hooks/postgresql-test-hook.section.md
  23. 49
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/chicken.section.md
  24. 34
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/cuda.section.md
  25. 18
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/gnome.section.md
  26. 6
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/go.section.md
  27. 2
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/index.xml
  28. 26
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/javascript.section.md
  29. 10
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/ocaml.section.md
  30. 2
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/texlive.section.md
  31. 7
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/vim.section.md
  32. 2
      infra/libkookie/nixpkgs/unstable/doc/manual.xml
  33. 45
      infra/libkookie/nixpkgs/unstable/doc/stdenv/cross-compilation.chapter.md
  34. 4
      infra/libkookie/nixpkgs/unstable/doc/stdenv/stdenv.chapter.md
  35. 51
      infra/libkookie/nixpkgs/unstable/lib/customisation.nix
  36. 12
      infra/libkookie/nixpkgs/unstable/lib/default.nix
  37. 49
      infra/libkookie/nixpkgs/unstable/lib/generators.nix
  38. 10
      infra/libkookie/nixpkgs/unstable/lib/licenses.nix
  39. 150
      infra/libkookie/nixpkgs/unstable/lib/modules.nix
  40. 4
      infra/libkookie/nixpkgs/unstable/lib/options.nix
  41. 141
      infra/libkookie/nixpkgs/unstable/lib/strings.nix
  42. 2
      infra/libkookie/nixpkgs/unstable/lib/systems/platforms.nix
  43. 219
      infra/libkookie/nixpkgs/unstable/lib/tests/misc.nix
  44. 59
      infra/libkookie/nixpkgs/unstable/lib/trivial.nix
  45. 8
      infra/libkookie/nixpkgs/unstable/lib/types.nix
  46. 259
      infra/libkookie/nixpkgs/unstable/maintainers/maintainer-list.nix
  47. 2
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/dep-licenses.sh
  48. 98
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/feature-freeze-teams.pl
  49. 22
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/haskell/maintained-broken-pkgs.nix
  50. 2
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/haskell/merge-and-open-pr.sh
  51. 37
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/haskell/update-stackage.sh
  52. 2
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/luarocks-packages.csv
  53. 187
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/pluginupdate.py
  54. 21
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/remove-old-aliases.py
  55. 323
      infra/libkookie/nixpkgs/unstable/maintainers/team-list.nix
  56. 4
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/default.nix
  57. 1
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/development/development.xml
  58. 4
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/development/option-declarations.section.md
  59. 14
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/development/settings-options.section.md
  60. 88
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/development/writing-nixos-tests.section.md
  61. 4
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/development/option-declarations.section.xml
  62. 32
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/development/settings-options.section.xml
  63. 151
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/development/writing-nixos-tests.section.xml
  64. 34
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/installation/building-nixos.chapter.xml
  65. 2
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/installation/installing-usb.section.xml
  66. 14
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/installation/installing.chapter.xml
  67. 8
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/release-notes/rl-1803.section.xml
  68. 771
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
  69. 31
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/installation/building-nixos.chapter.md
  70. 1
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/installation/installation.xml
  71. 2
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/installation/installing-usb.section.md
  72. 10
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/installation/installing.chapter.md
  73. 26
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/man-nixos-rebuild.xml
  74. 9
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/man-pages.xml
  75. 2
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/md-to-db.sh
  76. 2
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/release-notes/rl-1803.section.md
  77. 273
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/release-notes/rl-2205.section.md
  78. 1
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-disk-image.nix
  79. 0
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-multi-disk-zfs-image.nix
  80. 4
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-options-doc/mergeJSON.py
  81. 322
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-single-disk-zfs-image.nix
  82. 4
      infra/libkookie/nixpkgs/unstable/nixos/lib/qemu-common.nix
  83. 94
      infra/libkookie/nixpkgs/unstable/nixos/lib/systemd-lib.nix
  84. 37
      infra/libkookie/nixpkgs/unstable/nixos/lib/systemd-types.nix
  85. 961
      infra/libkookie/nixpkgs/unstable/nixos/lib/systemd-unit-options.nix
  86. 3
      infra/libkookie/nixpkgs/unstable/nixos/lib/test-driver/test_driver/driver.py
  87. 8
      infra/libkookie/nixpkgs/unstable/nixos/lib/test-driver/test_driver/logger.py
  88. 41
      infra/libkookie/nixpkgs/unstable/nixos/lib/test-driver/test_driver/machine.py
  89. 31
      infra/libkookie/nixpkgs/unstable/nixos/lib/testing-python.nix
  90. 17
      infra/libkookie/nixpkgs/unstable/nixos/lib/utils.nix
  91. 2
      infra/libkookie/nixpkgs/unstable/nixos/maintainers/scripts/ec2/amazon-image.nix
  92. 101
      infra/libkookie/nixpkgs/unstable/nixos/maintainers/scripts/openstack/openstack-image-zfs.nix
  93. 17
      infra/libkookie/nixpkgs/unstable/nixos/maintainers/scripts/openstack/openstack-image.nix
  94. 31
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/console.nix
  95. 11
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/nsswitch.nix
  96. 6
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/resolvconf.nix
  97. 26
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/terminfo.nix
  98. 3
      infra/libkookie/nixpkgs/unstable/nixos/modules/hardware/video/amdgpu-pro.nix
  99. 27
      infra/libkookie/nixpkgs/unstable/nixos/modules/hardware/video/nvidia.nix
  100. 5
      infra/libkookie/nixpkgs/unstable/nixos/modules/hardware/video/webcam/facetimehd.nix
  101. Some files were not shown because too many files have changed in this diff Show More

@ -10,9 +10,6 @@
# IMPORTANT NOTE: in order to actually get pinged, commit access is required.
# This also holds true for GitHub teams. Since almost none of our teams have write
# permissions, you need to list all members of the team with commit access individually.
# We still add the team to the list next to its members, this helps keeping things
# in sync. (Put non team members before the team to distinguish them.)
# See https://github.com/NixOS/nixpkgs/issues/124085 for more details
# This file
/.github/CODEOWNERS @edolstra
@ -39,12 +36,13 @@
/pkgs/top-level/stage.nix @nbp @Ericson2314 @matthewbauer
/pkgs/top-level/splice.nix @Ericson2314 @matthewbauer
/pkgs/top-level/release-cross.nix @Ericson2314 @matthewbauer
/pkgs/stdenv/generic @Ericson2314 @matthewbauer @cab404
/pkgs/stdenv/generic @Ericson2314 @matthewbauer
/pkgs/stdenv/cross @Ericson2314 @matthewbauer
/pkgs/build-support/cc-wrapper @Ericson2314 @orivej
/pkgs/build-support/bintools-wrapper @Ericson2314 @orivej
/pkgs/build-support/cc-wrapper @Ericson2314
/pkgs/build-support/bintools-wrapper @Ericson2314
/pkgs/build-support/setup-hooks @Ericson2314
/pkgs/build-support/setup-hooks/auto-patchelf.sh @aszlig
/pkgs/build-support/setup-hooks/auto-patchelf.sh @layus
/pkgs/build-support/setup-hooks/auto-patchelf.py @layus
# Nixpkgs build-support
/pkgs/build-support/writers @lassulus @Profpatsch
@ -77,6 +75,12 @@
# NixOS integration test driver
/nixos/lib/test-driver @tfc
# Systemd
/nixos/modules/system/boot/systemd.nix @NixOS/systemd
/nixos/modules/system/boot/systemd @NixOS/systemd
/nixos/lib/systemd-*.nix @NixOS/systemd
/pkgs/os-specific/linux/systemd @NixOS/systemd
# Updaters
## update.nix
/maintainers/scripts/update.nix @jtojnar
@ -91,8 +95,7 @@
/pkgs/development/python-modules @FRidh @jonringer
/doc/languages-frameworks/python.section.md @FRidh
/pkgs/development/tools/poetry2nix @adisbladis
/pkgs/development/interpreters/python/hooks @FRidh @jonringer @DavHau
/pkgs/development/interpreters/python/conda @DavHau
/pkgs/development/interpreters/python/hooks @FRidh @jonringer
# Haskell
/doc/languages-frameworks/haskell.section.md @cdepillabout @sternenseemann @maralorn @expipiplus1
@ -109,8 +112,8 @@
/pkgs/development/perl-modules @stigtsp @zakame
# R
/pkgs/applications/science/math/R @jbedo @bcdarwin
/pkgs/development/r-modules @jbedo @bcdarwin
/pkgs/applications/science/math/R @jbedo
/pkgs/development/r-modules @jbedo
# Ruby
/pkgs/development/interpreters/ruby @marsam
@ -121,10 +124,6 @@
/pkgs/build-support/rust @zowoq
/doc/languages-frameworks/rust.section.md @zowoq
# Darwin-related
/pkgs/stdenv/darwin @NixOS/darwin-maintainers
/pkgs/os-specific/darwin @NixOS/darwin-maintainers
# C compilers
/pkgs/development/compilers/gcc @matthewbauer
/pkgs/development/compilers/llvm @matthewbauer
@ -133,15 +132,6 @@
/pkgs/top-level/unix-tools.nix @matthewbauer
/pkgs/development/tools/xcbuild @matthewbauer
# Beam-related (Erlang, Elixir, LFE, etc)
/pkgs/development/beam-modules @gleber
/pkgs/development/interpreters/erlang @gleber
/pkgs/development/interpreters/lfe @gleber
/pkgs/development/interpreters/elixir @gleber
/pkgs/development/tools/build-managers/rebar @gleber
/pkgs/development/tools/build-managers/rebar3 @gleber
/pkgs/development/tools/erlang @gleber
# Audio
/nixos/modules/services/audio/botamusique.nix @mweinelt
/nixos/modules/services/audio/snapserver.nix @mweinelt
@ -209,7 +199,7 @@
/pkgs/development/idris-modules @Infinisil
# Bazel
/pkgs/development/tools/build-managers/bazel @mboes @Profpatsch
/pkgs/development/tools/build-managers/bazel @Profpatsch
# NixOS modules for e-mail and dns services
/nixos/modules/services/mail/mailman.nix @peti
@ -237,25 +227,24 @@
/nixos/tests/prometheus-exporters.nix @WilliButz
# PHP interpreter, packages, extensions, tests and documentation
/doc/languages-frameworks/php.section.md @NixOS/php @aanderse @etu @globin @ma27 @talyz
/nixos/tests/php @NixOS/php @aanderse @etu @globin @ma27 @talyz
/pkgs/build-support/build-pecl.nix @NixOS/php @aanderse @etu @globin @ma27 @talyz
/pkgs/development/interpreters/php @jtojnar @NixOS/php @aanderse @etu @globin @ma27 @talyz
/pkgs/development/php-packages @NixOS/php @aanderse @etu @globin @ma27 @talyz
/pkgs/top-level/php-packages.nix @jtojnar @NixOS/php @aanderse @etu @globin @ma27 @talyz
/doc/languages-frameworks/php.section.md @aanderse @etu @globin @ma27 @talyz
/nixos/tests/php @aanderse @etu @globin @ma27 @talyz
/pkgs/build-support/build-pecl.nix @aanderse @etu @globin @ma27 @talyz
/pkgs/development/interpreters/php @jtojnar @aanderse @etu @globin @ma27 @talyz
/pkgs/development/php-packages @aanderse @etu @globin @ma27 @talyz
/pkgs/top-level/php-packages.nix @jtojnar @aanderse @etu @globin @ma27 @talyz
# Podman, CRI-O modules and related
/nixos/modules/virtualisation/containers.nix @NixOS/podman @zowoq @adisbladis
/nixos/modules/virtualisation/cri-o.nix @NixOS/podman @zowoq @adisbladis
/nixos/modules/virtualisation/podman @NixOS/podman @zowoq @adisbladis
/nixos/tests/cri-o.nix @NixOS/podman @zowoq @adisbladis
/nixos/tests/podman @NixOS/podman @zowoq @adisbladis
/nixos/modules/virtualisation/containers.nix @zowoq @adisbladis
/nixos/modules/virtualisation/cri-o.nix @zowoq @adisbladis
/nixos/modules/virtualisation/podman @zowoq @adisbladis
/nixos/tests/cri-o.nix @zowoq @adisbladis
/nixos/tests/podman @zowoq @adisbladis
# Docker tools
/pkgs/build-support/docker @roberth @utdemir
/nixos/tests/docker-tools-overlay.nix @roberth
/nixos/tests/docker-tools.nix @roberth
/doc/builders/images/dockertools.xml @roberth
/pkgs/build-support/docker @roberth
/nixos/tests/docker-tools* @roberth
/doc/builders/images/dockertools.section.md @roberth
# Blockchains
/pkgs/applications/blockchains @mmahut @RaghavSood
@ -267,8 +256,8 @@
/pkgs/development/go-packages @kalbasit @Mic92 @zowoq
# GNOME
/pkgs/desktops/gnome @NixOS/GNOME @jtojnar @hedning
/pkgs/desktops/gnome/extensions @piegamesde @NixOS/GNOME @jtojnar @hedning
/pkgs/desktops/gnome @jtojnar @hedning
/pkgs/desktops/gnome/extensions @piegamesde @jtojnar @hedning
# Cinnamon
/pkgs/desktops/cinnamon @mkg20001
@ -289,10 +278,10 @@
# Matrix
/pkgs/servers/heisenbridge @piegamesde
/pkgs/servers/matrix-conduit @piegamesde @pstn
/pkgs/servers/matrix-conduit @piegamesde
/pkgs/servers/matrix-synapse/matrix-appservice-irc @piegamesde
/nixos/modules/services/misc/heisenbridge.nix @piegamesde
/nixos/modules/services/misc/matrix-appservice-irc.nix @piegamesde
/nixos/modules/services/misc/matrix-conduit.nix @piegamesde @pstn
/nixos/modules/services/misc/matrix-conduit.nix @piegamesde
/nixos/tests/matrix-appservice-irc.nix @piegamesde
/nixos/tests/matrix-conduit.nix @piegamesde @pstn
/nixos/tests/matrix-conduit.nix @piegamesde

@ -2,6 +2,12 @@ name: Backport
on:
pull_request_target:
types: [closed, labeled]
# WARNING:
# When extending this action, be aware that $GITHUB_TOKEN allows write access to
# the GitHub repository. This means that it should not evaluate user input in a
# way that allows code injection.
jobs:
backport:
name: Backport Pull Request

@ -1,21 +1,22 @@
name: Basic evaluation checks
on:
pull_request:
branches:
- master
- release-**
push:
branches:
- master
- release-**
workflow_dispatch
# pull_request:
# branches:
# - master
# - release-**
# push:
# branches:
# - master
# - release-**
jobs:
tests:
runs-on: ubuntu-latest
# we don't limit this action to only NixOS repo since the checks are cheap and useful developer feedback
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v16
- uses: cachix/install-nix-action@v17
- uses: cachix/cachix-action@v10
with:
# This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.

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

@ -28,7 +28,7 @@ jobs:
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- uses: cachix/install-nix-action@v16
- uses: cachix/install-nix-action@v17
with:
# nixpkgs commit is pinned so that it doesn't break
# editorconfig-checker 2.4.0

@ -4,6 +4,11 @@ on:
pull_request_target:
types: [edited, opened, synchronize, reopened]
# WARNING:
# When extending this action, be aware that $GITHUB_TOKEN allows some write
# access to the GitHub API. This means that it should not evaluate user input in
# a way that allows code injection.
permissions:
contents: read
pull-requests: write

@ -18,7 +18,7 @@ jobs:
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- uses: cachix/install-nix-action@v16
- uses: cachix/install-nix-action@v17
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true

@ -18,7 +18,7 @@ jobs:
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- uses: cachix/install-nix-action@v16
- uses: cachix/install-nix-action@v17
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true

@ -19,7 +19,7 @@ jobs:
with:
# pull_request_target checks out the base branch by default
ref: refs/pull/${{ github.event.pull_request.number }}/merge
- uses: cachix/install-nix-action@v16
- uses: cachix/install-nix-action@v17
- name: Check DocBook files generated from Markdown are consistent
run: |
nixos/doc/manual/md-to-db.sh

@ -3,6 +3,11 @@ name: "set pending status"
on:
pull_request_target:
# WARNING:
# When extending this action, be aware that $GITHUB_TOKEN allows write access to
# the GitHub repository. This means that it should not evaluate user input in a
# way that allows code injection.
jobs:
action:
runs-on: ubuntu-latest

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

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

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v16
- uses: cachix/install-nix-action@v17
- name: setup
id: setup
run: |
@ -39,7 +39,7 @@ jobs:
title: ${{ steps.setup.outputs.title }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: comment on failure
uses: peter-evans/create-or-update-comment@v1
uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }}
with:
issue-number: 153416

@ -20,7 +20,7 @@ Below is a short excerpt of some points in there:
```
(pkg-name | nixos/<module>): (from -> to | init at version | refactor | etc)
(Motivation for change. Additional information.)
(Motivation for change. Link to release notes. Additional information.)
```
For consistency, there should not be a period at the end of the commit message's summary line (the first line of the commit message).
@ -29,6 +29,7 @@ Below is a short excerpt of some points in there:
* nginx: init at 2.0.1
* firefox: 54.0.1 -> 55.0
https://www.mozilla.org/en-US/firefox/55.0/releasenotes/
* nixos/hydra: add bazBaz option
Dual baz behavior is needed to do foo.
@ -52,6 +53,46 @@ In addition to writing properly formatted commit messages, it's important to inc
For package version upgrades and such a one-line commit message is usually sufficient.
## Rebasing between branches (i.e. from master to staging)
From time to time, changes between branches must be rebased, for example, if the
number of new rebuilds they would cause is too large for the target branch. When
rebasing, care must be taken to include only the intended changes, otherwise
many CODEOWNERS will be inadvertently requested for review. To achieve this,
rebasing should not be performed directly on the target branch, but on the merge
base between the current and target branch.
In the following example, we see a rebase from `master` onto the merge base
between `master` and `staging`, so that a change can eventually be retargeted to
`staging`. The example uses `upstream` as the remote for `NixOS/nixpkgs.git`
while the `origin` remote is used for the remote you are pushing to.
```console
# Find the common base between two branches
common=$(git merge-base upstream/master upstream/staging)
# Find the common base between your feature branch and master
commits=$(git merge-base $(git branch --show-current) upstream/master)
# Rebase all commits onto the common base
git rebase --onto=$common $commits
# Force push your changes
git push origin $(git branch --show-current) --force-with-lease
```
Then change the base branch in the GitHub PR using the *Edit* button in the upper
right corner, and switch from `master` to `staging`. After the PR has been
retargeted it might be necessary to do a final rebase onto the target branch, to
resolve any outstanding merge conflicts.
```console
# Rebase onto target branch
git rebase upstream/staging
# Review and fixup possible conflicts
git status
# Force push your changes
git push origin $(git branch --show-current) --force-with-lease
```
## Backporting changes
Follow these steps to backport a change into a release branch in compliance with the [commit policy](https://nixos.org/nixpkgs/manual/#submitting-changes-stable-release-branches).

@ -6,7 +6,7 @@ When using Nix, you will frequently need to download source code and other files
Because fixed output derivations are _identified_ by their hash, a common mistake is to update a fetcher's URL or a version parameter, without updating the hash. **This will cause the old contents to be used.** So remember to always invalidate the hash argument.
For those who develop and maintain fetchers, a similar problem arises with changes to the implementation of a fetcher. These may cause a fixed output derivation to fail, but won't normally be caught by tests because the supposed output is already in the store or cache. For the purpose of testing, you can use a trick that is embodied by the [`invalidateFetcherByDrvHash`](#sec-pkgs-invalidateFetcherByDrvHash) function. It uses the derivation `name` to create a unique output path per fetcher implementation, defeating the caching precisely where it would be harmful.
For those who develop and maintain fetchers, a similar problem arises with changes to the implementation of a fetcher. These may cause a fixed output derivation to fail, but won't normally be caught by tests because the supposed output is already in the store or cache. For the purpose of testing, you can use a trick that is embodied by the [`invalidateFetcherByDrvHash`](#tester-invalidateFetcherByDrvHash) function. It uses the derivation `name` to create a unique output path per fetcher implementation, defeating the caching precisely where it would be harmful.
## `fetchurl` and `fetchzip` {#fetchurl}
@ -72,6 +72,10 @@ Used with Mercurial. Expects `url`, `rev`, and `sha256`.
A number of fetcher functions wrap part of `fetchurl` and `fetchzip`. They are mainly convenience functions intended for commonly used destinations of source code in Nixpkgs. These wrapper fetchers are listed below.
## `fetchFromGitea` {#fetchfromgitea}
`fetchFromGitea` expects five arguments. `domain` is the gitea server name. `owner` is a string corresponding to the Gitea user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every Gitea HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. Finally, `sha256` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available but `sha256` is currently preferred.
## `fetchFromGitHub` {#fetchfromgithub}
`fetchFromGitHub` expects four arguments. `owner` is a string corresponding to the GitHub user or organization that controls this repository. `repo` corresponds to the name of the software repository. These are located at the top of every GitHub HTML page as `owner`/`repo`. `rev` corresponds to the Git commit hash or tag (e.g `v1.0`) that will be downloaded from Git. Finally, `sha256` corresponds to the hash of the extracted directory. Again, other hash algorithms are also available but `sha256` is currently preferred.

@ -7,5 +7,4 @@
</para>
<xi:include href="special/fhs-environments.section.xml" />
<xi:include href="special/mkshell.section.xml" />
<xi:include href="special/invalidateFetcherByDrvHash.section.xml" />
</chapter>

@ -1,31 +0,0 @@
## `invalidateFetcherByDrvHash` {#sec-pkgs-invalidateFetcherByDrvHash}
Use the derivation hash to invalidate the output via name, for testing.
Type: `(a@{ name, ... } -> Derivation) -> a -> Derivation`
Normally, fixed output derivations can and should be cached by their output
hash only, but for testing we want to re-fetch everytime the fetcher changes.
Changes to the fetcher become apparent in the drvPath, which is a hash of
how to fetch, rather than a fixed store path.
By inserting this hash into the name, we can make sure to re-run the fetcher
every time the fetcher changes.
This relies on the assumption that Nix isn't clever enough to reuse its
database of local store contents to optimize fetching.
You might notice that the "salted" name derives from the normal invocation,
not the final derivation. `invalidateFetcherByDrvHash` has to invoke the fetcher
function twice: once to get a derivation hash, and again to produce the final
fixed output derivation.
Example:
tests.fetchgit = invalidateFetcherByDrvHash fetchgit {
name = "nix-source";
url = "https://github.com/NixOS/nix";
rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
sha256 = "sha256-7DszvbCNTjpzGRmpIVAWXk20P0/XTrWZ79KSOGLrUWY=";
};

@ -0,0 +1,82 @@
# Testers {#chap-testers}
This chapter describes several testing builders which are available in the <literal>testers</literal> namespace.
## `testVersion` {#tester-testVersion}
Checks the command output contains the specified version
Although simplistic, this test assures that the main program
can run. While there's no substitute for a real test case,
it does catch dynamic linking errors and such. It also provides
some protection against accidentally building the wrong version,
for example when using an 'old' hash in a fixed-output derivation.
Examples:
```nix
passthru.tests.version = testVersion { package = hello; };
passthru.tests.version = testVersion {
package = seaweedfs;
command = "weed version";
};
passthru.tests.version = testVersion {
package = key;
command = "KeY --help";
# Wrong '2.5' version in the code. Drop on next version.
version = "2.5";
};
```
## `testEqualDerivation` {#tester-testEqualDerivation}
Checks that two packages produce the exact same build instructions.
This can be used to make sure that a certain difference of configuration,
such as the presence of an overlay does not cause a cache miss.
When the derivations are equal, the return value is an empty file.
Otherwise, the build log explains the difference via `nix-diff`.
Example:
```nix
testEqualDerivation
"The hello package must stay the same when enabling checks."
hello
(hello.overrideAttrs(o: { doCheck = true; }))
```
## `invalidateFetcherByDrvHash` {#tester-invalidateFetcherByDrvHash}
Use the derivation hash to invalidate the output via name, for testing.
Type: `(a@{ name, ... } -> Derivation) -> a -> Derivation`
Normally, fixed output derivations can and should be cached by their output
hash only, but for testing we want to re-fetch everytime the fetcher changes.
Changes to the fetcher become apparent in the drvPath, which is a hash of
how to fetch, rather than a fixed store path.
By inserting this hash into the name, we can make sure to re-run the fetcher
every time the fetcher changes.
This relies on the assumption that Nix isn't clever enough to reuse its
database of local store contents to optimize fetching.
You might notice that the "salted" name derives from the normal invocation,
not the final derivation. `invalidateFetcherByDrvHash` has to invoke the fetcher
function twice: once to get a derivation hash, and again to produce the final
fixed output derivation.
Example:
```nix
tests.fetchgit = invalidateFetcherByDrvHash fetchgit {
name = "nix-source";
url = "https://github.com/NixOS/nix";
rev = "9d9dbe6ed05854e03811c361a3380e09183f4f4a";
sha256 = "sha256-7DszvbCNTjpzGRmpIVAWXk20P0/XTrWZ79KSOGLrUWY=";
};
```

@ -214,15 +214,15 @@ Most of the time, these are the same. For instance, the package `e2fsprogs` has
There are a few naming guidelines:
- The `name` attribute _should_ be identical to the upstream package name.
- The `pname` attribute _should_ be identical to the upstream package name.
- The `name` attribute _must not_ contain uppercase letters — e.g., `"mplayer-1.0rc2"` instead of `"MPlayer-1.0rc2"`.
- The `pname` and the `version` attribute _must not_ contain uppercase letters — e.g., `"mplayer" instead of `"MPlayer"`.
- The version part of the `name` attribute _must_ start with a digit (following a dash) — e.g., `"hello-0.3.1rc2"`.
- The `version` attribute _must_ start with a digit e.g`"0.3.1rc2".
- If a package is not a release but a commit from a repository, then the version part of the name _must_ be the date of that (fetched) commit. The date _must_ be in `"YYYY-MM-DD"` format. Also append `"unstable"` to the name - e.g., `"pkgname-unstable-2014-09-23"`.
- If a package is not a release but a commit from a repository, then the `version` attribute _must_ be the date of that (fetched) commit. The date _must_ be in `"unstable-YYYY-MM-DD"` format.
- Dashes in the package name _should_ be preserved in new variable names, rather than converted to underscores or camel cased — e.g., `http-parser` instead of `http_parser` or `httpParser`. The hyphenated style is preferred in all three package names.
- Dashes in the package `pname` _should_ be preserved in new variable names, rather than converted to underscores or camel cased — e.g., `http-parser` instead of `http_parser` or `httpParser`. The hyphenated style is preferred in all three package names.
- If there are multiple versions of a package, this _should_ be reflected in the variable names in `all-packages.nix`, e.g. `json-c_0_9` and `json-c_0_11`. If there is an obvious “default” version, make an attribute like `json-c = json-c_0_9;`. See also [](#sec-versioning)
@ -540,10 +540,11 @@ If you do need to do create this sort of patch file, one way to do so is with gi
If a patch is available online but does not cleanly apply, it can be modified in some fixed ways by using additional optional arguments for `fetchpatch`:
- `relative`: Similar to using `git-diff`'s `--relative` flag, only keep changes inside the specified directory, making paths relative to it.
- `stripLen`: Remove the first `stripLen` components of pathnames in the patch.
- `extraPrefix`: Prefix pathnames by this string.
- `excludes`: Exclude files matching this pattern.
- `includes`: Include only files matching this pattern.
- `excludes`: Exclude files matching these patterns (applies after the above arguments).
- `includes`: Include only files matching these patterns (applies after the above arguments).
- `revert`: Revert the patch.
Note that because the checksum is computed after applying these effects, using or modifying these arguments will have no effect unless the `sha256` argument is changed as well.

@ -122,10 +122,10 @@ Reviewing process:
- [CODEOWNERS](https://help.github.com/articles/about-codeowners/) will make GitHub notify users based on the submitted changes, but it can happen that it misses some of the package maintainers.
- Ensure that the module tests, if any, are succeeding.
- Ensure that the introduced options are correct.
- Type should be appropriate (string related types differs in their merging capabilities, `optionSet` and `string` types are deprecated).
- Type should be appropriate (string related types differs in their merging capabilities, `loaOf` and `string` types are deprecated).
- Description, default and example should be provided.
- Ensure that option changes are backward compatible.
- `mkRenamedOptionModule` and `mkAliasOptionModule` functions provide way to make option changes backward compatible.
- `mkRenamedOptionModuleWith` provides a way to make option changes backward compatible.
- Ensure that removed options are declared with `mkRemovedOptionModule`
- Ensure that changes that are not backward compatible are mentioned in release notes.
- Ensure that documentations affected by the change is updated.
@ -157,7 +157,7 @@ Reviewing process:
- Ensure that the module tests, if any, are succeeding.
- Ensure that the introduced options are correct.
- Type should be appropriate (string related types differs in their merging capabilities, `optionSet` and `string` types are deprecated).
- Type should be appropriate (string related types differs in their merging capabilities, `loaOf` and `string` types are deprecated).
- Description, default and example should be provided.
- Ensure that module `meta` field is present
- Maintainers should be declared in `meta.maintainers`.

@ -0,0 +1,10 @@
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="chap-hooks">
<title>Hooks reference</title>
<para>
Nixpkgs has several hook packages that augment the stdenv phases.
</para>
<xi:include href="./postgresql-test-hook.section.xml" />
</chapter>

@ -0,0 +1,59 @@
# `postgresqlTestHook` {#sec-postgresqlTestHook}
This hook starts a PostgreSQL server during the `checkPhase`. Example:
```nix
{ stdenv, postgresql, postgresqlTestHook }:
stdenv.mkDerivation {
# ...
checkInputs = [
postgresql
postgresqlTestHook
];
}
```
If you use a custom `checkPhase`, remember to add the `runHook` calls:
```nix
checkPhase ''
runHook preCheck
# ... your tests
runHook postCheck
''
```
## Variables {#sec-postgresqlTestHook-variables}
The hook logic will read a number of variables and set them to a default value if unset or empty.
Exported variables:
- `PGDATA`: location of server files.
- `PGHOST`: location of UNIX domain socket directory; the default `host` in a connection string.
- `PGUSER`: user to create / log in with, default: `test_user`.
- `PGDATABASE`: database name, default: `test_db`.
Bash-only variables:
- `postgresqlTestUserOptions`: SQL options to use when creating the `$PGUSER` role, default: `LOGIN`.
- `postgresqlTestSetupSQL`: SQL commands to run as database administrator after startup, default: statements that create `$PGUSER` and `$PGDATABASE`.
- `postgresqlTestSetupCommands`: bash commands to run after database start, defaults to running `$postgresqlTestSetupSQL` as database administrator.
- `postgresqlEnableTCP`: set to `1` to enable TCP listening. Flaky; not recommended.
- `postgresqlStartCommands`: defaults to `pg_ctl start`.
## TCP and the Nix sandbox {#sec-postgresqlTestHook-tcp}
`postgresqlEnableTCP` relies on network sandboxing, which is not available on macOS and some custom Nix installations, resulting in flaky tests.
For this reason, it is disabled by default.
The preferred solution is to make the test suite use a UNIX domain socket connection. This is the default behavior when no `host` connection parameter is provided.
Some test suites hardcode a value for `host` though, so a patch may be required. If you can upstream the patch, you can make `host` default to the `PGHOST` environment variable when set. Otherwise, you can patch it locally to omit the `host` connection string parameter altogether.
::: {.note}
The error `libpq: failed (could not receive data from server: Connection refused` is generally an indication that the test suite is trying to connect through TCP.
:::

@ -0,0 +1,49 @@
# CHICKEN {#sec-chicken}
[CHICKEN](https://call-cc.org/) is a
[R⁵RS](https://schemers.org/Documents/Standards/R5RS/HTML/)-compliant Scheme
compiler. It includes an interactive mode and a custom package format, "eggs".
## Using Eggs
Eggs described in nixpkgs are available inside the
`chickenPackages.chickenEggs` attrset. Including an egg as a build input is
done in the typical Nix fashion. For example, to include support for [SRFI
189](https://srfi.schemers.org/srfi-189/srfi-189.html) in a derivation, one
might write:
```nix
buildInputs = [
chicken
chickenPackages.chickenEggs.srfi-189
];
```
Both `chicken` and its eggs have a setup hook which configures the environment
variables `CHICKEN_INCLUDE_PATH` and `CHICKEN_REPOSITORY_PATH`.
## Updating Eggs
nixpkgs only knows about a subset of all published eggs. It uses
[egg2nix](https://github.com/the-kenny/egg2nix) to generate a
package set from a list of eggs to include.
The package set is regenerated by running the following shell commands:
```
$ nix-shell -p chickenPackages.egg2nix
$ cd pkgs/development/compilers/chicken/5/
$ egg2nix eggs.scm > eggs.nix
```
## Adding Eggs
When we run `egg2nix`, we obtain one collection of eggs with
mutually-compatible versions. This means that when we add new eggs, we may
need to update existing eggs. To keep those separate, follow the procedure for
updating eggs before including more eggs.
To include more eggs, edit `pkgs/development/compilers/chicken/5/eggs.scm`.
The first section of this file lists eggs which are required by `egg2nix`
itself; all other eggs go into the second section. After editing, follow the
procedure for updating eggs.

@ -0,0 +1,34 @@
# CUDA {#cuda}
CUDA-only packages are stored in the `cudaPackages` packages set. This set
includes the `cudatoolkit`, portions of the toolkit in separate derivations,
`cudnn`, `cutensor` and `nccl`.
A package set is available for each CUDA version, so for example
`cudaPackages_11_6`. Within each set is a matching version of the above listed
packages. Additionally, other versions of the packages that are packaged and
compatible are available as well. For example, there can be a
`cudaPackages.cudnn_8_3_2` package.
To use one or more CUDA packages in an expression, give the expression a `cudaPackages` parameter, and in case CUDA is optional
```nix
cudaSupport ? false
cudaPackages ? {}
```
When using `callPackage`, you can choose to pass in a different variant, e.g.
when a different version of the toolkit suffices
```nix
mypkg = callPackage { cudaPackages = cudaPackages_11_5; }
```
If another version of say `cudnn` or `cutensor` is needed, you can override the
package set to make it the default. This guarantees you get a consistent package
set.
```nix
mypkg = let
cudaPackages = cudaPackages_11_5.overrideScope' (final: prev {
cudnn = prev.cudnn_8_3_2;
}});
in callPackage { inherit cudaPackages; };
```

@ -42,7 +42,21 @@ Unlike other libraries mentioned in this section, GdkPixbuf only supports a sing
### Icons {#ssec-gnome-icons}
When an application uses icons, an icon theme should be available in `XDG_DATA_DIRS` during runtime. The package for the default, icon-less [hicolor-icon-theme](https://www.freedesktop.org/wiki/Software/icon-theme/) (should be propagated by every icon theme) contains [a setup hook](#ssec-gnome-hooks-hicolor-icon-theme) that will pick up icon themes from `buildInputs` and pass it to our wrapper. Unfortunately, relying on that would mean every user has to download the theme included in the package expression no matter their preference. For that reason, we leave the installation of icon theme on the user. If you use one of the desktop environments, you probably already have an icon theme installed.
When an application uses icons, an icon theme should be available in `XDG_DATA_DIRS` during runtime. The package for the default, icon-less [hicolor-icon-theme](https://www.freedesktop.org/wiki/Software/icon-theme/) (should be propagated by every icon theme) contains [a setup hook](#ssec-gnome-hooks-hicolor-icon-theme) that will pick up icon themes from `buildInputs` and add their datadirs to `XDG_ICON_DIRS` environment variable (this is Nixpkgs specific, not actually a XDG standard variable). Unfortunately, relying on that would mean every user has to download the theme included in the package expression no matter their preference. For that reason, we leave the installation of icon theme on the user. If you use one of the desktop environments, you probably already have an icon theme installed.
In the rare case you need to use icons from dependencies (e.g. when an app forces an icon theme), you can use the following to pick them up:
```nix
buildInputs = [
pantheon.elementary-icon-theme
];
preFixup = ''
gappsWrapperArgs+=(
# The icon theme is hardcoded.
--prefix XDG_DATA_DIRS : "$XDG_ICON_DIRS"
)
'';
```
To avoid costly file system access when locating icons, GTK, [as well as Qt](https://woboq.com/blog/qicon-reads-gtk-icon-cache-in-qt57.html), can rely on `icon-theme.cache` files from the themes' top-level directories. These files are generated using `gtk-update-icon-cache`, which is expected to be run whenever an icon is added or removed to an icon theme (typically an application icon into `hicolor` theme) and some programs do indeed run this after icon installation. However, since packages are installed into their own prefix by Nix, this would lead to conflicts. For that reason, `gtk3` provides a [setup hook](#ssec-gnome-hooks-gtk-drop-icon-theme-cache) that will clean the file from installation. Since most applications only ship their own icon that will be loaded on start-up, it should not affect them too much. On the other hand, icon themes are much larger and more widely used so we need to cache them. Because we recommend installing icon themes globally, we will generate the cache files from all packages in a profile using a NixOS module. You can enable the cache generation using `gtk.iconCache.enable` option if your desktop environment does not already do that.
@ -98,7 +112,7 @@ For convenience, it also adds `dconf.lib` for a GIO module implementing a GSetti
- []{#ssec-gnome-hooks-dconf} `dconf.lib` is a dependency of `wrapGAppsHook`, which then also adds it to the `GIO_EXTRA_MODULES` variable.
- []{#ssec-gnome-hooks-hicolor-icon-theme} `hicolor-icon-theme`’s setup hook will add icon themes to `XDG_ICON_DIRS` which is prepended to `XDG_DATA_DIRS` by `wrapGAppsHook`.
- []{#ssec-gnome-hooks-hicolor-icon-theme} `hicolor-icon-theme`’s setup hook will add icon themes to `XDG_ICON_DIRS`.
- []{#ssec-gnome-hooks-gobject-introspection} `gobject-introspection` setup hook populates `GI_TYPELIB_PATH` variable with `lib/girepository-1.0` directories of dependencies, which is then added to wrapper by `wrapGAppsHook`. It also adds `share` directories of dependencies to `XDG_DATA_DIRS`, which is intended to promote GIR files but it also [pollutes the closures](https://github.com/NixOS/nixpkgs/issues/32790) of packages using `wrapGAppsHook`.

@ -142,4 +142,8 @@ Removes the pre-existing vendor directory. This should only be used if the depen
### `subPackages` {#var-go-subPackages}
Limits the builder from building child packages that have not been listed. If `subPackages` is not specified, all child packages will be built.
Specified as a string or list of strings. Limits the builder from building child packages that have not been listed. If `subPackages` is not specified, all child packages will be built.
### `excludedPackages` {#var-go-excludedPackages}
Specified as a string or list of strings. Causes the builder to skip building child packages that match any of the provided values. If `excludedPackages` is not specified, all child packages will be built.

@ -9,8 +9,10 @@
<xi:include href="android.section.xml" />
<xi:include href="beam.section.xml" />
<xi:include href="bower.section.xml" />
<xi:include href="chicken.section.xml" />
<xi:include href="coq.section.xml" />
<xi:include href="crystal.section.xml" />
<xi:include href="cuda.section.xml" />
<xi:include href="dhall.section.xml" />
<xi:include href="dotnet.section.xml" />
<xi:include href="emscripten.section.xml" />

@ -85,7 +85,7 @@ you will still need to commit the modified version of the lock files, but at lea
each tool has an abstraction to just build the node_modules (dependencies) directory. you can always use the stdenv.mkDerivation with the node_modules to build the package (symlink the node_modules directory and then use the package build command). the node_modules abstraction can be also used to build some web framework frontends. For an example of this see how [plausible](https://github.com/NixOS/nixpkgs/blob/master/pkgs/servers/web-apps/plausible/default.nix) is built. mkYarnModules to make the derivation containing node_modules. Then when building the frontend you can just symlink the node_modules directory
## javascript packages inside nixpkgs {#javascript-packages-nixpkgs}
## Javascript packages inside nixpkgs {#javascript-packages-nixpkgs}
The `pkgs/development/node-packages` folder contains a generated collection of
[NPM packages](https://npmjs.com/) that can be installed with the Nix package
@ -121,12 +121,14 @@ requires `node-gyp-build`, so [we override](https://github.com/NixOS/nixpkgs/blo
};
```
### Adding and Updating Javascript packages in nixpkgs
To add a package from NPM to nixpkgs:
1. Modify `pkgs/development/node-packages/node-packages.json` to add, update
or remove package entries to have it included in `nodePackages` and
`nodePackages_latest`.
2. Run the script: `cd pkgs/development/node-packages && ./generate.sh`.
2. Run the script: `./pkgs/development/node-packages/generate.sh`.
3. Build your new package to test your changes:
`cd /path/to/nixpkgs && nix-build -A nodePackages.<new-or-updated-package>`.
To build against the latest stable Current Node.js version (e.g. 14.x):
@ -137,6 +139,26 @@ For more information about the generation process, consult the
[README.md](https://github.com/svanderburg/node2nix) file of the `node2nix`
tool.
To update NPM packages in nixpkgs, run the same `generate.sh` script:
```sh
./pkgs/development/node-packages/generate.sh
```
#### Git protocol error
Some packages may have Git dependencies from GitHub specified with `git://`.
GitHub has
[disabled unecrypted Git connections](https://github.blog/2021-09-01-improving-git-protocol-security-github/#no-more-unauthenticated-git),
so you may see the following error when running the generate script:
`The unauthenticated git protocol on port 9418 is no longer supported`.
Use the following Git configuration to resolve the issue:
```sh
git config --global url."https://github.com/".insteadOf git://github.com/
```
## Tool specific instructions {#javascript-tool-specific}
### node2nix {#javascript-node2nix}

@ -38,8 +38,12 @@ Here is a simple package example.
- It uses the `fetchFromGitHub` fetcher to get its source.
- `useDune2 = true` ensures that Dune version 2 is used for the
build (this is the default; set to `false` to use Dune version 1).
- `duneVersion = "2"` ensures that Dune version 2 is used for the
build (this is the default; valid values are `"1"`, `"2"`, and `"3"`);
note that there is also a legacy `useDune2` boolean attribute:
set to `false` it corresponds to `duneVersion = "1"`; set to `true` it
corresponds to `duneVersion = "2"`. If both arguments (`duneVersion` and
`useDune2`) are given, the second one (`useDune2`) is silently ignored.
- It sets the optional `doCheck` attribute such that tests will be run with
`dune runtest -p angstrom` after the build (`dune build -p angstrom`) is
@ -67,7 +71,7 @@ Here is a simple package example.
buildDunePackage rec {
pname = "angstrom";
version = "0.15.0";
useDune2 = true;
duneVersion = "2";
minimalOCamlVersion = "4.04";

@ -6,7 +6,7 @@ Since release 15.09 there is a new TeX Live packaging that lives entirely under
- For basic usage just pull `texlive.combined.scheme-basic` for an environment with basic LaTeX support.
- It typically won't work to use separately installed packages together. Instead, you can build a custom set of packages like this:
- It typically won't work to use separately installed packages together. Instead, you can build a custom set of packages like this. Most CTAN packages should be available:
```nix
texlive.combine {

@ -18,7 +18,7 @@ Adding custom .vimrc lines can be done using the following code:
```nix
vim_configurable.customize {
# `name` specifies the name of the executable and package
# `name` optionally specifies the name of the executable and package
name = "vim-with-plugins";
vimrcConfig.customRC = ''
@ -28,6 +28,9 @@ vim_configurable.customize {
```
This configuration is used when Vim is invoked with the command specified as name, in this case `vim-with-plugins`.
You can also omit `name` to customize Vim itself. See the
[definition of `vimUtils.makeCustomizable`](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/vim/plugins/vim-utils.nix#L408)
for all supported options.
For Neovim the `configure` argument can be overridden to achieve the same:
@ -286,7 +289,7 @@ Sample output1:
"reload" = buildVimPluginFrom2Nix { # created by nix#NixDerivation
name = "reload";
src = fetchgit {
url = "git://github.com/xolox/vim-reload";
url = "https://github.com/xolox/vim-reload";
rev = "0a601a668727f5b675cb1ddc19f6861f3f7ab9e1";
sha256 = "0vb832l9yxj919f5hfg6qj6bn9ni57gnjd3bj7zpq7d4iv2s4wdh";
};

@ -25,8 +25,10 @@
<title>Builders</title>
<xi:include href="builders/fetchers.chapter.xml" />
<xi:include href="builders/trivial-builders.chapter.xml" />
<xi:include href="builders/testers.chapter.xml" />
<xi:include href="builders/special.xml" />
<xi:include href="builders/images.xml" />
<xi:include href="hooks/index.xml" />
<xi:include href="languages-frameworks/index.xml" />
<xi:include href="builders/packages/index.xml" />
</part>

@ -78,21 +78,46 @@ If both the dependency and depending packages aren't compilers or other machine-
Finally, if the depending package is a compiler or other machine-code-producing tool, it might need dependencies that run at "emit time". This is for compilers that (regrettably) insist on being built together with their source languages' standard libraries. Assuming build != host != target, a run-time dependency of the standard library cannot be run at the compiler's build time or run time, but only at the run time of code emitted by the compiler.
Putting this all together, that means we have dependencies in the form "host → target", in at most the following six combinations:
Putting this all together, that means that we have dependency types of the form "X→ E", which means that the dependency executes on X and emits code for E; each of X and E can be `build`, `host`, or `target`, and E can be `*` to indicate that the dependency is not a compiler-like package.
Dependency types describe the relationships that a package has with each of its transitive dependencies. You could think of attaching one or more dependency types to each of the formal parameters at the top of a package's `.nix` file, as well as to all of *their* formal parameters, and so on. Triples like `(foo, bar, baz)`, on the other hand, are a property of an instantiated derivation -- you could would attach a triple `(mips-linux, mips-linux, sparc-solaris)` to a `.drv` file in `/nix/store`.
Only nine dependency types matter in practice:
#### Possible dependency types {#possible-dependency-types}
| Dependency’s host platform | Dependency’s target platform |
|----------------------------|------------------------------|
| build | build |
| build | host |
| build | target |
| host | host |
| host | target |
| target | target |
| Dependency type | Dependency’s host platform | Dependency’s target platform |
|-----------------|----------------------------|------------------------------|
| build → * | build | (none) |
| build → build | build | build |
| build → host | build | host |
| build → target | build | target |
| host → * | host | (none) |
| host → host | host | host |
| host → target | host | target |
| target → * | target | (none) |
| target → target | target | target |
Let's use `g++` as an example to make this table clearer. `g++` is a C++ compiler written in C. Suppose we are building `g++` with a `(build, host, target)` platform triple of `(foo, bar, baz)`. This means we are using a `foo`-machine to build a copy of `g++` which will run on a `bar`-machine and emit binaries for the `baz`-machine.
* `g++` links against the host platform's `glibc` C library, which is a "host→ *" dependency with a triple of `(bar, bar, *)`. Since it is a library, not a compiler, it has no "target".
* Since `g++` is written in C, the `gcc` compiler used to compile it is a "build→ host" dependency of `g++` with a triple of `(foo, foo, bar)`. This compiler runs on the build platform and emits code for the host platform.
* `gcc` links against the build platform's `glibc` C library, which is a "build→ *" dependency with a triple of `(foo, foo, *)`. Since it is a library, not a compiler, it has no "target".
* This `gcc` is itself compiled by an *earlier* copy of `gcc`. This earlier copy of `gcc` is a "build→ build" dependency of `g++` with a triple of `(foo, foo, foo)`. This "early `gcc`" runs on the build platform and emits code for the build platform.
* `g++` is bundled with `libgcc`, which includes a collection of target-machine routines for exception handling and
software floating point emulation. `libgcc` would be a "target→ *" dependency with triple `(foo, baz, *)`, because it consists of machine code which gets linked against the output of the compiler that we are building. It is a library, not a compiler, so it has no target of its own.
* `libgcc` is written in C and compiled with `gcc`. The `gcc` that compiles it will be a "build→ target" dependency with triple `(foo, foo, baz)`. It gets compiled *and run* at `g++`-build-time (on platform `foo`), but must emit code for the `baz`-platform.
* `g++` allows inline assembler code, so it depends on access to a copy of the `gas` assembler. This would be a "host→ target" dependency with triple `(foo, bar, baz)`.
* `g++` (and `gcc`) include a library `libgccjit.so`, which wrap the compiler in a library to create a just-in-time compiler. In nixpkgs, this library is in the `libgccjit` package; if C++ required that programs have access to a JIT, `g++` would need to add a "target→ target" dependency for `libgccjit` with triple `(foo, baz, baz)`. This would ensure that the compiler ships with a copy of `libgccjit` which both executes on and generates code for the `baz`-platform.
Some examples will make this table clearer. Suppose there's some package that is being built with a `(build, host, target)` platform triple of `(foo, bar, baz)`. If it has a build-time library dependency, that would be a "host → build" dependency with a triple of `(foo, foo, *)` (the target platform is irrelevant). If it needs a compiler to be built, that would be a "build → host" dependency with a triple of `(foo, foo, *)` (the target platform is irrelevant). That compiler, would be built with another compiler, also "build → host" dependency, with a triple of `(foo, foo, foo)`.
* If `g++` itself linked against `libgccjit.so` (for example, to allow compile-time-evaluated C++ expressions), then the `libgccjit` package used to provide this functionality would be a "host→ host" dependency of `g++`: it is code which runs on the `host` and emits code for execution on the `host`.
### Cross packaging cookbook {#ssec-cross-cookbook}

@ -125,7 +125,7 @@ The extension of `PATH` with dependencies, alluded to above, proceeds according
A dependency is said to be **propagated** when some of its other-transitive (non-immediate) downstream dependencies also need it as an immediate dependency.
[^footnote-stdenv-propagated-dependencies]
It is important to note that dependencies are not necessarily propagated as the same sort of dependency that they were before, but rather as the corresponding sort so that the platform rules still line up. To determine the exact rules for dependency propagation, we start by assigning to each dependency a couple of ternary numbers (`-1` for `build`, `0` for `host`, and `1` for `target`), representing how respectively its host and target platforms are "offset" from the depending derivation’s platforms. The following table summarize the different combinations that can be obtained:
It is important to note that dependencies are not necessarily propagated as the same sort of dependency that they were before, but rather as the corresponding sort so that the platform rules still line up. To determine the exact rules for dependency propagation, we start by assigning to each dependency a couple of ternary numbers (`-1` for `build`, `0` for `host`, and `1` for `target`) representing its [dependency type](#possible-dependency-types), which captures how its host and target platforms are each "offset" from the depending derivation’s host and target platforms. The following table summarize the different combinations that can be obtained:
| `host → target` | attribute name | offset |
| ------------------- | ------------------- | -------- |
@ -1043,7 +1043,7 @@ You can also specify a `runtimeDependencies` variable which lists dependencies t
In certain situations you may want to run the main command (`autoPatchelf`) of the setup hook on a file or a set of directories instead of unconditionally patching all outputs. This can be done by setting the `dontAutoPatchelf` environment variable to a non-empty value.
By default `autoPatchelf` will fail as soon as any ELF file requires a dependency which cannot be resolved via the given build inputs. In some situations you might prefer to just leave missing dependencies unpatched and continue to patch the rest. This can be achieved by setting the `autoPatchelfIgnoreMissingDeps` environment variable to a non-empty value.
By default `autoPatchelf` will fail as soon as any ELF file requires a dependency which cannot be resolved via the given build inputs. In some situations you might prefer to just leave missing dependencies unpatched and continue to patch the rest. This can be achieved by setting the `autoPatchelfIgnoreMissingDeps` environment variable to a non-empty value. `autoPatchelfIgnoreMissingDeps` can be set to a list like `autoPatchelfIgnoreMissingDeps = [ "libcuda.so.1" "libcudart.so.1" ];` or to simply `[ "*" ]` to ignore all missing dependencies.
The `autoPatchelf` command also recognizes a `--no-recurse` command line flag, which prevents it from recursing into subdirectories.

@ -117,8 +117,55 @@ rec {
callPackageWith = autoArgs: fn: args:
let
f = if lib.isFunction fn then fn else import fn;
auto = builtins.intersectAttrs (lib.functionArgs f) autoArgs;
in makeOverridable f (auto // args);
fargs = lib.functionArgs f;
# All arguments that will be passed to the function
# This includes automatic ones and ones passed explicitly
allArgs = builtins.intersectAttrs fargs autoArgs // args;
# A list of argument names that the function requires, but
# wouldn't be passed to it
missingArgs = lib.attrNames
# Filter out arguments that have a default value
(lib.filterAttrs (name: value: ! value)
# Filter out arguments that would be passed
(removeAttrs fargs (lib.attrNames allArgs)));
# Get a list of suggested argument names for a given missing one
getSuggestions = arg: lib.pipe (autoArgs // args) [
lib.attrNames
# Only use ones that are at most 2 edits away. While mork would work,
# levenshteinAtMost is only fast for 2 or less.
(lib.filter (lib.strings.levenshteinAtMost 2 arg))
# Put strings with shorter distance first
(lib.sort (x: y: lib.strings.levenshtein x arg < lib.strings.levenshtein y arg))
# Only take the first couple results
(lib.take 3)
# Quote all entries
(map (x: "\"" + x + "\""))
];
prettySuggestions = suggestions:
if suggestions == [] then ""
else if lib.length suggestions == 1 then ", did you mean ${lib.elemAt suggestions 0}?"
else ", did you mean ${lib.concatStringsSep ", " (lib.init suggestions)} or ${lib.last suggestions}?";
errorForArg = arg:
let
loc = builtins.unsafeGetAttrPos arg fargs;
# loc' can be removed once lib/minver.nix is >2.3.4, since that includes
# https://github.com/NixOS/nix/pull/3468 which makes loc be non-null
loc' = if loc != null then loc.file + ":" + toString loc.line
else if ! lib.isFunction fn then
toString fn + lib.optionalString (lib.sources.pathIsDirectory fn) "/default.nix"
else "<unknown location>";
in "Function called without required argument \"${arg}\" at "
+ "${loc'}${prettySuggestions (getSuggestions arg)}";
# Only show the error for the first missing argument
error = errorForArg (lib.head missingArgs);
in if missingArgs == [] then makeOverridable f allArgs else throw error;
/* Like callPackage, but for a function that returns an attribute

@ -66,9 +66,10 @@ let
stringLength sub substring tail trace;
inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor
bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max
importJSON importTOML warn warnIf throwIfNot checkListOfEnum
info showWarnings nixpkgsVersion version
mod compare splitByAndCompare functionArgs setFunctionArgs isFunction
importJSON importTOML warn warnIf warnIfNot throwIf throwIfNot checkListOfEnum
info showWarnings nixpkgsVersion version isInOldestRelease
mod compare splitByAndCompare
functionArgs setFunctionArgs isFunction toFunction
toHexString toBaseDigits;
inherit (self.fixedPoints) fix fix' converge extends composeExtensions
composeManyExtensions makeExtensible makeExtensibleWithCustomName;
@ -113,14 +114,15 @@ let
commitIdFromGitRepo cleanSourceWith pathHasContext
canCleanSource pathIsRegularFile pathIsGitRepo;
inherit (self.modules) evalModules setDefaultModuleLocation
unifyModuleSyntax applyIfFunction mergeModules
unifyModuleSyntax applyModuleArgsIfFunction mergeModules
mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions
pushDownProperties dischargeProperties filterOverrides
sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride
mkOptionDefault mkDefault mkImageMediaOverride mkForce mkVMOverride
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
mkRenamedOptionModule mkRenamedOptionModuleWith
mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule mkDerivedConfig doRename;
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption

@ -10,7 +10,7 @@
* are mostly generators themselves, called with
* their respective default values; they can be reused.
*
* Tests can be found in ./tests.nix
* Tests can be found in ./tests/misc.nix
* Documentation in the manual, #sec-generators
*/
{ lib }:
@ -108,7 +108,7 @@ rec {
* The mk* configuration attributes can generically change
* the way sections and key-value strings are generated.
*
* For more examples see the test cases in ./tests.nix.
* For more examples see the test cases in ./tests/misc.nix.
*/
toINI = {
# apply transformations (e.g. escapes) to section names
@ -130,6 +130,51 @@ rec {
# map input to ini sections
mapAttrsToStringsSep "\n" mkSection attrsOfAttrs;
/* Generate an INI-style config file from an attrset
* specifying the global section (no header), and an
* attrset of sections to an attrset of key-value pairs.
*
* generators.toINIWithGlobalSection {} {
* globalSection = {
* someGlobalKey = "hi";
* };
* sections = {
* foo = { hi = "${pkgs.hello}"; ciao = "bar"; };
* baz = { "also, integers" = 42; };
* }
*
*> someGlobalKey=hi
*>
*> [baz]
*> also, integers=42
*>
*> [foo]
*> ciao=bar
*> hi=/nix/store/y93qql1p5ggfnaqjjqhxcw0vqw95rlz0-hello-2.10
*
* The mk* configuration attributes can generically change
* the way sections and key-value strings are generated.
*
* For more examples see the test cases in ./tests/misc.nix.
*
* If you dont need a global section, you can also use
* `generators.toINI` directly, which only takes
* the part in `sections`.
*/
toINIWithGlobalSection = {
# apply transformations (e.g. escapes) to section names
mkSectionName ? (name: libStr.escape [ "[" "]" ] name),
# format a setting line from key and value
mkKeyValue ? mkKeyValueDefault {} "=",
# allow lists as values for duplicate keys
listsAsDuplicateKeys ? false
}: { globalSection, sections }:
( if globalSection == {}
then ""
else (toKeyValue { inherit mkKeyValue listsAsDuplicateKeys; } globalSection)
+ "\n")
+ (toINI { inherit mkSectionName mkKeyValue listsAsDuplicateKeys; } sections);
/* Generate a git-config file from an attrset.
*
* It has two major differences from the regular INI format:

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

@ -46,6 +46,7 @@ let
showFiles
showOption
unknownModule
literalExpression
;
showDeclPrefix = loc: decl: prefix:
@ -140,7 +141,7 @@ rec {
# this module is used, to avoid conflicts and allow chaining of
# extendModules.
internalModule = rec {
_file = ./modules.nix;
_file = "lib/modules.nix";
key = _file;
@ -153,8 +154,91 @@ rec {
# a `_module.args.pkgs = import (fetchTarball { ... }) {}` won't
# start a download when `pkgs` wasn't evaluated.
type = types.lazyAttrsOf types.raw;
internal = true;
description = "Arguments passed to each module.";
# Only render documentation once at the root of the option tree,
# not for all individual submodules.
internal = prefix != [];
# TODO: Change the type of this option to a submodule with a
# freeformType, so that individual arguments can be documented
# separately
description = ''
Additional arguments passed to each module in addition to ones
like <literal>lib</literal>, <literal>config</literal>,
and <literal>pkgs</literal>, <literal>modulesPath</literal>.
</para>
<para>
This option is also available to all submodules. Submodules do not
inherit args from their parent module, nor do they provide args to
their parent module or sibling submodules. The sole exception to
this is the argument <literal>name</literal> which is provided by
parent modules to a submodule and contains the attribute name
the submodule is bound to, or a unique generated name if it is
not bound to an attribute.
</para>
<para>
Some arguments are already passed by default, of which the
following <emphasis>cannot</emphasis> be changed with this option:
<itemizedlist>
<listitem>
<para>
<varname>lib</varname>: The nixpkgs library.
</para>
</listitem>
<listitem>
<para>
<varname>config</varname>: The results of all options after merging the values from all modules together.
</para>
</listitem>
<listitem>
<para>
<varname>options</varname>: The options declared in all modules.
</para>
</listitem>
<listitem>
<para>
<varname>specialArgs</varname>: The <literal>specialArgs</literal> argument passed to <literal>evalModules</literal>.
</para>
</listitem>
<listitem>
<para>
All attributes of <varname>specialArgs</varname>
</para>
<para>
Whereas option values can generally depend on other option values
thanks to laziness, this does not apply to <literal>imports</literal>, which
must be computed statically before anything else.
</para>
<para>
For this reason, callers of the module system can provide <literal>specialArgs</literal>
which are available during import resolution.
</para>
<para>
For NixOS, <literal>specialArgs</literal> includes
<varname>modulesPath</varname>, which allows you to import
extra modules from the nixpkgs package tree without having to
somehow make the module aware of the location of the
<literal>nixpkgs</literal> or NixOS directories.
<programlisting>
{ modulesPath, ... }: {
imports = [
(modulesPath + "/profiles/minimal.nix")
];
}
</programlisting>
</para>
</listitem>
</itemizedlist>
</para>
<para>
For NixOS, the default value for this option includes at least this argument:
<itemizedlist>
<listitem>
<para>
<varname>pkgs</varname>: The nixpkgs package set according to
the <option>nixpkgs.pkgs</option> option.
</para>
</listitem>
</itemizedlist>
'';
};
_module.check = mkOption {
@ -282,11 +366,11 @@ rec {
# Like unifyModuleSyntax, but also imports paths and calls functions if necessary
loadModule = args: fallbackFile: fallbackKey: m:
if isFunction m || isAttrs m then
unifyModuleSyntax fallbackFile fallbackKey (applyIfFunction fallbackKey m args)
unifyModuleSyntax fallbackFile fallbackKey (applyModuleArgsIfFunction fallbackKey m args)
else if isList m then
let defs = [{ file = fallbackFile; value = m; }]; in
throw "Module imports can't be nested lists. Perhaps you meant to remove one level of lists? Definitions: ${showDefs defs}"
else unifyModuleSyntax (toString m) (toString m) (applyIfFunction (toString m) (import m) args);
else unifyModuleSyntax (toString m) (toString m) (applyModuleArgsIfFunction (toString m) (import m) args);
/*
Collects all modules recursively into the form
@ -383,7 +467,7 @@ rec {
config = addFreeformType (addMeta (removeAttrs m ["_file" "key" "disabledModules" "require" "imports" "freeformType"]));
};
applyIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
applyModuleArgsIfFunction = key: f: args@{ config, options, lib, ... }: if isFunction f then
let
# Module arguments are resolved in a strict manner when attribute set
# deconstruction is used. As the arguments are now defined with the
@ -609,17 +693,9 @@ rec {
throw "The option `${showOption loc}' in `${opt._file}' is already declared in ${showFiles res.declarations}."
else
let
/* Add the modules of the current option to the list of modules
already collected. The options attribute except either a list of
submodules or a submodule. For each submodule, we add the file of the
current option declaration as the file use for the submodule. If the
submodule defines any filename, then we ignore the enclosing option file. */
options' = toList opt.options.options;
getSubModules = opt.options.type.getSubModules or null;
submodules =
if getSubModules != null then map (setDefaultModuleLocation opt._file) getSubModules ++ res.options
else if opt.options ? options then map (coerceOption opt._file) options' ++ res.options
else res.options;
in opt.options // res //
{ declarations = res.declarations ++ [opt._file];
@ -802,27 +878,13 @@ rec {
compare = a: b: (a.priority or 1000) < (b.priority or 1000);
in sort compare defs';
# This calls substSubModules, whose entire purpose is only to ensure that
# option declarations in submodules have accurate position information.
# TODO: Merge this into mergeOptionDecls
fixupOptionType = loc: opt:
let
options = opt.options or
(throw "Option `${showOption loc}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}.");
# Hack for backward compatibility: convert options of type
# optionSet to options of type submodule. FIXME: remove
# eventually.
f = tp:
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 (tp.functor.wrapped.name or null) == "optionSet" then
if tp.name == "attrsOf" then types.attrsOf (types.submodule options)
else if tp.name == "listOf" then types.listOf (types.submodule options)
else if tp.name == "nullOr" then types.nullOr (types.submodule options)
else tp
else tp;
in
if opt.type.getSubModules or null == null
then opt // { type = f (opt.type or types.unspecified); }
else opt // { type = opt.type.substSubModules opt.options; options = []; };
if opt.type.getSubModules or null == null
then opt // { type = opt.type or types.unspecified; }
else opt // { type = opt.type.substSubModules opt.options; options = []; };
/* Properties. */
@ -954,6 +1016,26 @@ rec {
use = builtins.trace "Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
};
mkRenamedOptionModuleWith = {
/* Old option path as list of strings. */
from,
/* New option path as list of strings. */
to,
/*
Release number of the first release that contains the rename, ignoring backports.
Set it to the upcoming release, matching the nixpkgs/.version file.
*/
sinceRelease,
}: doRename {
inherit from to;
visible = false;
warn = lib.isInOldestRelease sinceRelease;
use = lib.warnIf (lib.isInOldestRelease sinceRelease)
"Obsolete option `${showOption from}' is used. It was renamed to `${showOption to}'.";
};
/* Return a module that causes a warning to be shown if any of the "from"
option is defined; the defined values can be used in the "mergeFn" to set
the "to" value.

@ -79,8 +79,6 @@ rec {
visible ? null,
# Whether the option can be set only once
readOnly ? null,
# Deprecated, used by types.optionSet.
options ? null
} @ attrs:
attrs // { _type = "option"; };
@ -122,7 +120,7 @@ rec {
Example:
mkPackageOption pkgs "GHC" {
default = [ "ghc" ];
example = "pkgs.haskell.package.ghc921.ghc.withPackages (hkgs: [ hkgs.primes ])";
example = "pkgs.haskell.package.ghc922.ghc.withPackages (hkgs: [ hkgs.primes ])";
}
=> { _type = "option"; default = «derivation /nix/store/jxx55cxsjrf8kyh3fp2ya17q99w7541r-ghc-8.10.7.drv»; defaultText = { ... }; description = "The GHC package to use."; example = { ... }; type = { ... }; }
*/

@ -253,10 +253,7 @@ rec {
=> false
*/
hasInfix = infix: content:
let
drop = x: substring 1 (stringLength x) x;
in hasPrefix infix content
|| content != "" && hasInfix infix (drop content);
builtins.match ".*${escapeRegex infix}.*" content != null;
/* Convert a string to a list of characters (i.e. singleton strings).
This allows you to, e.g., map a function over each character. However,
@ -756,7 +753,14 @@ rec {
sanitizeDerivationName pkgs.hello
=> "-nix-store-2g75chlbpxlrqn15zlby2dfh8hr9qwbk-hello-2.10"
*/
sanitizeDerivationName = string: lib.pipe string [
sanitizeDerivationName =
let okRegex = match "[[:alnum:]+_?=-][[:alnum:]+._?=-]*";
in
string:
# First detect the common case of already valid strings, to speed those up
if stringLength string <= 207 && okRegex string != null
then unsafeDiscardStringContext string
else lib.pipe string [
# Get rid of string context. This is safe under the assumption that the
# resulting string is only used as a derivation name
unsafeDiscardStringContext
@ -774,4 +778,131 @@ rec {
(x: if stringLength x == 0 then "unknown" else x)
];
/* Computes the Levenshtein distance between two strings.
Complexity O(n*m) where n and m are the lengths of the strings.
Algorithm adjusted from https://stackoverflow.com/a/9750974/6605742
Type: levenshtein :: string -> string -> int
Example:
levenshtein "foo" "foo"
=> 0
levenshtein "book" "hook"
=> 1
levenshtein "hello" "Heyo"
=> 3
*/
levenshtein = a: b: let
# Two dimensional array with dimensions (stringLength a + 1, stringLength b + 1)
arr = lib.genList (i:
lib.genList (j:
dist i j
) (stringLength b + 1)
) (stringLength a + 1);
d = x: y: lib.elemAt (lib.elemAt arr x) y;
dist = i: j:
let c = if substring (i - 1) 1 a == substring (j - 1) 1 b
then 0 else 1;
in
if j == 0 then i
else if i == 0 then j
else lib.min
( lib.min (d (i - 1) j + 1) (d i (j - 1) + 1))
( d (i - 1) (j - 1) + c );
in d (stringLength a) (stringLength b);
/* Returns the length of the prefix common to both strings.
*/
commonPrefixLength = a: b:
let
m = lib.min (stringLength a) (stringLength b);
go = i: if i >= m then m else if substring i 1 a == substring i 1 b then go (i + 1) else i;
in go 0;
/* Returns the length of the suffix common to both strings.
*/
commonSuffixLength = a: b:
let
m = lib.min (stringLength a) (stringLength b);
go = i: if i >= m then m else if substring (stringLength a - i - 1) 1 a == substring (stringLength b - i - 1) 1 b then go (i + 1) else i;
in go 0;
/* Returns whether the levenshtein distance between two strings is at most some value
Complexity is O(min(n,m)) for k <= 2 and O(n*m) otherwise
Type: levenshteinAtMost :: int -> string -> string -> bool
Example:
levenshteinAtMost 0 "foo" "foo"
=> true
levenshteinAtMost 1 "foo" "boa"
=> false
levenshteinAtMost 2 "foo" "boa"
=> true
levenshteinAtMost 2 "This is a sentence" "this is a sentense."
=> false
levenshteinAtMost 3 "This is a sentence" "this is a sentense."
=> true
*/
levenshteinAtMost = let
infixDifferAtMost1 = x: y: stringLength x <= 1 && stringLength y <= 1;
# This function takes two strings stripped by their common pre and suffix,
# and returns whether they differ by at most two by Levenshtein distance.
# Because of this stripping, if they do indeed differ by at most two edits,
# we know that those edits were (if at all) done at the start or the end,
# while the middle has to have stayed the same. This fact is used in the
# implementation.
infixDifferAtMost2 = x: y:
let
xlen = stringLength x;
ylen = stringLength y;
# This function is only called with |x| >= |y| and |x| - |y| <= 2, so
# diff is one of 0, 1 or 2
diff = xlen - ylen;
# Infix of x and y, stripped by the left and right most character
xinfix = substring 1 (xlen - 2) x;
yinfix = substring 1 (ylen - 2) y;
# x and y but a character deleted at the left or right
xdelr = substring 0 (xlen - 1) x;
xdell = substring 1 (xlen - 1) x;
ydelr = substring 0 (ylen - 1) y;
ydell = substring 1 (ylen - 1) y;
in
# A length difference of 2 can only be gotten with 2 delete edits,
# which have to have happened at the start and end of x
# Example: "abcdef" -> "bcde"
if diff == 2 then xinfix == y
# A length difference of 1 can only be gotten with a deletion on the
# right and a replacement on the left or vice versa.
# Example: "abcdef" -> "bcdez" or "zbcde"
else if diff == 1 then xinfix == ydelr || xinfix == ydell
# No length difference can either happen through replacements on both
# sides, or a deletion on the left and an insertion on the right or
# vice versa
# Example: "abcdef" -> "zbcdez" or "bcdefz" or "zabcde"
else xinfix == yinfix || xdelr == ydell || xdell == ydelr;
in k: if k <= 0 then a: b: a == b else
let f = a: b:
let
alen = stringLength a;
blen = stringLength b;
prelen = commonPrefixLength a b;
suflen = commonSuffixLength a b;
presuflen = prelen + suflen;
ainfix = substring prelen (alen - presuflen) a;
binfix = substring prelen (blen - presuflen) b;
in
# Make a be the bigger string
if alen < blen then f b a
# If a has over k more characters than b, even with k deletes on a, b can't be reached
else if alen - blen > k then false
else if k == 1 then infixDifferAtMost1 ainfix binfix
else if k == 2 then infixDifferAtMost2 ainfix binfix
else levenshtein ainfix binfix <= k;
in f;
}

@ -500,7 +500,7 @@ rec {
# 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 // {
mips64el-qemu-linux-gnuabi64 = {
linux-kernel = {
name = "mips64el";
baseConfig = "64r2el_defconfig";

@ -471,6 +471,66 @@ runTests {
'';
};
testToINIWithGlobalSectionEmpty = {
expr = generators.toINIWithGlobalSection {} {
globalSection = {
};
sections = {
};
};
expected = ''
'';
};
testToINIWithGlobalSectionGlobalEmptyIsTheSameAsToINI =
let
sections = {
"section 1" = {
attribute1 = 5;
x = "Me-se JarJar Binx";
};
"foo" = {
"he\\h=he" = "this is okay";
};
};
in {
expr =
generators.toINIWithGlobalSection {} {
globalSection = {};
sections = sections;
};
expected = generators.toINI {} sections;
};
testToINIWithGlobalSectionFull = {
expr = generators.toINIWithGlobalSection {} {
globalSection = {
foo = "bar";
test = false;
};
sections = {
"section 1" = {
attribute1 = 5;
x = "Me-se JarJar Binx";
};
"foo" = {
"he\\h=he" = "this is okay";
};
};
};
expected = ''
foo=bar
test=false
[foo]
he\h\=he=this is okay
[section 1]
attribute1=5
x=Me-se JarJar Binx
'';
};
/* right now only invocation check */
testToJSONSimple =
let val = {
@ -649,6 +709,11 @@ runTests {
expected = "foo";
};
testSanitizeDerivationNameUnicode = testSanitizeDerivationName {
name = "fö";
expected = "f-";
};
testSanitizeDerivationNameAscii = testSanitizeDerivationName {
name = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
expected = "-+--.-0123456789-=-?-ABCDEFGHIJKLMNOPQRSTUVWXYZ-_-abcdefghijklmnopqrstuvwxyz-";
@ -691,7 +756,7 @@ runTests {
locs = filter (o: ! o.internal) (optionAttrSetToDocList options);
in map (o: o.loc) locs;
expected = [ [ "foo" ] [ "foo" "<name>" "bar" ] [ "foo" "bar" ] ];
expected = [ [ "_module" "args" ] [ "foo" ] [ "foo" "<name>" "bar" ] [ "foo" "bar" ] ];
};
testCartesianProductOfEmptySet = {
@ -913,4 +978,156 @@ runTests {
};
};
## Levenshtein distance functions and co.
testCommonPrefixLengthEmpty = {
expr = strings.commonPrefixLength "" "hello";
expected = 0;
};
testCommonPrefixLengthSame = {
expr = strings.commonPrefixLength "hello" "hello";
expected = 5;
};
testCommonPrefixLengthDiffering = {
expr = strings.commonPrefixLength "hello" "hey";
expected = 2;
};
testCommonSuffixLengthEmpty = {
expr = strings.commonSuffixLength "" "hello";
expected = 0;
};
testCommonSuffixLengthSame = {
expr = strings.commonSuffixLength "hello" "hello";
expected = 5;
};
testCommonSuffixLengthDiffering = {
expr = strings.commonSuffixLength "test" "rest";
expected = 3;
};
testLevenshteinEmpty = {
expr = strings.levenshtein "" "";
expected = 0;
};
testLevenshteinOnlyAdd = {
expr = strings.levenshtein "" "hello there";
expected = 11;
};
testLevenshteinOnlyRemove = {
expr = strings.levenshtein "hello there" "";
expected = 11;
};
testLevenshteinOnlyTransform = {
expr = strings.levenshtein "abcdef" "ghijkl";
expected = 6;
};
testLevenshteinMixed = {
expr = strings.levenshtein "kitchen" "sitting";
expected = 5;
};
testLevenshteinAtMostZeroFalse = {
expr = strings.levenshteinAtMost 0 "foo" "boo";
expected = false;
};
testLevenshteinAtMostZeroTrue = {
expr = strings.levenshteinAtMost 0 "foo" "foo";
expected = true;
};
testLevenshteinAtMostOneFalse = {
expr = strings.levenshteinAtMost 1 "car" "ct";
expected = false;
};
testLevenshteinAtMostOneTrue = {
expr = strings.levenshteinAtMost 1 "car" "cr";
expected = true;
};
# We test levenshteinAtMost 2 particularly well because it uses a complicated
# implementation
testLevenshteinAtMostTwoIsEmpty = {
expr = strings.levenshteinAtMost 2 "" "";
expected = true;
};
testLevenshteinAtMostTwoIsZero = {
expr = strings.levenshteinAtMost 2 "abcdef" "abcdef";
expected = true;
};
testLevenshteinAtMostTwoIsOne = {
expr = strings.levenshteinAtMost 2 "abcdef" "abddef";
expected = true;
};
testLevenshteinAtMostTwoDiff0False = {
expr = strings.levenshteinAtMost 2 "abcdef" "aczyef";
expected = false;
};
testLevenshteinAtMostTwoDiff0Outer = {
expr = strings.levenshteinAtMost 2 "abcdef" "zbcdez";
expected = true;
};
testLevenshteinAtMostTwoDiff0DelLeft = {
expr = strings.levenshteinAtMost 2 "abcdef" "bcdefz";
expected = true;
};
testLevenshteinAtMostTwoDiff0DelRight = {
expr = strings.levenshteinAtMost 2 "abcdef" "zabcde";
expected = true;
};
testLevenshteinAtMostTwoDiff1False = {
expr = strings.levenshteinAtMost 2 "abcdef" "bddez";
expected = false;
};
testLevenshteinAtMostTwoDiff1DelLeft = {
expr = strings.levenshteinAtMost 2 "abcdef" "bcdez";
expected = true;
};
testLevenshteinAtMostTwoDiff1DelRight = {
expr = strings.levenshteinAtMost 2 "abcdef" "zbcde";
expected = true;
};
testLevenshteinAtMostTwoDiff2False = {
expr = strings.levenshteinAtMost 2 "hello" "hxo";
expected = false;
};
testLevenshteinAtMostTwoDiff2True = {
expr = strings.levenshteinAtMost 2 "hello" "heo";
expected = true;
};
testLevenshteinAtMostTwoDiff3 = {
expr = strings.levenshteinAtMost 2 "hello" "ho";
expected = false;
};
testLevenshteinAtMostThreeFalse = {
expr = strings.levenshteinAtMost 3 "hello" "Holla!";
expected = false;
};
testLevenshteinAtMostThreeTrue = {
expr = strings.levenshteinAtMost 3 "hello" "Holla";
expected = true;
};
}

@ -166,6 +166,30 @@ rec {
/* Returns the current nixpkgs release number as string. */
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.
On each release the first letter is bumped and a new animal is chosen
@ -323,7 +347,14 @@ rec {
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
@ -347,6 +378,13 @@ rec {
*/
throwIfNot = cond: msg: if cond then x: x else throw msg;
/*
Like throwIfNot, but negated (throw if the first argument is `true`).
Type: bool -> string -> a -> a
*/
throwIf = cond: msg: if cond then throw msg else x: x;
/* Check if the elements in a list are valid values from a enum, returning the identity function, or throwing an error message otherwise.
Example:
@ -403,6 +441,25 @@ rec {
isFunction = f: builtins.isFunction f ||
(f ? __functor && isFunction (f.__functor f));
/*
Turns any non-callable values into constant functions.
Returns callable values as is.
Example:
nix-repl> lib.toFunction 1 2
1
nix-repl> lib.toFunction (x: x + 1) 2
3
*/
toFunction =
# Any value
v:
if isFunction v
then v
else k: v;
/* Convert the given positive integer to a string of its hexadecimal
representation. For example:

@ -749,14 +749,6 @@ rec {
nestedTypes.finalType = finalType;
};
# Obsolete alternative to configOf. It takes its option
# declarations from the ‘options’ attribute of containing option
# declaration.
optionSet = mkOptionType {
name = "optionSet";
description = "option set";
deprecationMessage = "Use `types.submodule' instead";
};
# Augment the given type with an additional type check function.
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };

@ -380,6 +380,12 @@
githubId = 209175;
name = "Alesya Huzik";
};
aidalgol = {
email = "aidalgol+nixpkgs@fastmail.net";
github = "aidalgol";
githubId = 2313201;
name = "Aidan Gauland";
};
aij = {
email = "aij+git@mrph.org";
github = "aij";
@ -669,6 +675,12 @@
githubId = 858965;
name = "Andrew Morsillo";
};
an-empty-string = {
name = "Tris Emmy Wilson";
email = "tris@tris.fyi";
github = "an-empty-string";
githubId = 681716;
};
andehen = {
email = "git@andehen.net";
github = "andehen";
@ -929,6 +941,12 @@
githubId = 1296771;
name = "Anders Riutta";
};
arjan-s = {
email = "github@anymore.nl";
github = "arjan-s";
githubId = 10400299;
name = "Arjan Schrijver";
};
arkivm = {
email = "vikram186@gmail.com";
github = "arkivm";
@ -1031,8 +1049,8 @@
name = "Kirill Boltaev";
};
ashley = {
email = "personavinny@protonmail.com";
github = "paranoidcat";
email = "ashley@kira64.xyz";
github = "kira64xyz";
githubId = 84152630;
name = "Ashley Chiara";
};
@ -1295,6 +1313,12 @@
githubId = 127523;
name = "Herman Fries";
};
BarinovMaxim = {
name = "Barinov Maxim";
email = "barinov274@gmail.com";
github = "barinov274";
githubId = 54442153;
};
barrucadu = {
email = "mike@barrucadu.co.uk";
github = "barrucadu";
@ -1782,6 +1806,12 @@
githubId = 7214361;
name = "Roman Gerasimenko";
};
builditluc = {
email = "builditluc@icloud.com";
github = "builditluc";
githubId = 37375448;
name = "Buildit";
};
bburdette = {
email = "bburdette@protonmail.com";
github = "bburdette";
@ -2071,12 +2101,6 @@
githubId = 18648043;
name = "Daniel Cartwright";
};
chiiruno = {
email = "okinan@protonmail.com";
github = "chiiruno";
githubId = 30435868;
name = "Okina Matara";
};
Chili-Man = {
email = "dr.elhombrechile@gmail.com";
name = "Diego Rodriguez";
@ -2818,6 +2842,12 @@
githubId = 49904992;
name = "Dawid Sowa";
};
dbeckwith = {
email = "djbsnx@gmail.com";
github = "dbeckwith";
githubId = 1279939;
name = "Daniel Beckwith";
};
dbirks = {
email = "david@birks.dev";
github = "dbirks";
@ -3819,6 +3849,13 @@
githubId = 222467;
name = "Dmitry Ivanov";
};
ethindp = {
name = "Ethin Probst";
email = "harlydavidsen@gmail.com";
matrix = "@ethindp:the-gdn.net";
github = "ethindp";
githubId = 8030501;
};
Etjean = {
email = "et.jean@outlook.fr";
github = "Etjean";
@ -4235,7 +4272,12 @@
githubId = 119691;
name = "Michael Gough";
};
freax13 = {
email = "erbse.13@gmx.de";
github = "freax13";
githubId = 14952658;
name = "Tom Dohrmann";
};
fredeb = {
email = "im@fredeb.dev";
github = "fredeeb";
@ -4479,6 +4521,12 @@
githubId = 3217744;
name = "Peter Ferenczy";
};
ghostbuster91 = {
name = "Kasper Kondzielski";
email = "kghost0@gmail.com";
github = "ghostbuster91";
githubId = 5662622;
};
ghuntley = {
email = "ghuntley@ghuntley.com";
github = "ghuntley";
@ -4633,6 +4681,12 @@
githubId = 4656860;
name = "Gaute Ravndal";
};
graysonhead = {
email = "grayson@graysonhead.net";
github = "graysonhead";
githubId = 6179496;
name = "Grayson Head";
};
grburst = {
email = "GRBurst@protonmail.com";
github = "GRBurst";
@ -4679,6 +4733,12 @@
githubId = 343415;
name = "Greg Roodt";
};
grnnja = {
email = "grnnja@gmail.com";
github = "grnnja";
githubId = 31556469;
name = "Prem Netsuwan";
};
gruve-p = {
email = "groestlcoin@gmail.com";
github = "gruve-p";
@ -5394,6 +5454,12 @@
githubId = 41924494;
name = "Ivar";
};
iwanb = {
email = "tracnar@gmail.com";
github = "iwanb";
githubId = 4035835;
name = "Iwan";
};
ixmatus = {
email = "parnell@digitalmentat.com";
github = "ixmatus";
@ -5869,6 +5935,12 @@
githubId = 587870;
name = "Jonathan Mettes";
};
jmgilman = {
email = "joshuagilman@gmail.com";
github = "jmgilman";
githubId = 2308444;
name = "Joshua Gilman";
};
jo1gi = {
email = "joakimholm@protonmail.com";
github = "jo1gi";
@ -7131,6 +7203,13 @@
githubId = 714;
name = "Lily Ballard";
};
lilyinstarlight = {
email = "lily@lily.flowers";
matrix = "@lily:lily.flowers";
github = "lilyinstarlight";
githubId = 298109;
name = "Lily Foster";
};
limeytexan = {
email = "limeytexan@gmail.com";
github = "limeytexan";
@ -7241,6 +7320,17 @@
githubId = 1267527;
name = "Daniel Firth";
};
lockejan = {
email = "git@smittie.de";
matrix = "@jan:smittie.de";
github = "lockejan";
githubId = 25434434;
name = "Jan Schmitt";
keys = [{
longkeyid = "dsa2048/0xA2BC3C6F14351991";
fingerprint = "1763 9903 2D7C 5B82 5D5A 0EAD A2BC 3C6F 1435 1991";
}];
};
lodi = {
email = "anthony.lodi@gmail.com";
github = "lodi";
@ -7248,7 +7338,7 @@
name = "Anthony Lodi";
};
loicreynier = {
email = "loic@loireynier.fr";
email = "loic@loicreynier.fr";
github = "loicreynier";
githubId = 88983487;
name = "Loïc Reynier";
@ -8039,6 +8129,12 @@
githubId = 20536514;
name = "Magdalena Haselsteiner";
};
mh182 = {
email = "mh182@chello.at";
github = "mh182";
githubId = 9980864;
name = "Max Hofer";
};
mic92 = {
email = "joerg@thalheim.io";
matrix = "@mic92:nixos.dev";
@ -8212,6 +8308,17 @@
githubId = 1776903;
name = "Andrew Abbott";
};
misterio77 = {
email = "eu@misterio.me";
github = "misterio77";
githubId = 5727578;
matrix = "@misterio:matrix.org";
name = "Gabriel Fontes";
keys = [{
longkeyid = "rsa3072/0x245CAB70B4C225E9";
fingerprint = "7088 C742 1873 E0DB 97FF 17C2 245C AB70 B4C2 25E9";
}];
};
mitchmindtree = {
email = "mail@mitchellnordine.com";
github = "mitchmindtree";
@ -8509,7 +8616,7 @@
};
msfjarvis = {
github = "msfjarvis";
githubId = 3348378;
githubId = 13348378;
name = "Harsh Shandilya";
email = "nixos@msfjarvis.dev";
keys = [{
@ -8763,6 +8870,12 @@
githubId = 3747396;
name = "Nathan Isom";
};
neilmayhew = {
email = "nix@neil.mayhew.name";
github = "neilmayhew";
githubId = 166791;
name = "Neil Mayhew";
};
nelsonjeppesen = {
email = "nix@jeppesen.io";
github = "NelsonJeppesen";
@ -9870,6 +9983,12 @@
fingerprint = "2CD2 B030 BD22 32EF DF5A 008A 3618 20A4 5DB4 1E9A";
}];
};
podocarp = {
email = "xdjiaxd@gmail.com";
github = "podocarp";
githubId = 10473184;
name = "Jia Xiaodong";
};
polendri = {
email = "paul@ijj.li";
github = "polendri";
@ -9910,6 +10029,12 @@
fingerprint = "48AD DE10 F27B AFB4 7BB0 CCAF 2D25 95A0 0D08 ACE0";
}];
};
ppenguin = {
name = "Jeroen Versteeg";
email = "hieronymusv@gmail.com";
github = "ppenguin";
githubId = 17690377;
};
ppom = {
name = "Paco Pompeani";
email = "paco@ecomail.io";
@ -10123,6 +10248,12 @@
githubId = 115877;
name = "Kenny Shen";
};
quag = {
email = "quaggy@gmail.com";
github = "quag";
githubId = 35086;
name = "Jonathan Wright";
};
queezle = {
email = "git@queezle.net";
github = "qzle";
@ -10266,6 +10397,16 @@
githubId = 16487165;
name = "Rafael Basso";
};
rbreslow = {
name = "Rocky Breslow";
email = "1774125+rbreslow@users.noreply.github.com";
github = "rbreslow";
githubId = 1774125;
keys = [{
longkeyid = "ed25519/0xA0D32ACCA38B88ED";
fingerprint = "B5B7 BCA0 EE6F F31E 263A 69E3 A0D3 2ACC A38B 88ED";
}];
};
rbrewer = {
email = "rwb123@gmail.com";
github = "rbrewer123";
@ -10398,6 +10539,12 @@
githubId = 811827;
name = "Gabriel Lievano";
};
rgrinberg = {
name = "Rudi Grinberg";
email = "me@rgrinberg.com";
github = "rgrinberg";
githubId = 139003;
};
rgrunbla = {
email = "remy@grunblatt.org";
github = "rgrunbla";
@ -10927,28 +11074,22 @@
githubId = 132835;
name = "Samuel Dionne-Riel";
};
samuelgrf = {
email = "s@muel.gr";
github = "samuelgrf";
githubId = 67663538;
name = "Samuel Gräfenstein";
keys = [
{
longkeyid = "rsa4096/0xDE75F92E318123F0";
fingerprint = "6F2E 2A90 423C 8111 BFF2 895E DE75 F92E 3181 23F0";
}
{
longkeyid = "rsa4096/0xEF76A063F15C63C8";
fingerprint = "FF24 5832 8FAF 4660 18C6 186E EF76 A063 F15C 63C8";
}
];
};
samuelrivas = {
email = "samuelrivas@gmail.com";
github = "samuelrivas";
githubId = 107703;
name = "Samuel Rivas";
};
samyak = {
name = "Samyak Sarnayak";
email = "samyak201@gmail.com";
github = "Samyak2";
githubId = 34161949;
keys = [{
longkeyid = "rsa4096/0x365873F2F0C6153B";
fingerprint = "155C F413 0129 C058 9A5F 5524 3658 73F2 F0C6 153B";
}];
};
sander = {
email = "s.vanderburg@tudelft.nl";
github = "svanderburg";
@ -11055,6 +11196,16 @@
email = "schristopher@konputa.com";
name = "Scott Christopher";
};
sciencentistguy = {
email = "jamie@quigley.xyz";
name = "Jamie Quigley";
github = "Sciencentistguy";
githubId = 4983935;
keys = [{
longkeyid = "rsa2048/0x8E8FF66E2AE8D970";
fingerprint = "30BB FF3F AB0B BB3E 0435 F83C 8E8F F66E 2AE8 D970";
}];
};
scode = {
email = "peter.schuller@infidyne.com";
github = "scode";
@ -11209,6 +11360,12 @@
githubId = 1151264;
name = "Sebastian Graf";
};
shadaj = {
email = "shadaj@users.noreply.github.com";
github = "shadaj";
githubId = 543055;
name = "Shadaj Laddad";
};
shahrukh330 = {
email = "shahrukh330@gmail.com";
github = "shahrukh330";
@ -11249,6 +11406,12 @@
githubId = 293035;
name = "Shawn Dellysse";
};
shawn8901 = {
email = "shawn8901@googlemail.com";
github = "shawn8901";
githubId = 12239057;
name = "Shawn8901";
};
shazow = {
email = "andrey.petrov@shazow.net";
github = "shazow";
@ -11399,6 +11562,12 @@
githubId = 2770647;
name = "Simon Vandel Sillesen";
};
sir4ur0n = {
email = "sir4ur0n@users.noreply.github.com";
github = "sir4ur0n";
githubId = 1204125;
name = "sir4ur0n";
};
siraben = {
email = "bensiraphob@gmail.com";
matrix = "@siraben:matrix.org";
@ -12742,6 +12911,12 @@
githubId = 1983821;
name = "Eric Wolf";
};
uakci = {
name = "uakci";
email = "uakci@uakci.pl";
github = "uakci";
githubId = 6961268;
};
udono = {
email = "udono@virtual-things.biz";
github = "udono";
@ -13169,6 +13344,12 @@
githubId = 34962284;
name = "wchresta";
};
wdavidw = {
name = "David Worms";
email = "david@adaltas.com";
github = "wdavidw";
githubId = 46896;
};
wedens = {
email = "kirill.wedens@gmail.com";
name = "wedens";
@ -14063,6 +14244,12 @@
github = "zbioe";
githubId = 7332055;
};
zendo = {
name = "zendo";
email = "linzway@qq.com";
github = "zendo";
githubId = 348013;
};
zenithal = {
name = "zenithal";
email = "i@zenithal.me";
@ -14171,4 +14358,22 @@
github = "nigelgbanks";
githubId = 487373;
};
zanculmarktum = {
name = "Azure Zanculmarktum";
email = "zanculmarktum@gmail.com";
github = "zanculmarktum";
githubId = 16958511;
};
kuwii = {
name = "kuwii";
email = "kuwii.someone@gmail.com";
github = "kuwii";
githubId = 10705175;
};
melias122 = {
name = "Martin Elias";
email = "martin+nixpkgs@elias.sx";
github = "melias122";
githubId = 1027766;
};
}

@ -9,7 +9,7 @@ tmp=$(mktemp --tmpdir -d nixpkgs-dep-license.XXXXXX)
exitHandler() {
exitCode=$?
rm -rf "$tmp"
exit $exitCode
return $exitCode
}
trap "exitHandler" EXIT

@ -0,0 +1,98 @@
#!/usr/bin/env nix-shell
#!nix-shell -i perl -p perl -p perlPackages.JSON perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.TermReadKey
# This script generates a list of teams to ping for the Feature Freeze announcement on Discourse.
# It's intended to be used by Release Managers before creating such posts.
#
# The script interactively reads a GitHub username and a corresponding GitHub Personal Access token.
# This is required to access the GitHub Teams API so the token needs at least the read:org privilege.
## no critic (InputOutput::RequireCheckedSyscalls, InputOutput::ProhibitBacktickOperators)
use strict;
use warnings;
use Carp;
use Cwd 'abs_path';
use File::Basename;
use JSON qw(decode_json);
use LWP::UserAgent;
use Term::ReadKey qw(ReadLine ReadMode);
sub github_team_members {
my ($team_name, $username, $token) = @_;
my @ret;
my $req = HTTP::Request->new('GET', "https://api.github.com/orgs/NixOS/teams/$team_name/members", [ 'Accept' => 'application/vnd.github.v3+json' ]);
$req->authorization_basic($username, $token);
my $response = LWP::UserAgent->new->request($req);
if ($response->is_success) {
my $content = decode_json($response->decoded_content);
foreach (@{$content}) {
push @ret, $_->{'login'};
}
} else {
print {*STDERR} "!! Requesting members of GitHub Team '$team_name' failed: $response->status_line";
}
return \@ret;
}
# Read GitHub credentials
print {*STDERR} 'GitHub username: ';
my $github_user = ReadLine(0);
ReadMode('noecho');
print {*STDERR} 'GitHub personal access token (no echo): ';
my $github_token = ReadLine(0);
ReadMode('restore');
print {*STDERR} "\n";
chomp $github_user;
chomp $github_token;
# Read nix output
my $nix_version = `nix --version`;
my $out;
my $lib_path = abs_path(dirname(__FILE__)) . '../../../lib';
if ($nix_version =~ m/2[.]3[.]/msx) {
$out = `nix eval --json '(import $lib_path).teams'` || croak 'nix eval failed';
} else {
$out = `nix --extra-experimental-features nix-command eval --json --impure --expr '(import $lib_path).teams'` || croak('nix eval failed');
}
my $data = decode_json($out);
# Process teams
print {*STDERR} "\n";
while (my ($team_nix_key, $team_config) = each %{$data}) {
# Ignore teams that don't want to be or can't be pinged
if (not defined $team_config->{enableFeatureFreezePing} or not $team_config->{enableFeatureFreezePing}) {
next;
}
if (not defined $team_config->{shortName}) {
print {*STDERR} "!! The team with the nix key '$team_nix_key' has no shortName set - ignoring";
next;
}
# Team name
print {*STDERR} "$team_config->{shortName}:";
# GitHub Teams
my @github_members;
if (defined $team_config->{githubTeams}) {
foreach (@{$team_config->{githubTeams}}) {
print {*STDERR} " \@NixOS/${_}";
push @github_members, @{github_team_members($_, $github_user, $github_token)};
}
}
my %github_members = map { $_ => 1 } @github_members;
# Members
if (defined $team_config->{members}) {
foreach (@{$team_config->{members}}) {
my %user = %{$_};
my $github_handle = $user{'github'};
# Ensure we don't ping team members twice (as team member and directly)
if (defined $github_members{$github_handle}) {
next;
}
print {*STDERR} " \@$github_handle";
}
}
print {*STDERR} "\n";
}

@ -0,0 +1,22 @@
let
nixpkgs = import ../../..;
inherit (nixpkgs {}) haskellPackages lib;
maintainedPkgs = lib.filterAttrs (
_: v: builtins.length (v.meta.maintainers or []) > 0
) haskellPackages;
brokenPkgs = lib.filterAttrs (_: v: v.meta.broken) maintainedPkgs;
transitiveBrokenPkgs = lib.filterAttrs
(_: v: !(builtins.tryEval (v.outPath or null)).success && !v.meta.broken)
maintainedPkgs;
infoList = pkgs: lib.concatStringsSep "\n" (lib.mapAttrsToList (name: drv: "${name} ${(builtins.elemAt drv.meta.maintainers 0).github}") pkgs);
in {
report = ''
BROKEN:
${infoList brokenPkgs}
TRANSITIVE BROKEN:
${infoList transitiveBrokenPkgs}
'';
transitiveErrors =
builtins.attrValues transitiveBrokenPkgs;
}

@ -99,7 +99,7 @@ This PR is the regular merge of the \`haskell-updates\` branch into \`master\`.
This branch is being continually built and tested by hydra at https://hydra.nixos.org/jobset/nixpkgs/haskell-updates. You may be able to find an up-to-date Hydra build report at [cdepillabout/nix-haskell-updates-status](https://github.com/cdepillabout/nix-haskell-updates-status).
We roughly aim to merge these \`haskell-updates\` PRs at least once every two weeks. See the @NixOS/haskell [team calendar](https://cloud.maralorn.de/apps/calendar/p/Mw5WLnzsP7fC4Zky) for who is currently in charge of this branch.
We roughly aim to merge these \`haskell-updates\` PRs at least once every two weeks. See the @NixOS/haskell [team calendar](https://cloud.maralorn.de/apps/calendar/p/H6migHmKX7xHoTFa) for who is currently in charge of this branch.
### haskellPackages Workflow Summary

@ -1,26 +1,38 @@
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p nix curl jq nix-prefetch-github git gnused gnugrep -I nixpkgs=.
# shellcheck shell=bash
set -eu -o pipefail
tmpfile=$(mktemp "update-stackage.XXXXXXX")
# shellcheck disable=SC2064
# Stackage solver to use, LTS or Nightly
# (should be capitalized like the display name)
SOLVER=LTS
TMP_TEMPLATE=update-stackage.XXXXXXX
readonly SOLVER
readonly TMP_TEMPLATE
toLower() {
printf "%s" "$1" | tr '[:upper:]' '[:lower:]'
}
tmpfile=$(mktemp "$TMP_TEMPLATE")
tmpfile_new=$(mktemp "$TMP_TEMPLATE")
stackage_config="pkgs/development/haskell-modules/configuration-hackage2nix/stackage.yaml"
trap "rm ${tmpfile} ${tmpfile}.new" 0
touch "$tmpfile" "$tmpfile.new" # Creating files here so that trap creates no errors.
trap 'rm "${tmpfile}" "${tmpfile_new}"' 0
touch "$tmpfile" "$tmpfile_new" # Creating files here so that trap creates no errors.
curl -L -s "https://stackage.org/lts/cabal.config" >"$tmpfile"
old_version=$(grep "# Stackage" $stackage_config | sed -E 's/.*([0-9]{2}\.[0-9]+)/\1/')
version=$(sed -rn "s/^--.*http:..(www.)?stackage.org.snapshot.lts-//p" "$tmpfile")
curl -L -s "https://stackage.org/$(toLower "$SOLVER")/cabal.config" >"$tmpfile"
old_version=$(grep '^# Stackage' $stackage_config | sed -e 's/.\+ \([A-Za-z]\+ [0-9.-]\+\)$/\1/g')
version="$SOLVER $(sed -rn "s/^--.*http:..(www.)?stackage.org.snapshot.$(toLower "$SOLVER")-//p" "$tmpfile")"
if [[ "$old_version" == "$version" ]]; then
echo "No new stackage version"
exit 0 # Nothing to do
fi
echo "Updating Stackage LTS from $old_version to $version."
echo "Updating Stackage from $old_version to $version."
# Create a simple yaml version of the file.
sed -r \
@ -30,10 +42,10 @@ sed -r \
-e 's|,$||' \
-e '/installed$/d' \
-e '/^$/d' \
< "${tmpfile}" | sort --ignore-case >"${tmpfile}.new"
< "${tmpfile}" | sort --ignore-case >"${tmpfile_new}"
cat > $stackage_config << EOF
# Stackage LTS $version
# Stackage $version
# This file is auto-generated by
# maintainers/scripts/haskell/update-stackage.sh
default-package-overrides:
@ -45,12 +57,13 @@ sed -r \
-e '/ distribution-nixpkgs /d' \
-e '/ jailbreak-cabal /d' \
-e '/ language-nix /d' \
< "${tmpfile}.new" >> $stackage_config
-e '/ cabal-install /d' \
< "${tmpfile_new}" >> $stackage_config
if [[ "${1:-}" == "--do-commit" ]]; then
git add $stackage_config
git commit -F - << EOF
haskellPackages: stackage-lts $old_version -> $version
haskellPackages: stackage $old_version -> $version
This commit has been generated by maintainers/scripts/haskell/update-stackage.sh
EOF

@ -81,6 +81,6 @@ rapidjson,https://github.com/xpol/lua-rapidjson.git,,,,,
readline,,,,,,
say,https://github.com/Olivine-Labs/say.git,,,,,
std._debug,https://github.com/lua-stdlib/_debug.git,,,,,
std.normalize,git://github.com/lua-stdlib/normalize.git,,,,,
std.normalize,https://github.com/lua-stdlib/normalize.git,,,,,
stdlib,,,,41.2.2,,vyp
vstruct,https://github.com/ToxicFrog/vstruct.git,,,,,

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

@ -8,6 +8,7 @@
# $ nix run nixpkgs.python3Packages.flake8 -c flake8 --ignore E501,E265 update.py
import argparse
import csv
import functools
import http
import json
@ -28,7 +29,7 @@ from pathlib import Path
from typing import Dict, List, Optional, Tuple, Union, Any, Callable
from urllib.parse import urljoin, urlparse
from tempfile import NamedTemporaryFile
from dataclasses import dataclass
from dataclasses import dataclass, asdict
import git
@ -85,21 +86,30 @@ def make_request(url: str, token=None) -> urllib.request.Request:
headers["Authorization"] = f"token {token}"
return urllib.request.Request(url, headers=headers)
Redirects = Dict['Repo', 'Repo']
class Repo:
def __init__(
self, uri: str, branch: str, alias: Optional[str]
self, uri: str, branch: str
) -> None:
self.uri = uri
'''Url to the repo'''
self.branch = branch
self.alias = alias
self.redirect: Dict[str, str] = {}
self._branch = branch
# {old_uri: new_uri}
self.redirect: Redirects = {}
self.token = "dummy_token"
@property
def name(self):
return self.uri.split('/')[-1]
@property
def branch(self):
return self._branch or "HEAD"
def __str__(self) -> str:
return f"{self.uri}"
def __repr__(self) -> str:
return f"Repo({self.name}, {self.uri})"
@ -109,6 +119,7 @@ class Repo:
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
def latest_commit(self) -> Tuple[str, datetime]:
log.debug("Latest commit")
loaded = self._prefetch(None)
updated = datetime.strptime(loaded['date'], "%Y-%m-%dT%H:%M:%S%z")
@ -124,6 +135,7 @@ class Repo:
return loaded
def prefetch(self, ref: Optional[str]) -> str:
print("Prefetching")
loaded = self._prefetch(ref)
return loaded["sha256"]
@ -137,21 +149,22 @@ class Repo:
class RepoGitHub(Repo):
def __init__(
self, owner: str, repo: str, branch: str, alias: Optional[str]
self, owner: str, repo: str, branch: str
) -> None:
self.owner = owner
self.repo = repo
self.token = None
'''Url to the repo'''
super().__init__(self.url(""), branch, alias)
log.debug("Instantiating github repo %s/%s", self.owner, self.repo)
super().__init__(self.url(""), branch)
log.debug("Instantiating github repo owner=%s and repo=%s", self.owner, self.repo)
@property
def name(self):
return self.repo
def url(self, path: str) -> str:
return urljoin(f"https://github.com/{self.owner}/{self.name}/", path)
res = urljoin(f"https://github.com/{self.owner}/{self.repo}/", path)
return res
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
def has_submodules(self) -> bool:
@ -168,6 +181,7 @@ class RepoGitHub(Repo):
@retry(urllib.error.URLError, tries=4, delay=3, backoff=2)
def latest_commit(self) -> Tuple[str, datetime]:
commit_url = self.url(f"commits/{self.branch}.atom")
log.debug("Sending request to %s", commit_url)
commit_req = make_request(commit_url, self.token)
with urllib.request.urlopen(commit_req, timeout=10) as req:
self._check_for_redirect(commit_url, req)
@ -191,12 +205,9 @@ class RepoGitHub(Repo):
new_owner, new_name = (
urllib.parse.urlsplit(response_url).path.strip("/").split("/")[:2]
)
end_line = "\n" if self.alias is None else f" as {self.alias}\n"
plugin_line = "{owner}/{name}" + end_line
old_plugin = plugin_line.format(owner=self.owner, name=self.name)
new_plugin = plugin_line.format(owner=new_owner, name=new_name)
self.redirect[old_plugin] = new_plugin
new_repo = RepoGitHub(owner=new_owner, repo=new_name, branch=self.branch)
self.redirect[self] = new_repo
def prefetch(self, commit: str) -> str:
@ -207,9 +218,9 @@ class RepoGitHub(Repo):
return sha256
def prefetch_github(self, ref: str) -> str:
data = subprocess.check_output(
["nix-prefetch-url", "--unpack", self.url(f"archive/{ref}.tar.gz")]
)
cmd = ["nix-prefetch-url", "--unpack", self.url(f"archive/{ref}.tar.gz")]
log.debug("Running %s", cmd)
data = subprocess.check_output(cmd)
return data.strip().decode("utf-8")
def as_nix(self, plugin: "Plugin") -> str:
@ -239,21 +250,38 @@ class PluginDesc:
else:
return self.alias
def __lt__(self, other):
return self.repo.name < other.repo.name
@staticmethod
def load_from_csv(config: FetchConfig, row: Dict[str, str]) -> 'PluginDesc':
branch = row["branch"]
repo = make_repo(row['repo'], branch.strip())
repo.token = config.github_token
return PluginDesc(repo, branch.strip(), row["alias"])
@staticmethod
def load_from_string(config: FetchConfig, line: str) -> 'PluginDesc':
branch = "HEAD"
alias = None
uri = line
if " as " in uri:
uri, alias = uri.split(" as ")
alias = alias.strip()
if "@" in uri:
uri, branch = uri.split("@")
repo = make_repo(uri.strip(), branch.strip())
repo.token = config.github_token
return PluginDesc(repo, branch.strip(), alias)
@dataclass
class Plugin:
def __init__(
self,
name: str,
commit: str,
has_submodules: bool,
sha256: str,
date: Optional[datetime] = None,
) -> None:
self.name = name
self.commit = commit
self.has_submodules = has_submodules
self.sha256 = sha256
self.date = date
name: str
commit: str
has_submodules: bool
sha256: str
date: Optional[datetime] = None
@property
def normalized_name(self) -> str:
@ -270,6 +298,17 @@ class Plugin:
return copy
def load_plugins_from_csv(config: FetchConfig, input_file: Path,) -> List[PluginDesc]:
log.debug("Load plugins from csv %s", input_file)
plugins = []
with open(input_file, newline='') as csvfile:
log.debug("Writing into %s", input_file)
reader = csv.DictReader(csvfile,)
for line in reader:
plugin = PluginDesc.load_from_csv(config, line)
plugins.append(plugin)
return plugins
class Editor:
"""The configuration of the update script."""
@ -298,14 +337,8 @@ class Editor:
return get_current_plugins(self)
def load_plugin_spec(self, config: FetchConfig, plugin_file) -> List[PluginDesc]:
plugins = []
with open(plugin_file) as f:
for line in f:
if line.startswith("#"):
continue
plugin = parse_plugin_line(config, line)
plugins.append(plugin)
return plugins
'''CSV spec'''
return load_plugins_from_csv(config, plugin_file)
def generate_nix(self, plugins, outfile: str):
'''Returns nothing for now, writes directly to outfile'''
@ -316,11 +349,11 @@ class Editor:
_prefetch = functools.partial(prefetch, cache=cache)
def update() -> dict:
plugin_names = self.load_plugin_spec(config, input_file)
plugins = self.load_plugin_spec(config, input_file)
try:
pool = Pool(processes=config.proc)
results = pool.map(_prefetch, plugin_names)
results = pool.map(_prefetch, plugins)
finally:
cache.store()
@ -423,6 +456,7 @@ def get_current_plugins(editor: Editor) -> List[Plugin]:
data = json.loads(out)
plugins = []
for name, attr in data.items():
print("get_current_plugins: name %s" % name)
p = Plugin(name, attr["rev"], attr["submodules"], attr["sha256"])
plugins.append(p)
return plugins
@ -431,7 +465,7 @@ def get_current_plugins(editor: Editor) -> List[Plugin]:
def prefetch_plugin(
p: PluginDesc,
cache: "Optional[Cache]" = None,
) -> Tuple[Plugin, Dict[str, str]]:
) -> Tuple[Plugin, Redirects]:
repo, branch, alias = p.repo, p.branch, p.alias
name = alias or p.repo.name
commit = None
@ -454,11 +488,6 @@ def prefetch_plugin(
)
def fetch_plugin_from_pluginline(config: FetchConfig, plugin_line: str) -> Plugin:
plugin, _ = prefetch_plugin(parse_plugin_line(config, plugin_line))
return plugin
def print_download_error(plugin: str, ex: Exception):
print(f"{plugin}: {ex}", file=sys.stderr)
ex_traceback = ex.__traceback__
@ -468,14 +497,14 @@ def print_download_error(plugin: str, ex: Exception):
]
print("\n".join(tb_lines))
def check_results(
results: List[Tuple[PluginDesc, Union[Exception, Plugin], Dict[str, str]]]
) -> Tuple[List[Tuple[PluginDesc, Plugin]], Dict[str, str]]:
results: List[Tuple[PluginDesc, Union[Exception, Plugin], Redirects]]
) -> Tuple[List[Tuple[PluginDesc, Plugin]], Redirects]:
''' '''
failures: List[Tuple[str, Exception]] = []
plugins = []
redirects: Dict[str, str] = {}
# {old: new} plugindesc
redirects: Dict[Repo, Repo] = {}
for (pdesc, result, redirect) in results:
if isinstance(result, Exception):
failures.append((pdesc.name, result))
@ -495,31 +524,17 @@ def check_results(
sys.exit(1)
def make_repo(uri, branch, alias) -> Repo:
def make_repo(uri: str, branch) -> Repo:
'''Instantiate a Repo with the correct specialization depending on server (gitub spec)'''
# dumb check to see if it's of the form owner/repo (=> github) or https://...
res = uri.split('/')
if len(res) <= 2:
repo = RepoGitHub(res[0], res[1], branch, alias)
res = urlparse(uri)
if res.netloc in [ "github.com", ""]:
res = res.path.strip('/').split('/')
repo = RepoGitHub(res[0], res[1], branch)
else:
repo = Repo(uri.strip(), branch, alias)
repo = Repo(uri.strip(), branch)
return repo
def parse_plugin_line(config: FetchConfig, line: str) -> PluginDesc:
branch = "HEAD"
alias = None
uri = line
if " as " in uri:
uri, alias = uri.split(" as ")
alias = alias.strip()
if "@" in uri:
uri, branch = uri.split("@")
repo = make_repo(uri.strip(), branch.strip(), alias)
repo.token = config.github_token
return PluginDesc(repo, branch.strip(), alias)
def get_cache_path(cache_file_name: str) -> Optional[Path]:
xdg_cache = os.environ.get("XDG_CACHE_HOME", None)
@ -585,27 +600,27 @@ def prefetch(
return (pluginDesc, e, {})
def rewrite_input(
config: FetchConfig,
input_file: Path,
deprecated: Path,
redirects: Dict[str, str] = None,
append: Tuple = (),
# old pluginDesc and the new
redirects: Dict[PluginDesc, PluginDesc] = {},
append: List[PluginDesc] = [],
):
with open(input_file, "r") as f:
lines = f.readlines()
plugins = load_plugins_from_csv(config, input_file,)
lines.extend(append)
plugins.extend(append)
if redirects:
lines = [redirects.get(line, line) for line in lines]
cur_date_iso = datetime.now().strftime("%Y-%m-%d")
with open(deprecated, "r") as f:
deprecations = json.load(f)
for old, new in redirects.items():
old_plugin = fetch_plugin_from_pluginline(config, old)
new_plugin = fetch_plugin_from_pluginline(config, new)
old_plugin, _ = prefetch_plugin(old)
new_plugin, _ = prefetch_plugin(new)
if old_plugin.normalized_name != new_plugin.normalized_name:
deprecations[old_plugin.normalized_name] = {
"new": new_plugin.normalized_name,
@ -615,10 +630,14 @@ def rewrite_input(
json.dump(deprecations, f, indent=4, sort_keys=True)
f.write("\n")
lines = sorted(lines, key=str.casefold)
with open(input_file, "w") as f:
f.writelines(lines)
log.debug("Writing into %s", input_file)
# fields = dataclasses.fields(PluginDesc)
fieldnames = ['repo', 'branch', 'alias']
writer = csv.DictWriter(f, fieldnames, dialect='unix', quoting=csv.QUOTE_NONE)
writer.writeheader()
for plugin in sorted(plugins):
writer.writerow(asdict(plugin))
def commit(repo: git.Repo, message: str, files: List[Path]) -> None:
@ -660,9 +679,11 @@ def update_plugins(editor: Editor, args):
)
for plugin_line in args.add_plugins:
editor.rewrite_input(fetch_config, args.input_file, editor.deprecated, append=(plugin_line + "\n",))
pdesc = PluginDesc.load_from_string(fetch_config, plugin_line)
append = [ pdesc ]
editor.rewrite_input(fetch_config, args.input_file, editor.deprecated, append=append)
update()
plugin = fetch_plugin_from_pluginline(fetch_config, plugin_line)
plugin, _ = prefetch_plugin(pdesc, )
if autocommit:
commit(
nixpkgs_repo,

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

@ -3,12 +3,19 @@
# Required
members = [ maintainer1 maintainer2 ];
scope = "Maintain foo packages.";
shortName = "foo";
# Optional
enableFeatureFreezePing = true;
githubTeams = [ "my-subsystem" ];
};
where
- `members` is the list of maintainers belonging to the group,
- `scope` describes the scope of the group.
- `shortName` short human-readable name
- `enableFeatureFreezePing` will ping this team during the Feature Freeze announcements on releases
- `githubTeams` will ping specified GitHub teams as well
More fields may be added in the future.
@ -27,6 +34,7 @@ with lib.maintainers; {
m1cr0man
];
scope = "Maintain ACME-related packages and modules.";
shortName = "ACME";
};
bazel = {
@ -41,6 +49,8 @@ with lib.maintainers; {
ylecornec
];
scope = "Bazel build tool & related tools https://bazel.build/";
shortName = "Bazel";
enableFeatureFreezePing = true;
};
beam = {
@ -53,7 +63,32 @@ with lib.maintainers; {
minijackson
yurrriq
];
githubTeams = [
"beam"
];
scope = "Maintain BEAM-related packages and modules.";
shortName = "BEAM";
enableFeatureFreezePing = true;
};
blockchains = {
members = [
mmahut
RaghavSood
];
scope = "Maintain Blockchain packages and modules.";
shortName = "Blockchains";
enableFeatureFreezePing = true;
};
c = {
members = [
matthewbauer
mic92
];
scope = "Maintain C libraries and tooling.";
shortName = "C";
enableFeatureFreezePing = true;
};
cinnamon = {
@ -61,6 +96,8 @@ with lib.maintainers; {
mkg20001
];
scope = "Maintain Cinnamon desktop environment and applications made by the LinuxMint team.";
shortName = "Cinnamon";
enableFeatureFreezePing = true;
};
chia = {
@ -68,6 +105,40 @@ with lib.maintainers; {
lourkeur
];
scope = "Maintain the Chia blockchain and its dependencies";
shortName = "Chia Blockchain";
};
coq = {
members = [
cohencyril
Zimmi48
# gares has no entry in the maintainers list
siraben
vbgl
];
scope = "Maintain the Coq theorem prover and related packages.";
shortName = "Coq";
enableFeatureFreezePing = true;
};
darwin = {
members = [
toonn
];
githubTeams = [
"darwin-maintainers"
];
scope = "Maintain Darwin compatibility of packages and Darwin-only packages.";
shortName = "Darwin";
enableFeatureFreezePing = true;
};
cosmopolitan = {
members = [
lourkeur
tomberek
];
scope = "Maintain the Cosmopolitan LibC and related programs.";
};
deshaw = {
@ -76,6 +147,7 @@ with lib.maintainers; {
limeytexan
];
scope = "Group registration for D. E. Shaw employees who collectively maintain packages.";
shortName = "Shaw employees";
};
determinatesystems = {
@ -85,11 +157,63 @@ with lib.maintainers; {
grahamc
];
scope = "Group registration for packages maintained by Determinate Systems.";
shortName = "Determinate Systems employees";
};
dhall = {
members = [
Gabriel439
ehmry
];
scope = "Maintain Dhall and related packages.";
shortName = "Dhall";
enableFeatureFreezePing = true;
};
docker = {
members = [
roberth
utdemir
];
scope = "Maintain Docker and related tools.";
shortName = "DockerTools";
enableFeatureFreezePing = true;
};
docs = {
members = [
ryantm
];
scope = "Maintain nixpkgs/NixOS documentation and tools for building it.";
shortName = "Docs";
enableFeatureFreezePing = true;
};
emacs = {
members = [
adisbladis
];
scope = "Maintain the Emacs editor and packages.";
shortName = "Emacs";
enableFeatureFreezePing = true;
};
# Dummy group for the "everyone else" section
feature-freeze-everyone-else = {
members = [ ];
githubTeams = [
"nixpkgs-committers"
"release-engineers"
];
scope = "Dummy team for the #everyone else' section during feture freezes, not to be used as package maintainers!";
shortName = "Everyone else";
enableFeatureFreezePing = true;
};
freedesktop = {
members = [ jtojnar ];
scope = "Maintain Freedesktop.org packages for graphical desktop.";
shortName = "freedesktop.org packaging";
};
gcc = {
@ -99,6 +223,7 @@ with lib.maintainers; {
ericson2314
];
scope = "Maintain GCC (GNU Compiler Collection) compilers";
shortName = "GCC";
};
golang = {
@ -113,16 +238,24 @@ with lib.maintainers; {
zowoq
];
scope = "Maintain Golang compilers.";
shortName = "Go";
enableFeatureFreezePing = true;
};
gnome = {
members = [
bobby285271
hedning
jtojnar
dasj19
maxeaubrey
];
githubTeams = [
"gnome"
];
scope = "Maintain GNOME desktop environment and platform.";
shortName = "GNOME";
enableFeatureFreezePing = true;
};
haskell = {
@ -132,7 +265,12 @@ with lib.maintainers; {
maralorn
sternenseemann
];
githubTeams = [
"haskell"
];
scope = "Maintain Haskell packages and infrastructure.";
shortName = "Haskell";
enableFeatureFreezePing = true;
};
home-assistant = {
@ -143,6 +281,7 @@ with lib.maintainers; {
mic92
];
scope = "Maintain the Home Assistant ecosystem";
shortName = "Home Assistant";
};
iog = {
@ -154,6 +293,7 @@ with lib.maintainers; {
nrdxp
];
scope = "Input-Output Global employees, which maintain critical software";
shortName = "Input-Output Global employees";
};
jitsi = {
@ -164,6 +304,7 @@ with lib.maintainers; {
yuka
];
scope = "Maintain Jitsi.";
shortName = "Jitsi";
};
kubernetes = {
@ -175,6 +316,7 @@ with lib.maintainers; {
zowoq
];
scope = "Maintain the Kubernetes package and module";
shortName = "Kubernetes";
};
kodi = {
@ -187,6 +329,7 @@ with lib.maintainers; {
sephalon
];
scope = "Maintain Kodi and related packages.";
shortName = "Kodi";
};
linux-kernel = {
@ -197,6 +340,17 @@ with lib.maintainers; {
qyliss
];
scope = "Maintain the Linux kernel.";
shortName = "Linux Kernel";
};
marketing = {
members = [
garbas
tomberek
];
scope = "Marketing of Nix/NixOS/nixpkgs.";
shortName = "Marketing";
enableFeatureFreezePing = true;
};
mate = {
@ -205,6 +359,7 @@ with lib.maintainers; {
romildo
];
scope = "Maintain Mate desktop environment and related packages.";
shortName = "MATE";
};
matrix = {
@ -218,6 +373,40 @@ with lib.maintainers; {
sumnerevans
];
scope = "Maintain the ecosystem around Matrix, a decentralized messenger.";
shortName = "Matrix";
};
mobile = {
members = [
samueldr
];
scope = "Maintain Mobile NixOS.";
shortName = "Mobile";
enableFeatureFreezePing = true;
};
nix = {
members = [
Profpatsch
eelco
grahamc
pierron
];
scope = "Maintain the Nix package manager.";
shortName = "Nix/nix-cli ecosystem";
enableFeatureFreezePing = true;
};
nixos-modules = {
members = [
ericson2314
infinisil
qyliss
roberth
];
scope = "Maintain nixpkgs module system internals.";
shortName = "NixOS Modules / internals";
enableFeatureFreezePing = true;
};
openstack = {
@ -226,6 +415,7 @@ with lib.maintainers; {
SuperSandro2000
];
scope = "Maintain the ecosystem around OpenStack";
shortName = "OpenStack";
};
pantheon = {
@ -233,7 +423,21 @@ with lib.maintainers; {
davidak
bobby285271
];
githubTeams = [
"pantheon"
];
scope = "Maintain Pantheon desktop environment and platform.";
shortName = "Pantheon";
enableFeatureFreezePing = true;
};
perl = {
members = [
sgo
];
scope = "Maintain the Perl interpreter and Perl packages.";
shortName = "Perl";
enableFeatureFreezePing = true;
};
php = {
@ -245,7 +449,12 @@ with lib.maintainers; {
ma27
talyz
];
githubTeams = [
"php"
];
scope = "Maintain PHP related packages and extensions.";
shortName = "PHP";
enableFeatureFreezePing = true;
};
podman = {
@ -255,7 +464,54 @@ with lib.maintainers; {
vdemeester
zowoq
];
githubTeams = [
"podman"
];
scope = "Maintain Podman and CRI-O related packages and modules.";
shortName = "Podman";
enableFeatureFreezePing = true;
};
postgres = {
members = [
thoughtpolice
];
scope = "Maintain the PostgreSQL package and plugins along with the NixOS module.";
shortName = "PostgreSQL";
enableFeatureFreezePing = true;
};
python = {
members = [
fridh
hexa
jonringer
];
scope = "Maintain the Python interpreter and related packages.";
shortName = "Python";
enableFeatureFreezePing = true;
};
qt-kde = {
members = [
ttuegel
];
githubTeams = [
"qt-kde"
];
scope = "Maintain the KDE desktop environment and Qt.";
shortName = "Qt / KDE";
enableFeatureFreezePing = true;
};
r = {
members = [
bcdarwin
jbedo
];
scope = "Maintain the R programming language and related packages.";
shortName = "R";
enableFeatureFreezePing = true;
};
redcodelabs = {
@ -265,6 +521,38 @@ with lib.maintainers; {
wintrmvte
];
scope = "Maintain Red Code Labs related packages and modules.";
shortName = "Red Code Labs";
};
release = {
members = [ ];
githubTeams = [
"nixos-release-managers"
];
scope = "Manage the current nixpkgs/NixOS release.";
shortName = "Release";
enableFeatureFreezePing = true;
};
ruby = {
members = [
marsam
];
scope = "Maintain the Ruby interpreter and related packages.";
shortName = "Ruby";
enableFeatureFreezePing = true;
};
rust = {
members = [
andir
lnl7
mic92
zowoq
];
scope = "Maintain the Rust compiler toolchain and nixpkgs integration.";
shortName = "Rust";
enableFeatureFreezePing = true;
};
sage = {
@ -275,6 +563,7 @@ with lib.maintainers; {
collares
];
scope = "Maintain SageMath and the dependencies that are likely to break it.";
shortName = "SageMath";
};
sphinx = {
@ -282,6 +571,7 @@ with lib.maintainers; {
SuperSandro2000
];
scope = "Maintain Sphinx related packages.";
shortName = "Sphinx";
};
serokell = {
@ -291,6 +581,26 @@ with lib.maintainers; {
mkaito
];
scope = "Group registration for Serokell employees who collectively maintain packages.";
shortName = "Serokell employees";
};
systemd = {
members = [ ];
githubTeams = [
"systemd"
];
scope = "Maintain systemd for NixOS.";
shortName = "systemd";
enableFeatureFreezePing = true;
};
tests = {
members = [
tfc
];
scope = "Maintain the NixOS VM test runner.";
shortName = "NixOS tests";
enableFeatureFreezePing = true;
};
tts = {
@ -299,6 +609,18 @@ with lib.maintainers; {
mic92
];
scope = "coqui-ai TTS (formerly Mozilla TTS) and leaf packages";
shortName = "coqui-ai TTS";
};
vim = {
members = [
jonringer
softinio
teto
];
scope = "Maintain the vim and neovim text editors and related packages.";
shortName = "Vim/Neovim";
enableFeatureFreezePing = true;
};
xfce = {
@ -306,5 +628,6 @@ with lib.maintainers; {
romildo
];
scope = "Maintain Xfce desktop environment and related packages.";
shortName = "Xfce";
};
}

@ -14,6 +14,10 @@ with pkgs;
let
lib = pkgs.lib;
docbook_xsl_ns = pkgs.docbook-xsl-ns.override {
withManOptDedupPatch = true;
};
# We need to strip references to /nix/store/* from options,
# including any `extraSources` if some modules came from elsewhere,
# or else the build will fail.

@ -14,7 +14,6 @@
<xi:include href="../from_md/development/building-parts.chapter.xml" />
<xi:include href="../from_md/development/what-happens-during-a-system-switch.chapter.xml" />
<xi:include href="../from_md/development/writing-documentation.chapter.xml" />
<xi:include href="../from_md/development/building-nixos.chapter.xml" />
<xi:include href="../from_md/development/nixos-tests.chapter.xml" />
<xi:include href="../from_md/development/testing-installer.chapter.xml" />
</part>

@ -120,14 +120,14 @@ lib.mkOption {
```nix
lib.mkPackageOption pkgs "GHC" {
default = [ "ghc" ];
example = "pkgs.haskell.package.ghc921.ghc.withPackages (hkgs: [ hkgs.primes ])";
example = "pkgs.haskell.package.ghc922.ghc.withPackages (hkgs: [ hkgs.primes ])";
}
# is like
lib.mkOption {
type = lib.types.package;
default = pkgs.ghc;
defaultText = lib.literalExpression "pkgs.ghc";
example = lib.literalExpression "pkgs.haskell.package.ghc921.ghc.withPackages (hkgs: [ hkgs.primes ])";
example = lib.literalExpression "pkgs.haskell.package.ghc922.ghc.withPackages (hkgs: [ hkgs.primes ])";
description = "The GHC package to use.";
}
```

@ -32,6 +32,20 @@ type of this option should represent the format. The most common formats
have a predefined type and string generator already declared under
`pkgs.formats`:
`pkgs.formats.javaProperties` { *`comment`* ? `"Generated with Nix"` }
: A function taking an attribute set with values
`comment`
: A string to put at the start of the
file in a comment. It can have multiple
lines.
It returns the `type`: `attrsOf str` and a function
`generate` to build a Java `.properties` file, taking
care of the correct escaping, etc.
`pkgs.formats.json` { }
: A function taking an empty attribute set (for future extensibility)

@ -5,15 +5,9 @@ A NixOS test is a Nix expression that has the following structure:
```nix
import ./make-test-python.nix {
# Either the configuration of a single machine:
machine =
{ config, pkgs, ... }:
{ configuration…
};
# Or a set of machines:
# One or more machines:
nodes =
{ machine1 =
{ machine =
{ config, pkgs, ... }: { … };
machine2 =
{ config, pkgs, ... }: { … };
@ -29,17 +23,16 @@ import ./make-test-python.nix {
The attribute `testScript` is a bit of Python code that executes the
test (described below). During the test, it will start one or more
virtual machines, the configuration of which is described by the
attribute `machine` (if you need only one machine in your test) or by
the attribute `nodes` (if you need multiple machines). For instance,
[`login.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix)
only needs a single machine to test whether users can log in
virtual machines, the configuration of which is described by
the attribute `nodes`.
An example of a single-node test is
[`login.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix).
It only needs a single machine to test whether users can log in
on the virtual console, whether device ownership is correctly maintained
when switching between consoles, and so on. On the other hand,
[`nfs/simple.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs/simple.nix),
which tests NFS client and server functionality in the
Linux kernel (including whether locks are maintained across server
crashes), requires three machines: a server and two clients.
when switching between consoles, and so on. An interesting multi-node test is
[`nfs/simple.nix`](https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs/simple.nix).
It uses two client nodes to test correct locking across server crashes.
There are a few special NixOS configuration options for test VMs:
@ -67,8 +60,7 @@ The test script is a sequence of Python statements that perform various
actions, such as starting VMs, executing commands in the VMs, and so on.
Each virtual machine is represented as an object stored in the variable
`name` if this is also the identifier of the machine in the declarative
config. If you didn\'t specify multiple machines using the `nodes`
attribute, it is just `machine`. The following example starts the
config. If you specified a node `nodes.machine`, the following example starts the
machine, waits until it has finished booting, then executes a command
and checks that the output is more-or-less correct:
@ -79,7 +71,7 @@ if not "Linux" in machine.succeed("uname"):
raise Exception("Wrong OS")
```
The first line is actually unnecessary; machines are implicitly started
The first line is technically unnecessary; machines are implicitly started
when you first execute an action on them (such as `wait_for_unit` or
`succeed`). If you have multiple machines, you can speed up the test by
starting them in parallel:
@ -158,37 +150,51 @@ The following methods are available on machine objects:
e.g., `send_chars("foobar\n")` will type the string `foobar`
followed by the Enter key.
`send_console`
: Send keys to the kernel console. This allows interaction with the systemd
emergency mode, for example. Takes a string that is sent, e.g.,
`send_console("\n\nsystemctl default\n")`.
`execute`
: Execute a shell command, returning a list `(status, stdout)`.
Commands are run with `set -euo pipefail` set:
- If several commands are separated by `;` and one fails, the
command as a whole will fail.
- For pipelines, the last non-zero exit status will be returned
(if there is one; otherwise zero will be returned).
- Dereferencing unset variables fails the command.
- It will wait for stdout to be closed.
If the command detaches, it must close stdout, as `execute` will wait
for this to consume all output reliably. This can be achieved by
redirecting stdout to stderr `>&2`, to `/dev/console`, `/dev/null` or
a file. Examples of detaching commands are `sleep 365d &`, where the
shell forks a new process that can write to stdout and `xclip -i`, where
the `xclip` command itself forks without closing stdout.
Takes an optional parameter `check_return` that defaults to `True`.
Setting this parameter to `False` will not check for the return code
and return -1 instead. This can be used for commands that shut down
the VM and would therefore break the pipe that would be used for
retrieving the return code.
A timeout for the command can be specified (in seconds) using the optional
`timeout` parameter, e.g., `execute(cmd, timeout=10)` or
`execute(cmd, timeout=None)`. The default is 900 seconds.
`succeed`
: Execute a shell command, raising an exception if the exit status is
not zero, otherwise returning the standard output. Commands are run
with `set -euo pipefail` set:
- If several commands are separated by `;` and one fails, the
command as a whole will fail.
- For pipelines, the last non-zero exit status will be returned
(if there is one, zero will be returned otherwise).
- Dereferencing unset variables fail the command.
- It will wait for stdout to be closed. See `execute` for the
implications.
not zero, otherwise returning the standard output. Similar to `execute`,
except that the timeout is `None` by default. See `execute` for details on
command execution.
`fail`
@ -198,10 +204,13 @@ The following methods are available on machine objects:
`wait_until_succeeds`
: Repeat a shell command with 1-second intervals until it succeeds.
Has a default timeout of 900 seconds which can be modified, e.g.
`wait_until_succeeds(cmd, timeout=10)`. See `execute` for details on
command execution.
`wait_until_fails`
: Repeat a shell command with 1-second intervals until it fails.
: Like `wait_until_succeeds`, but repeating the command until it fails.
`wait_for_unit`
@ -272,6 +281,13 @@ The following methods are available on machine objects:
Killing the interactive session with `Ctrl-d` or `Ctrl-c` also ends
the guest session.
`console_interact`
: Allows you to directly interact with QEMU's stdin. This should
only be used during test development, not in production tests.
Output from QEMU is only read line-wise. `Ctrl-c` kills QEMU and
`Ctrl-d` closes console and returns to the test runner.
To test user units declared by `systemd.user.services` the optional
`user` argument can be used:
@ -290,7 +306,7 @@ For faster dev cycles it\'s also possible to disable the code-linters
```nix
import ./make-test-python.nix {
skipLint = true;
machine =
nodes.machine =
{ config, pkgs, ... }:
{ configuration…
};

@ -183,14 +183,14 @@ lib.mkOption {
<programlisting language="bash">
lib.mkPackageOption pkgs &quot;GHC&quot; {
default = [ &quot;ghc&quot; ];
example = &quot;pkgs.haskell.package.ghc921.ghc.withPackages (hkgs: [ hkgs.primes ])&quot;;
example = &quot;pkgs.haskell.package.ghc922.ghc.withPackages (hkgs: [ hkgs.primes ])&quot;;
}
# is like
lib.mkOption {
type = lib.types.package;
default = pkgs.ghc;
defaultText = lib.literalExpression &quot;pkgs.ghc&quot;;
example = lib.literalExpression &quot;pkgs.haskell.package.ghc921.ghc.withPackages (hkgs: [ hkgs.primes ])&quot;;
example = lib.literalExpression &quot;pkgs.haskell.package.ghc922.ghc.withPackages (hkgs: [ hkgs.primes ])&quot;;
description = &quot;The GHC package to use.&quot;;
}
</programlisting>

@ -53,6 +53,38 @@
<literal>pkgs.formats</literal>:
</para>
<variablelist>
<varlistentry>
<term>
<literal>pkgs.formats.javaProperties</literal> {
<emphasis><literal>comment</literal></emphasis> ?
<literal>&quot;Generated with Nix&quot;</literal> }
</term>
<listitem>
<para>
A function taking an attribute set with values
</para>
<variablelist>
<varlistentry>
<term>
<literal>comment</literal>
</term>
<listitem>
<para>
A string to put at the start of the file in a comment.
It can have multiple lines.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
It returns the <literal>type</literal>:
<literal>attrsOf str</literal> and a function
<literal>generate</literal> to build a Java
<literal>.properties</literal> file, taking care of the
correct escaping, etc.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>pkgs.formats.json</literal> { }

@ -6,15 +6,9 @@
<programlisting language="bash">
import ./make-test-python.nix {
# Either the configuration of a single machine:
machine =
{ config, pkgs, ... }:
{ configuration…
};
# Or a set of machines:
# One or more machines:
nodes =
{ machine1 =
{ machine =
{ config, pkgs, ... }: { … };
machine2 =
{ config, pkgs, ... }: { … };
@ -31,18 +25,18 @@ import ./make-test-python.nix {
The attribute <literal>testScript</literal> is a bit of Python code
that executes the test (described below). During the test, it will
start one or more virtual machines, the configuration of which is
described by the attribute <literal>machine</literal> (if you need
only one machine in your test) or by the attribute
<literal>nodes</literal> (if you need multiple machines). For
instance,
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix"><literal>login.nix</literal></link>
only needs a single machine to test whether users can log in on the
virtual console, whether device ownership is correctly maintained
when switching between consoles, and so on. On the other hand,
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs/simple.nix"><literal>nfs/simple.nix</literal></link>,
which tests NFS client and server functionality in the Linux kernel
(including whether locks are maintained across server crashes),
requires three machines: a server and two clients.
described by the attribute <literal>nodes</literal>.
</para>
<para>
An example of a single-node test is
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/login.nix"><literal>login.nix</literal></link>.
It only needs a single machine to test whether users can log in on
the virtual console, whether device ownership is correctly
maintained when switching between consoles, and so on. An
interesting multi-node test is
<link xlink:href="https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/nfs/simple.nix"><literal>nfs/simple.nix</literal></link>.
It uses two client nodes to test correct locking across server
crashes.
</para>
<para>
There are a few special NixOS configuration options for test VMs:
@ -94,9 +88,8 @@ import ./make-test-python.nix {
various actions, such as starting VMs, executing commands in the
VMs, and so on. Each virtual machine is represented as an object
stored in the variable <literal>name</literal> if this is also the
identifier of the machine in the declarative config. If you didn't
specify multiple machines using the <literal>nodes</literal>
attribute, it is just <literal>machine</literal>. The following
identifier of the machine in the declarative config. If you
specified a node <literal>nodes.machine</literal>, the following
example starts the machine, waits until it has finished booting,
then executes a command and checks that the output is more-or-less
correct:
@ -108,7 +101,7 @@ if not &quot;Linux&quot; in machine.succeed(&quot;uname&quot;):
raise Exception(&quot;Wrong OS&quot;)
</programlisting>
<para>
The first line is actually unnecessary; machines are implicitly
The first line is technically unnecessary; machines are implicitly
started when you first execute an action on them (such as
<literal>wait_for_unit</literal> or <literal>succeed</literal>). If
you have multiple machines, you can speed up the test by starting
@ -263,40 +256,27 @@ start_all()
</varlistentry>
<varlistentry>
<term>
<literal>execute</literal>
<literal>send_console</literal>
</term>
<listitem>
<para>
Execute a shell command, returning a list
<literal>(status, stdout)</literal>. If the command
detaches, it must close stdout, as
<literal>execute</literal> will wait for this to consume all
output reliably. This can be achieved by redirecting stdout
to stderr <literal>&gt;&amp;2</literal>, to
<literal>/dev/console</literal>,
<literal>/dev/null</literal> or a file. Examples of
detaching commands are <literal>sleep 365d &amp;</literal>,
where the shell forks a new process that can write to stdout
and <literal>xclip -i</literal>, where the
<literal>xclip</literal> command itself forks without
closing stdout. Takes an optional parameter
<literal>check_return</literal> that defaults to
<literal>True</literal>. Setting this parameter to
<literal>False</literal> will not check for the return code
and return -1 instead. This can be used for commands that
shut down the VM and would therefore break the pipe that
would be used for retrieving the return code.
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>
<term>
<literal>succeed</literal>
<literal>execute</literal>
</term>
<listitem>
<para>
Execute a shell command, raising an exception if the exit
status is not zero, otherwise returning the standard output.
Execute a shell command, returning a list
<literal>(status, stdout)</literal>.
</para>
<para>
Commands are run with <literal>set -euo pipefail</literal>
set:
</para>
@ -311,22 +291,63 @@ start_all()
<listitem>
<para>
For pipelines, the last non-zero exit status will be
returned (if there is one, zero will be returned
otherwise).
returned (if there is one; otherwise zero will be
returned).
</para>
</listitem>
<listitem>
<para>
Dereferencing unset variables fail the command.
Dereferencing unset variables fails the command.
</para>
</listitem>
<listitem>
<para>
It will wait for stdout to be closed. See
<literal>execute</literal> for the implications.
It will wait for stdout to be closed.
</para>
</listitem>
</itemizedlist>
<para>
If the command detaches, it must close stdout, as
<literal>execute</literal> will wait for this to consume all
output reliably. This can be achieved by redirecting stdout
to stderr <literal>&gt;&amp;2</literal>, to
<literal>/dev/console</literal>,
<literal>/dev/null</literal> or a file. Examples of
detaching commands are <literal>sleep 365d &amp;</literal>,
where the shell forks a new process that can write to stdout
and <literal>xclip -i</literal>, where the
<literal>xclip</literal> command itself forks without
closing stdout.
</para>
<para>
Takes an optional parameter <literal>check_return</literal>
that defaults to <literal>True</literal>. Setting this
parameter to <literal>False</literal> will not check for the
return code and return -1 instead. This can be used for
commands that shut down the VM and would therefore break the
pipe that would be used for retrieving the return code.
</para>
<para>
A timeout for the command can be specified (in seconds)
using the optional <literal>timeout</literal> parameter,
e.g., <literal>execute(cmd, timeout=10)</literal> or
<literal>execute(cmd, timeout=None)</literal>. The default
is 900 seconds.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>succeed</literal>
</term>
<listitem>
<para>
Execute a shell command, raising an exception if the exit
status is not zero, otherwise returning the standard output.
Similar to <literal>execute</literal>, except that the
timeout is <literal>None</literal> by default. See
<literal>execute</literal> for details on command execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
@ -347,7 +368,10 @@ start_all()
<listitem>
<para>
Repeat a shell command with 1-second intervals until it
succeeds.
succeeds. Has a default timeout of 900 seconds which can be
modified, e.g.
<literal>wait_until_succeeds(cmd, timeout=10)</literal>. See
<literal>execute</literal> for details on command execution.
</para>
</listitem>
</varlistentry>
@ -357,8 +381,8 @@ start_all()
</term>
<listitem>
<para>
Repeat a shell command with 1-second intervals until it
fails.
Like <literal>wait_until_succeeds</literal>, but repeating
the command until it fails.
</para>
</listitem>
</varlistentry>
@ -502,6 +526,21 @@ machine.systemctl(&quot;list-jobs --no-pager&quot;, &quot;any-user&quot;) # spaw
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>console_interact</literal>
</term>
<listitem>
<para>
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.
<literal>Ctrl-c</literal> kills QEMU and
<literal>Ctrl-d</literal> closes console and returns to the
test runner.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
To test user units declared by
@ -526,7 +565,7 @@ machine.wait_for_unit(&quot;xautolock.service&quot;, &quot;x-session-user&quot;)
<programlisting language="bash">
import ./make-test-python.nix {
skipLint = true;
machine =
nodes.machine =
{ config, pkgs, ... }:
{ configuration…
};

@ -43,6 +43,40 @@ $ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd
</para>
<programlisting>
# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso
</programlisting>
</section>
<section xml:id="sec-building-image-drivers">
<title>Additional drivers or firmware</title>
<para>
If you need additional (non-distributable) drivers or firmware in
the installer, you might want to extend these configurations.
</para>
<para>
For example, to build the GNOME graphical installer ISO, but with
support for certain WiFi adapters present in some MacBooks, you
can create the following file at
<literal>modules/installer/cd-dvd/installation-cd-graphical-gnome-macbook.nix</literal>:
</para>
<programlisting language="bash">
{ config, ... }:
{
imports = [ ./installation-cd-graphical-gnome.nix ];
boot.initrd.kernelModules = [ &quot;wl&quot; ];
boot.kernelModules = [ &quot;kvm-intel&quot; &quot;wl&quot; ];
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
}
</programlisting>
<para>
Then build it like in the example above:
</para>
<programlisting>
$ git clone https://github.com/NixOS/nixpkgs.git
$ cd nixpkgs/nixos
$ export NIXPKGS_ALLOW_UNFREE=1
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-graphical-gnome-macbook.nix default.nix
</programlisting>
</section>
<section xml:id="sec-building-image-tech-notes">

@ -17,7 +17,7 @@ $ diskutil list
[..]
$ diskutil unmountDisk diskN
Unmount of all volumes on diskN was successful
$ sudo dd if=nix.iso of=/dev/rdiskN
$ sudo dd if=nix.iso of=/dev/rdiskN bs=1M
</programlisting>
<para>
Using the 'raw' <literal>rdiskN</literal> device instead of

@ -411,6 +411,13 @@ OK
specify on which disk the GRUB boot loader is to be
installed. Without it, NixOS cannot boot.
</para>
<para>
If there are other operating systems running on the
machine before installing NixOS, the
<xref linkend="opt-boot.loader.grub.useOSProber" />
option can be set to <literal>true</literal> to
automatically add them to the grub menu.
</para>
</listitem>
</varlistentry>
<varlistentry>
@ -436,13 +443,6 @@ OK
</listitem>
</varlistentry>
</variablelist>
<para>
If there are other operating systems running on the machine
before installing NixOS, the
<xref linkend="opt-boot.loader.grub.useOSProber" /> option can
be set to <literal>true</literal> to automatically add them to
the grub menu.
</para>
<para>
If you need to configure networking for your machine the
configuration options are described in

@ -866,6 +866,14 @@
package.
</para>
</listitem>
<listitem>
<para>
The vim/kakoune plugin updater now reads from a CSV file:
check
<literal>pkgs/applications/editors/vim/plugins/vim-plugin-names</literal>
out to see the new format
</para>
</listitem>
</itemizedlist>
</section>
</section>

@ -30,6 +30,37 @@ To check the content of an ISO image, mount it like so:
# mount -o loop -t iso9660 ./result/iso/cd.iso /mnt/iso
```
## Additional drivers or firmware {#sec-building-image-drivers}
If you need additional (non-distributable) drivers or firmware in the
installer, you might want to extend these configurations.
For example, to build the GNOME graphical installer ISO, but with support for
certain WiFi adapters present in some MacBooks, you can create the following
file at `modules/installer/cd-dvd/installation-cd-graphical-gnome-macbook.nix`:
```nix
{ config, ... }:
{
imports = [ ./installation-cd-graphical-gnome.nix ];
boot.initrd.kernelModules = [ "wl" ];
boot.kernelModules = [ "kvm-intel" "wl" ];
boot.extraModulePackages = [ config.boot.kernelPackages.broadcom_sta ];
}
```
Then build it like in the example above:
```ShellSession
$ git clone https://github.com/NixOS/nixpkgs.git
$ cd nixpkgs/nixos
$ export NIXPKGS_ALLOW_UNFREE=1
$ nix-build -A config.system.build.isoImage -I nixos-config=modules/installer/cd-dvd/installation-cd-graphical-gnome-macbook.nix default.nix
```
## Technical Notes {#sec-building-image-tech-notes}
The config value enforcement is implemented via `mkImageMediaOverride = mkOverride 60;`

@ -14,4 +14,5 @@
<xi:include href="../from_md/installation/installing.chapter.xml" />
<xi:include href="../from_md/installation/changing-config.chapter.xml" />
<xi:include href="../from_md/installation/upgrading.chapter.xml" />
<xi:include href="../from_md/installation/building-nixos.chapter.xml" />
</part>

@ -18,7 +18,7 @@ $ diskutil list
[..]
$ diskutil unmountDisk diskN
Unmount of all volumes on diskN was successful
$ sudo dd if=nix.iso of=/dev/rdiskN
$ sudo dd if=nix.iso of=/dev/rdiskN bs=1M
```
Using the \'raw\' `rdiskN` device instead of `diskN` completes in

@ -296,6 +296,11 @@ Use the following commands:
specify on which disk the GRUB boot loader is to be installed.
Without it, NixOS cannot boot.
: If there are other operating systems running on the machine before
installing NixOS, the [](#opt-boot.loader.grub.useOSProber)
option can be set to `true` to automatically add them to the grub
menu.
UEFI systems
: You *must* set the option [](#opt-boot.loader.systemd-boot.enable)
@ -307,11 +312,6 @@ Use the following commands:
[`boot.loader.systemd-boot`](#opt-boot.loader.systemd-boot.enable)
as well.
If there are other operating systems running on the machine before
installing NixOS, the [](#opt-boot.loader.grub.useOSProber)
option can be set to `true` to automatically add them to the grub
menu.
If you need to configure networking for your machine the
configuration options are described in [](#sec-networking). In
particular, while wifi is supported on the installation image, it is

@ -91,6 +91,10 @@
<option>--flake</option> <replaceable>flake-uri</replaceable>
</arg>
<arg>
<option>--no-flake</option>
</arg>
<arg>
<option>--override-input</option> <replaceable>input-name</replaceable> <replaceable>flake-uri</replaceable>
</arg>
@ -544,6 +548,14 @@
(<replaceable>user@host</replaceable>). You can also set ssh options by
defining the <envar>NIX_SSHOPTS</envar> environment variable.
</para>
<para>
Note that <command>nixos-rebuild</command> honors the
<literal>nixpkgs.crossSystem</literal> setting of the given configuration
but disregards the true architecture of the target host. Hence the
<literal>nixpkgs.crossSystem</literal> setting has to match the target
platform or else activation will fail.
</para>
</listitem>
</varlistentry>
@ -594,6 +606,20 @@
</listitem>
</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>
<para>

@ -3,10 +3,15 @@
xmlns:xi="http://www.w3.org/2001/XInclude">
<title>NixOS Reference Pages</title>
<info>
<author><personname><firstname>Eelco</firstname><surname>Dolstra</surname></personname>
<author>
<personname><firstname>Eelco</firstname><surname>Dolstra</surname></personname>
<contrib>Author</contrib>
</author>
<copyright><year>2007-2020</year><holder>Eelco Dolstra</holder>
<author>
<personname><othername>The Nixpkgs/NixOS contributors</othername></personname>
<contrib>Author</contrib>
</author>
<copyright><year>2007-2022</year><holder>Eelco Dolstra and the Nixpkgs/NixOS contributors</holder>
</copyright>
</info>
<xi:include href="man-configuration.xml" />

@ -1,5 +1,5 @@
#! /usr/bin/env nix-shell
#! nix-shell -I nixpkgs=channel:nixpkgs-unstable -i bash -p pandoc
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/tarball/21.11 -i bash -p pandoc
# This script is temporarily needed while we transition the manual to
# CommonMark. It converts the .md files in the regular manual folder

@ -282,3 +282,5 @@ When upgrading from a previous release, please be aware of the following incompa
- The NixOS test driver supports user services declared by `systemd.user.services`. The methods `waitForUnit`, `getUnitInfo`, `startJob` and `stopJob` provide an optional `$user` argument for that purpose.
- Enabling bash completion on NixOS, `programs.bash.enableCompletion`, will now also enable completion for the Nix command line tools by installing the [nix-bash-completions](https://github.com/hedning/nix-bash-completions) package.
- The vim/kakoune plugin updater now reads from a CSV file: check `pkgs/applications/editors/vim/plugins/vim-plugin-names` out to see the new format

@ -6,11 +6,17 @@ In addition to numerous new and upgraded packages, this release has the followin
## Highlights {#sec-release-22.05-highlights}
- The `firefox` browser on `x86_64-linux` is now making use of
profile-guided optimization resulting in a much more responsive
browsing experience.
- `security.acme.defaults` has been added to simplify configuring
settings for many certificates at once. This also opens up the
the option to use DNS-01 validation when using `enableACME` on
web server virtual hosts (e.g. `services.nginx.virtualHosts.*.enableACME`).
- GNOME has been upgraded to 42. Please take a look at their [Release Notes](https://release.gnome.org/42/) for details. Notably, it replaces gedit with GNOME Text Editor, GNOME Terminal with GNOME Console (formerly King’s Cross), and GNOME Screenshot with a tool built into the Shell.
- PHP 8.1 is now available
- Mattermost has been updated to extended support release 6.3, as the previously packaged extended support release 5.37 is [reaching its end of life](https://docs.mattermost.com/upgrade/extended-support-release.html).
@ -19,8 +25,16 @@ In addition to numerous new and upgraded packages, this release has the followin
- systemd services can now set [systemd.services.\<name\>.reloadTriggers](#opt-systemd.services) instead of `reloadIfChanged` for a more granular distinction between reloads and restarts.
- Systemd has been upgraded to the version 250.
- The new [`postgresqlTestHook`](https://nixos.org/manual/nixpkgs/stable/#sec-postgresqlTestHook) runs a PostgreSQL server for the duration of package checks.
- [`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.
- The default GHC version has been updated from 8.10.7 to 9.0.2. `pkgs.haskellPackages` and `pkgs.ghc` will now use this version by default.
## 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).
@ -29,11 +43,13 @@ In addition to numerous new and upgraded packages, this release has the followin
- [matrix-conduit](https://conduit.rs/), a simple, fast and reliable chat server powered by matrix. Available as [services.matrix-conduit](option.html#opt-services.matrix-conduit.enable).
- [nethoscope](https://github.com/vvilhonen/nethoscope), listen to your network traffic. Available as [programs.nethoscope](#opt-programs.nethoscope.enable).
- [filebeat](https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-overview.html), a lightweight shipper for forwarding and centralizing log data. Available as [services.filebeat](#opt-services.filebeat.enable).
- [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).
@ -53,10 +69,14 @@ In addition to numerous new and upgraded packages, this release has the followin
- [K40-Whisperer](https://www.scorchworks.com/K40whisperer/k40whisperer.html), a program to control cheap Chinese laser cutters. Available as [programs.k40-whisperer.enable](options.html#opt-programs.k4-whisperer.enable). Users must add themselves to the `k40` group to be able to access the device.
- [mozillavpn](https://github.com/mozilla-mobile/mozilla-vpn-client), the client for the [Mozilla VPN](https://vpn.mozilla.org/) service. Available as [services.mozillavpn](options.html#opt-services.mozillavpn).
- [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).
- [netbox](https://github.com/netbox-community/netbox), infrastructure resource modeling (IRM) tool. Available as [services.netbox](options.html#opt-services.netbox.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).
@ -79,16 +99,22 @@ In addition to numerous new and upgraded packages, this release has the followin
- [nbd](https://nbd.sourceforge.io/), a Network Block Device server. Available as [services.nbd](options.html#opt-services.nbd.server.enable).
- [nix-ld](https://github.com/Mic92/nix-ld), Run unpatched dynamic binaries on NixOS. Available as [programs.nix-ld](options.html#opt-programs.nix-ld.enable).
- [timetagger](https://timetagger.app), an open source time-tracker with an intuitive user experience and powerful reporting. [services.timetagger](options.html#opt-services.timetagger.enable).
- [rstudio-server](https://www.rstudio.com/products/rstudio/#rstudio-server), a browser-based version of the RStudio IDE for the R programming language. Available as [services.rstudio-server](options.html#opt-services.rstudio-server.enable).
- [headscale](https://github.com/juanfont/headscale), an Open Source implementation of the [Tailscale](https://tailscale.io) Control Server. Available as [services.headscale](options.html#opt-services.headscale.enable)
- [create_ap](https://github.com/lakinduakash/linux-wifi-hotspot), a module for creating wifi hotspots using the program linux-wifi-hotspot. Available as [services.create_ap](options.html#opt-services.create_ap.enable).
- [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
- [nifi](https://nifi.apache.org), an easy to use, powerful, and reliable system to process and distribute data. Available as [services.nifi](options.html#opt-services.nifi.enable).
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
## Backward Incompatibilities {#sec-release-22.05-incompatibilities}
@ -125,10 +151,58 @@ In addition to numerous new and upgraded packages, this release has the followin
org-contrib, refer to the ones in `pkgs.emacsPackages.elpaPackages` and
`pkgs.emacsPackages.nongnuPackages` where the new versions will release.
- `security.klogd` was removed. Logging of kernel messages is handled
by systemd since Linux 3.5.
- `pkgs.ssmtp` has been dropped due to the program being unmaintained.
`pkgs.msmtp` can be used instead as a substitute `sendmail` implementation.
The corresponding options `services.ssmtp.*` have been removed as well.
`programs.msmtp.*` can be used instead for an equivalent setup. For example:
```nix
{
# Original ssmtp configuration:
services.ssmtp = {
enable = true;
useTLS = true;
useSTARTTLS = true;
hostName = "smtp.example:587";
authUser = "someone";
authPassFile = "/secrets/password.txt";
};
# Equivalent msmtp configuration:
programs.msmtp = {
enable = true;
accounts.default = {
tls = true;
tls_starttls = true;
auth = true;
host = "smtp.example";
port = 587;
user = "someone";
passwordeval = "cat /secrets/password.txt";
};
};
}
```
- `services.kubernetes.addons.dashboard` was removed due to it being an outdated version.
- `services.kubernetes.scheduler.{port,address}` now set `--secure-port` and `--bind-address` instead of `--port` and `--address`, since the former have been deprecated and are no longer functional in kubernetes>=1.23. Ensure that you are not relying on the insecure behaviour before upgrading.
- In the PowerDNS Recursor module (`services.pdns-recursor`), default values of several IP address-related NixOS options have been updated to match the default upstream behavior.
In particular, Recursor by default will:
- listen on (and allows connections from) both IPv4 and IPv6 addresses
(`services.pdns-recursor.dns.address`, `services.pdns-recursor.dns.allowFrom`);
- allow only local connections to the REST API server (`services.pdns-recursor.api.allowFrom`).
- In the ncdns module, the default value of `services.ncdns.address` has been changed to the IPv6 loopback address (`::1`).
- `openssh` has been update to 8.9p1, changing the FIDO security key middleware interface.
- `git` no longer hardcodes the path to openssh' ssh binary to reduce the amount of rebuilds. If you are using git with ssh remotes and do not have a ssh binary in your enviroment consider adding `openssh` to it or switching to `gitFull`.
- `services.k3s.enable` no longer implies `systemd.enableUnifiedCgroupHierarchy = false`, and will default to the 'systemd' cgroup driver when using `services.k3s.docker = true`.
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.
@ -146,6 +220,8 @@ In addition to numerous new and upgraded packages, this release has the followin
}
```
- `services.prometheus.alertManagerTimeout` has been removed as it has been deprecated upstream and has no effect.
- The DHCP server (`services.dhcpd4`, `services.dhcpd6`) has been hardened.
The service is now using the systemd's `DynamicUser` mechanism to run as an unprivileged dynamically-allocated user with limited capabilities.
The dhcpd state files are now always stored in `/var/lib/dhcpd{4,6}` and the `services.dhcpd4.stateDir` and `service.dhcpd6.stateDir` options have been removed.
@ -153,6 +229,12 @@ In addition to numerous new and upgraded packages, this release has the followin
- The `mailpile` email webclient (`services.mailpile`) has been removed due to its reliance on python2.
- `services.ipfs.extraFlags` is now escaped with `utils.escapeSystemdExecArgs`. If you rely on systemd interpolating `extraFlags` in the service `ExecStart`, this will no longer work.
- `hbase` version 0.98.24 has been removed. The package now defaults to version 2.4.11. Versions 1.7.1 and 3.0.0-alpha-2 are also available.
- `services.paperless-ng` was renamed to `services.paperless`. Accordingly, the `paperless-ng-manage` script (located in `dataDir`) was renamed to `paperless-manage`. `services.paperless` now uses `paperless-ngx`.
- The `matrix-synapse` service (`services.matrix-synapse`) has been converted to use the `settings` option defined in RFC42.
This means that options that are part of your `homeserver.yaml` configuration, and that were specified at the top-level of the
module (`services.matrix-synapse`) now need to be moved into `services.matrix-synapse.settings`. And while not all options you
@ -247,6 +329,81 @@ In addition to numerous new and upgraded packages, this release has the followin
`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 Keycloak package (`pkgs.keycloak`) has been switched from the
Wildfly version, which will soon be deprecated, to the Quarkus based
version. The Keycloak service (`services.keycloak`) has been updated
to accommodate the change and now differs from the previous version
in a few ways:
- `services.keycloak.extraConfig` has been removed in favor of the
new [settings-style](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md)
[`services.keycloak.settings`](#opt-services.keycloak.settings)
option. The available options correspond directly to parameters in
`conf/keycloak.conf`. Some of the most important parameters are
documented as suboptions, the rest can be found in the [All
configuration section of the Keycloak Server Installation and
Configuration
Guide](https://www.keycloak.org/server/all-config). While the new
configuration is much simpler and cleaner than the old JBoss CLI
one, this unfortunately mean that there's no straightforward way
to convert an old configuration to the new format and some
settings may not even be available anymore.
- `services.keycloak.frontendUrl` was removed and the frontend URL
is now configured through the `hostname` family of settings in
[`services.keycloak.settings`](#opt-services.keycloak.settings)
instead. See the [Hostname section of the Keycloak Server
Installation and Configuration
Guide](https://www.keycloak.org/server/hostname) for more
details. Additionally, `/auth` was removed from the default
context path and needs to be added back in
[`services.keycloak.settings.http-relative-path`](#opt-services.keycloak.settings.http-relative-path)
if you want to keep compatibility with your current clients.
- `services.keycloak.bindAddress`,
`services.keycloak.forceBackendUrlToFrontendUrl`,
`services.keycloak.httpPort` and `services.keycloak.httpsPort`
have been removed in favor of their equivalent options in
[`services.keycloak.settings`](#opt-services.keycloak.settings). `httpPort`
and `httpsPort` have additionally had their types changed from
`str` to `port`.
The new names are as follows:
- `bindAddress`: [`services.keycloak.settings.http-host`](#opt-services.keycloak.settings.http-host)
- `forceBackendUrlToFrontendUrl`: [`services.keycloak.settings.hostname-strict-backchannel`](#opt-services.keycloak.settings.hostname-strict-backchannel)
- `httpPort`: [`services.keycloak.settings.http-port`](#opt-services.keycloak.settings.http-port)
- `httpsPort`: [`services.keycloak.settings.https-port`](#opt-services.keycloak.settings.https-port)
For example, when using a reverse proxy the migration could look
like this:
Before:
```nix
services.keycloak = {
enable = true;
httpPort = "8080";
frontendUrl = "https://keycloak.example.com/auth";
database.passwordFile = "/run/keys/db_password";
extraConfig = {
"subsystem=undertow"."server=default-server"."http-listener=default".proxy-address-forwarding = true;
};
};
```
After:
```nix
services.keycloak = {
enable = true;
settings = {
http-port = 8080;
hostname = "keycloak.example.com";
http-relative-path = "/auth";
proxy = "edge";
};
database.passwordFile = "/run/keys/db_password";
};
```
- 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.
@ -269,6 +426,10 @@ In addition to numerous new and upgraded packages, this release has the followin
- The `gnome-passwordsafe` package updated to [version 6.x](https://gitlab.gnome.org/World/secrets/-/tags/6.0) and renamed to `gnome-secrets`.
- `services.gnome.experimental-features.realtime-scheduling` option has been removed, as GNOME Shell now [uses rtkit](https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2060). Use `security.rtkit.enable = true;` instead. As before, you will need to have it enabled using GSettings.
- `services.telepathy` will no longer be enabled by default for GNOME desktops, one should enable it in their configs if using Empathy or Polari.
- If you previously used `/etc/docker/daemon.json`, you need to incorporate the changes into the new option `virtualisation.docker.daemon.settings`.
- Ntopng (`services.ntopng`) is updated to 5.2.1 and uses a separate Redis instance if `system.stateVersion` is at least `22.05`. Existing setups shouldn't be affected.
@ -284,6 +445,10 @@ In addition to numerous new and upgraded packages, this release has the followin
- `services.miniflux.adminCredentialFiles` is now required, instead of defaulting to `admin` and `password`.
- The `taskserver` module no longer implicitly opens ports in the firewall
configuration. This is now controlled through the option
`services.taskserver.openFirewall`.
- The `autorestic` package has been upgraded from 1.3.0 to 1.5.0 which introduces breaking changes in config file, check [their migration guide](https://autorestic.vercel.app/migration/1.4_1.5) for more details.
- For `pkgs.python3.pkgs.ipython`, its direct dependency `pkgs.python3.pkgs.matplotlib-inline`
@ -311,6 +476,15 @@ In addition to numerous new and upgraded packages, this release has the followin
- `pkgs._7zz` is now correctly licensed as LGPL3+ and BSD3 with optional unfree unRAR licensed code
- The `vim.customize` function produced by `vimUtils.makeCustomizable` now has a slightly different interface:
* The wrapper now includes everything in the given Vim derivation if `name` is `"vim"` (the default). This makes the `wrapManual` argument obsolete, but this behavior can be overriden by setting the `standalone` argument.
* All the executables present in the given derivation (or, in `standalone` mode, only the `*vim` ones) are wrapped. This makes the `wrapGui` argument obsolete.
* The `vimExecutableName` and `gvimExecutableName` arguments were replaced by a single `executableName` argument in which the shell variable `$exe` can be used to refer to the wrapped executable's name.
See the comments in `pkgs/applications/editors/vim/plugins/vim-utils.nix` for more details.
`vimUtils.vimWithRC` was removed. You should instead use `customize` on a Vim derivation, which now accepts `vimrcFile` and `gvimrcFile` arguments.
- `tilp2` was removed together with its module
- The F-PROT antivirus (`fprot` package) and its service module were removed because it
@ -320,10 +494,20 @@ 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 `miller` package has been upgraded from 5.10.3 to [6.2.0](https://github.com/johnkerl/miller/releases/tag/v6.2.0). See [What's new in Miller 6](https://miller.readthedocs.io/en/latest/new-in-miller-6).
- MultiMC has been replaced with the fork PolyMC due to upstream developers being hostile to 3rd party package maintainers. PolyMC removes all MultiMC branding and is aimed at providing proper 3rd party packages like the one contained in Nixpkgs. This change affects the data folder where game instances and other save and configuration files are stored. Users with existing installations should rename `~/.local/share/multimc` to `~/.local/share/polymc`. The main config file's path has also moved from `~/.local/share/multimc/multimc.cfg` to `~/.local/share/polymc/polymc.cfg`.
- `systemd-nspawn@.service` settings have been reverted to the default systemd behaviour. User namespaces are now activated by default. If you want to keep running nspawn containers without user namespaces you need to set `systemd.nspawn.<name>.execConfig.PrivateUsers = false`
- `systemd-shutdown` is now properly linked on shutdown to unmount all filesystems and device mapper devices cleanly. This can be disabled using `boot.systemd.shutdown.enable`.
- 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`.
- `services.github-runner` has been hardened. Notably address families and
system calls have been restricted, which may adversely affect some kinds of
testing, e.g. using `AF_BLUETOOTH` to test bluetooth devices.
- 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).
@ -344,8 +528,7 @@ In addition to numerous new and upgraded packages, this release has the followin
you should change the package you refer to. If you don't need them update your
commands from `otelcontribcol` to `otelcorecol` and enjoy a 7x smaller binary.
- `pkgs.pgadmin` now refers to `pkgs.pgadmin4`.
If you still need pgadmin3, use `pkgs.pgadmin3`.
- `pkgs.pgadmin` now refers to `pkgs.pgadmin4`. `pgadmin3` has been removed.
- `pkgs.noto-fonts-cjk` is now deprecated in favor of `pkgs.noto-fonts-cjk-sans`
and `pkgs.noto-fonts-cjk-serif` because they each have different release
@ -415,6 +598,15 @@ In addition to numerous new and upgraded packages, this release has the followin
See the `vscode` package for a more detailed example.
- Existing `resholve*` functions have been renamed and nested under `pkgs.resholve`. Update uses to:
- `resholvePackage` -> `resholve.mkDerivation`
- `resholveScript` -> `resholve.writeScript`
- `resholveScriptBin` -> `resholve.writeScriptBin`
- `pkgs.cosmopolitan` no longer provides the `cosmoc` command. It has been moved to `pkgs.cosmoc`.
- `pkgs.graalvmXX-ce` packages no longer provide support for Python/Ruby/WASM, instead focusing only in Java and Native Image Support. If you need to add support back, please see the `pkgs.graalvmCEPackages.mkGraal` function to create your own customized version of GraalVM with support for what you need.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
## Other Notable Changes {#sec-release-22.05-notable-changes}
@ -446,7 +638,7 @@ In addition to numerous new and upgraded packages, this release has the followin
Similarly [virtualisation.vmVariantWithBootloader](#opt-virtualisation.vmVariantWithBootLoader) was added.
- The configuration portion of the `nix-daemon` module has been reworked and exposed as [nix.settings](options.html#opt-nix-settings):
* Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) but may be deprecated in the future.
* Legacy options have been mapped to the corresponding options under under [nix.settings](options.html#opt-nix.settings) and will be deprecated when NixOS 21.11 reaches end of life.
* [nix.buildMachines.publicHostKey](options.html#opt-nix.buildMachines.publicHostKey) has been added.
- The `writers.writePyPy2`/`writers.writePyPy3` and corresponding `writers.writePyPy2Bin`/`writers.writePyPy3Bin` convenience functions to create executable Python 2/3 scripts using the PyPy interpreter were added.
@ -456,6 +648,10 @@ In addition to numerous new and upgraded packages, this release has the followin
- Support for older versions of hadoop have been added to the module
- Overriding and extending site XML files has been made easier
- The auto-upgrade service now accepts persistent (default: true) parameter.
By default auto-upgrade will now run immediately if it would have been triggered at least
once during the time when the timer was inactive.
- If you are using Wayland you can choose to use the Ozone Wayland support
in Chrome and several Electron apps by setting the environment variable
`NIXOS_OZONE_WL=1` (for example via
@ -464,6 +660,11 @@ In addition to numerous new and upgraded packages, this release has the followin
still under heavy development and behavior is not always flawless.
Furthermore, not all Electron apps use the latest Electron versions.
- A new option group `systemd.network.wait-online` was added, with options to configure `systemd-networkd-wait-online.service`:
- `anyInterface` allows specifying that the network should be considered online when *at least one* interface is online (useful on laptops)
- `timeout` defines how long to wait for the network to come online
- `extraArgs` for everything else
- The `influxdb2` package was split into `influxdb2-server` and
`influxdb2-cli`, matching the split that took place upstream. A
combined `influxdb2` package is still provided in this release for
@ -474,9 +675,14 @@ In addition to numerous new and upgraded packages, this release has the followin
- `programs.zsh.autosuggestions.strategy` now takes a list of strings instead of a string.
- The `asterisk` and `asterisk-stable` packages were switched from `asterisk_18` to the newly-packaged `asterisk_19`. Asterisk 13 and 17 have been removed as they have reached their end of life.
- The `services.unifi.openPorts` option default value of `true` is now deprecated and will be changed to `false` in 22.11.
Configurations using this default will print a warning when rebuilt.
- The `services.unifi-video.openPorts` option default value of `true` is now deprecated and will be changed to `false` in 22.11.
Configurations using this default will print a warning when rebuilt.
- `security.acme` certificates will now correctly check for CA
revokation before reaching their minimum age.
@ -495,28 +701,53 @@ In addition to numerous new and upgraded packages, this release has the followin
e.g. Wayland.
- [programs.ssh.knownHosts](#opt-programs.ssh.knownHosts) has gained an `extraHostNames`
option to replace `hostNames`. `hostNames` is deprecated, but still available for now.
option to augment `hostNames`. It is now possible to use the attribute name of a `knownHosts`
entry as the primary host name and specify secondary host names using `extraHostNames` without
having to duplicate the primary host name.
- The `services.stubby` module was converted to a [settings-style](https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md) configuration.
- The option
[services.xserver.desktopManager.runXdgAutostartIfNone](#opt-services.xserver.desktopManager.runXdgAutostartIfNone)
was added in order to automatically run XDG autostart files for sessions without a desktop manager.
This replaces helpers like the `dex` package.
- When setting [i18n.inputMethod.enabled](#opt-i18n.inputMethod.enabled) to `fcitx5`,
it no longer creates corresponding systemd user services.
It now relies on XDG autostart files to start and work properly in your desktop sessions.
If you are using only a window manager without a desktop manager, you need to enable
`services.xserver.desktopManager.runXdgAutostartIfNone` or using the `dex` package to make `fcitx5` work.
- A new module was added for the Envoy reverse proxy, providing the options `services.envoy.enable` and `services.envoy.settings`.
- The option `services.duplicati.dataDir` has been added to allow changing the location of duplicati's files.
- The options `boot.extraModprobeConfig` and `boot.blacklistedKernelModules` now also take effect in the initrd by copying the file `/etc/modprobe.d/nixos.conf` into the initrd.
- `nixos-generate-config` now puts the dhcp configuration in `hardware-configuration.nix` instead of `configuration.nix`.
- ORY Kratos was updated to version 0.8.3-alpha.1.pre.0, which introduces some breaking changes:
- ORY Kratos was updated to version 0.9.0-alpha.3, which introduces some breaking changes:
- All endpoints at the Admin API are now exposed at `/admin/`. For example, endpoint `https://kratos:4434/identities` is now exposed at `https://kratos:4434/admin/identities`
- Configuration key `selfservice.whitelisted_return_urls` has been renamed to `allowed_return_urls`
- The `password_identifier` form field of the password login strategy has been renamed to `identifier` to make compatibility with passwordless flows possible.
- Instead of having a global `default_schema_url` which developers used to update their schema, you now need to define the `default_schema_id` which must reference schema ID in your config.
- Calling `/self-service/recovery` without flow ID or with an invalid flow ID while authenticated will now respond with an error instead of redirecting to the default page.
- 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)
- [Release Notes for v0.9.0-alpha-1](https://github.com/ory/kratos/releases/tag/v0.9.0-alpha.1)
- [Release Notes for v0.9.0-alpha-3](https://github.com/ory/kratos/releases/tag/v0.9.0-alpha.3)
- `fetchFromSourcehut` now allows fetching repositories recursively
using `fetchgit` or `fetchhg` if the argument `fetchSubmodules`
is set to `true`.
- A module for declarative configuration of openconnect VPN profiles was added under `networking.openconnect`.
- The `element-desktop` package now has an `useKeytar` option (defaults to `true`),
which allows disabling `keytar` and in turn `libsecret` usage
(which binds to native credential managers / keychain libraries).
@ -541,18 +772,30 @@ In addition to numerous new and upgraded packages, this release has the followin
- `services.mattermost.plugins` has been added to allow the declarative installation of Mattermost plugins.
Plugins are automatically repackaged using autoPatchelf.
- `services.logrotate.enable` now defaults to true if any rotate path has
- [services.logrotate.enable](#opt-services.logrotate.enable) now defaults to true if any rotate path has
been defined, and some paths have been added by default.
- The logrotate module also has been updated to freeform syntax: [services.logrotate.paths](#opt-services.logrotate.paths)
and [services.logrotate.extraConfig](#opt-services.logrotate.extraConfig) will work, but issue deprecation
warnings and [services.logrotate.settings](#opt-services.logrotate.settings) should now be used instead.
- `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 `vscode-extensions.ionide.ionide-fsharp` package has been updated to 6.0.0 and now requires .NET 6.0.
- 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.
- A bug involving encrypt-on-receive has been fixed. Read the [zrepl documentation](https://zrepl.github.io/configuration/sendrecvoptions.html#job-recv-options-placeholder) and check the output of `zfs get -r encryption,zrepl:placeholder PATH_TO_ROOTFS` on the receiver.
- The `polybar` package has been updated from 3.5.7 to 3.6.2. See [the changelog](https://github.com/polybar/polybar/releases/tag/3.6.0) for more details.
- Breaking changes include changes to escaping rules in configuration values, changes in behavior when encountering invalid tag names, and changes to inter-process-messaging (IPC).
- Renamed option `services.openssh.challengeResponseAuthentication` to `services.openssh.kbdInteractiveAuthentication`.
Reason is that the old name has been deprecated upstream.
Using the old option name will still work, but produce a warning.
- `services.autorandr` now allows for adding hooks and profiles declaratively.
- The `pomerium-cli` command has been moved out of the `pomerium` package into
the `pomerium-cli` package, following upstream's repository split. If you are
using the `pomerium-cli` command, you should now install the `pomerium-cli`
@ -568,13 +811,29 @@ 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.
- xfsprogs was update to version 5.15, which enables inobtcount and bigtime by default on filesystem creation. Support for these features was added in kernel 5.10 and deemed stable in kernel 5.15.
If you want to be able to mount XFS filesystems created with this release of xfsprogs on kernel releases older than 5.10, you need to format them with `mkfs.xfs -m bigtime=0 -m inobtcount=0`.
- `services.xserver.desktopManager.xfce` now includes Xfce's screen locker, `xfce4-screensaver` that is enabled by default. You can disable it by setting `false` to [services.xserver.desktopManager.xfce.enableScreensaver](#opt-services.xserver.desktopManager.xfce.enableScreensaver).
- 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 `nss` package was split into `nss_esr` and `nss_latest`, with `nss` being an alias for `nss_esr`. This was done to ease maintenance of `nss` and dependent high-profile packages like `firefox`.
- The Nextcloud module now supports to create a Mysql database automatically
with `services.nextcloud.database.createLocally` enabled.
- 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.
- The option `services.snapserver.openFirewall` will no longer default to
`true` starting with NixOS 22.11. Enable it explicitly if you need to control
Snapserver remotely or connect streamig clients from other hosts.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

@ -170,6 +170,7 @@ let format' = format; in let
config.system.build.nixos-install
config.system.build.nixos-enter
nix
systemdMinimal
] ++ stdenv.initialPath);
# I'm preserving the line below because I'm going to search for it across nixpkgs to consolidate

@ -48,7 +48,9 @@ overrides = pivot(json.load(open(sys.argv[2 + optOffset], 'r')))
# fix up declaration paths in lazy options, since we don't eval them from a full nixpkgs dir
for (k, v) in options.items():
v.value['declarations'] = list(map(lambda s: f'nixos/modules/{s}', v.value['declarations']))
# The _module options are not declared in nixos/modules
if v.value['loc'][0] != "_module":
v.value['declarations'] = list(map(lambda s: f'nixos/modules/{s}', v.value['declarations']))
# merge both descriptions
for (k, v) in overrides.items():

@ -0,0 +1,322 @@
# Note: This is a private API, internal to NixOS. Its interface is subject
# to change without notice.
#
# The result of this builder is a single disk image, partitioned like this:
#
# * partition #1: a very small, 1MiB partition to leave room for Grub.
#
# * partition #2: boot, a partition formatted with FAT to be used for /boot.
# FAT is chosen to support EFI.
#
# * partition #3: nixos, a partition dedicated to a zpool.
#
# This single-disk approach does not satisfy ZFS's requirements for autoexpand,
# however automation can expand it anyway. For example, with
# `services.zfs.expandOnBoot`.
{ lib
, pkgs
, # The NixOS configuration to be installed onto the disk image.
config
, # size of the FAT partition, in megabytes.
bootSize ? 1024
, # The size of the root partition, in megabytes.
rootSize ? 2048
, # The name of the ZFS pool
rootPoolName ? "tank"
, # zpool properties
rootPoolProperties ? {
autoexpand = "on";
}
, # pool-wide filesystem properties
rootPoolFilesystemProperties ? {
acltype = "posixacl";
atime = "off";
compression = "on";
mountpoint = "legacy";
xattr = "sa";
}
, # datasets, with per-attribute options:
# mount: (optional) mount point in the VM
# properties: (optional) ZFS properties on the dataset, like filesystemProperties
# Notes:
# 1. datasets will be created from shorter to longer names as a simple topo-sort
# 2. you should define a root's dataset's mount for `/`
datasets ? { }
, # The files and directories to be placed in the target file system.
# This is a list of attribute sets {source, target} where `source'
# is the file system object (regular file or directory) to be
# grafted in the file system at path `target'.
contents ? [ ]
, # The initial NixOS configuration file to be copied to
# /etc/nixos/configuration.nix. This configuration will be embedded
# inside a configuration which includes the described ZFS fileSystems.
configFile ? null
, # Shell code executed after the VM has finished.
postVM ? ""
, name ? "nixos-disk-image"
, # Disk image format, one of qcow2, qcow2-compressed, vdi, vpc, raw.
format ? "raw"
, # Include a copy of Nixpkgs in the disk image
includeChannel ? true
}:
let
formatOpt = if format == "qcow2-compressed" then "qcow2" else format;
compress = lib.optionalString (format == "qcow2-compressed") "-c";
filenameSuffix = "." + {
qcow2 = "qcow2";
vdi = "vdi";
vpc = "vhd";
raw = "img";
}.${formatOpt} or formatOpt;
rootFilename = "nixos.root${filenameSuffix}";
# FIXME: merge with channel.nix / make-channel.nix.
channelSources =
let
nixpkgs = lib.cleanSource pkgs.path;
in
pkgs.runCommand "nixos-${config.system.nixos.version}" { } ''
mkdir -p $out
cp -prd ${nixpkgs.outPath} $out/nixos
chmod -R u+w $out/nixos
if [ ! -e $out/nixos/nixpkgs ]; then
ln -s . $out/nixos/nixpkgs
fi
rm -rf $out/nixos/.git
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix
'';
closureInfo = pkgs.closureInfo {
rootPaths = [ config.system.build.toplevel ]
++ (lib.optional includeChannel channelSources);
};
modulesTree = pkgs.aggregateModules
(with config.boot.kernelPackages; [ kernel zfs ]);
tools = lib.makeBinPath (
with pkgs; [
config.system.build.nixos-enter
config.system.build.nixos-install
dosfstools
e2fsprogs
gptfdisk
nix
parted
utillinux
zfs
]
);
hasDefinedMount = disk: ((disk.mount or null) != null);
stringifyProperties = prefix: properties: lib.concatStringsSep " \\\n" (
lib.mapAttrsToList
(
property: value: "${prefix} ${lib.escapeShellArg property}=${lib.escapeShellArg value}"
)
properties
);
featuresToProperties = features:
lib.listToAttrs
(builtins.map
(feature: {
name = "feature@${feature}";
value = "enabled";
})
features);
createDatasets =
let
datasetlist = lib.mapAttrsToList lib.nameValuePair datasets;
sorted = lib.sort (left: right: (lib.stringLength left.name) < (lib.stringLength right.name)) datasetlist;
cmd = { name, value }:
let
properties = stringifyProperties "-o" (value.properties or { });
in
"zfs create -p ${properties} ${name}";
in
lib.concatMapStringsSep "\n" cmd sorted;
mountDatasets =
let
datasetlist = lib.mapAttrsToList lib.nameValuePair datasets;
mounts = lib.filter ({ value, ... }: hasDefinedMount value) datasetlist;
sorted = lib.sort (left: right: (lib.stringLength left.value.mount) < (lib.stringLength right.value.mount)) mounts;
cmd = { name, value }:
''
mkdir -p /mnt${lib.escapeShellArg value.mount}
mount -t zfs ${name} /mnt${lib.escapeShellArg value.mount}
'';
in
lib.concatMapStringsSep "\n" cmd sorted;
unmountDatasets =
let
datasetlist = lib.mapAttrsToList lib.nameValuePair datasets;
mounts = lib.filter ({ value, ... }: hasDefinedMount value) datasetlist;
sorted = lib.sort (left: right: (lib.stringLength left.value.mount) > (lib.stringLength right.value.mount)) mounts;
cmd = { name, value }:
''
umount /mnt${lib.escapeShellArg value.mount}
'';
in
lib.concatMapStringsSep "\n" cmd sorted;
fileSystemsCfgFile =
let
mountable = lib.filterAttrs (_: value: hasDefinedMount value) datasets;
in
pkgs.runCommand "filesystem-config.nix"
{
buildInputs = with pkgs; [ jq nixpkgs-fmt ];
filesystems = builtins.toJSON {
fileSystems = lib.mapAttrs'
(
dataset: attrs:
{
name = attrs.mount;
value = {
fsType = "zfs";
device = "${dataset}";
};
}
)
mountable;
};
passAsFile = [ "filesystems" ];
} ''
(
echo "builtins.fromJSON '''"
jq . < "$filesystemsPath"
echo "'''"
) > $out
nixpkgs-fmt $out
'';
mergedConfig =
if configFile == null
then fileSystemsCfgFile
else
pkgs.runCommand "configuration.nix"
{
buildInputs = with pkgs; [ nixpkgs-fmt ];
}
''
(
echo '{ imports = ['
printf "(%s)\n" "$(cat ${fileSystemsCfgFile})";
printf "(%s)\n" "$(cat ${configFile})";
echo ']; }'
) > $out
nixpkgs-fmt $out
'';
image = (
pkgs.vmTools.override {
rootModules =
[ "zfs" "9p" "9pnet_virtio" "virtio_pci" "virtio_blk" ] ++
(pkgs.lib.optional pkgs.stdenv.hostPlatform.isx86 "rtc_cmos");
kernel = modulesTree;
}
).runInLinuxVM (
pkgs.runCommand name
{
memSize = 1024;
QEMU_OPTS = "-drive file=$rootDiskImage,if=virtio,cache=unsafe,werror=report";
preVM = ''
PATH=$PATH:${pkgs.qemu_kvm}/bin
mkdir $out
rootDiskImage=root.raw
qemu-img create -f raw $rootDiskImage ${toString (bootSize + rootSize)}M
'';
postVM = ''
${if formatOpt == "raw" then ''
mv $rootDiskImage $out/${rootFilename}
'' else ''
${pkgs.qemu}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $rootDiskImage $out/${rootFilename}
''}
rootDiskImage=$out/${rootFilename}
set -x
${postVM}
'';
} ''
export PATH=${tools}:$PATH
set -x
cp -sv /dev/vda /dev/sda
cp -sv /dev/vda /dev/xvda
parted --script /dev/vda -- \
mklabel gpt \
mkpart no-fs 1MiB 2MiB \
set 1 bios_grub on \
align-check optimal 1 \
mkpart primary fat32 2MiB ${toString bootSize}MiB \
align-check optimal 2 \
mkpart primary fat32 ${toString bootSize}MiB -1MiB \
align-check optimal 3 \
print
sfdisk --dump /dev/vda
zpool create \
${stringifyProperties " -o" rootPoolProperties} \
${stringifyProperties " -O" rootPoolFilesystemProperties} \
${rootPoolName} /dev/vda3
parted --script /dev/vda -- print
${createDatasets}
${mountDatasets}
mkdir -p /mnt/boot
mkfs.vfat -n ESP /dev/vda2
mount /dev/vda2 /mnt/boot
mount
# Install a configuration.nix
mkdir -p /mnt/etc/nixos
# `cat` so it is mutable on the fs
cat ${mergedConfig} > /mnt/etc/nixos/configuration.nix
export NIX_STATE_DIR=$TMPDIR/state
nix-store --load-db < ${closureInfo}/registration
nixos-install \
--root /mnt \
--no-root-passwd \
--system ${config.system.build.toplevel} \
--substituters "" \
${lib.optionalString includeChannel ''--channel ${channelSources}''}
df -h
umount /mnt/boot
${unmountDatasets}
zpool export ${rootPoolName}
''
);
in
image

@ -23,8 +23,8 @@ rec {
qemuBinary = qemuPkg: {
x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu max";
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -enable-kvm -machine virt -cpu host";
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -enable-kvm -machine virt,gic-version=host -cpu host";
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -machine virt,accel=kvm:tcg -cpu max";
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -machine virt,gic-version=max,accel=kvm:tcg -cpu max";
powerpc64le-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv";
powerpc64-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv";
x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max";

@ -23,8 +23,9 @@ in rec {
inherit (unit) text;
}
''
mkdir -p $out
echo -n "$text" > $out/${shellEscape name}
name=${shellEscape name}
mkdir -p "$out/$(dirname "$name")"
echo -n "$text" > "$out/$name"
''
else
pkgs.runCommand "unit-${mkPathSafeName name}-disabled"
@ -32,8 +33,9 @@ in rec {
allowSubstitutes = false;
}
''
mkdir -p $out
ln -s /dev/null $out/${shellEscape name}
name=${shellEscape name}
mkdir -p "$out/$(dirname "$name")"
ln -s /dev/null "$out/$name"
'';
boolValues = [true false "yes" "no"];
@ -120,10 +122,15 @@ in rec {
(if isList value then value else [value]))
as));
generateUnits = generateUnits' true;
generateUnits' = allowCollisions: type: units: upstreamUnits: upstreamWants:
pkgs.runCommand "${type}-units"
generateUnits = { allowCollisions ? true, type, units, upstreamUnits, upstreamWants, packages ? cfg.packages, package ? cfg.package }:
let
typeDir = ({
system = "system";
initrd = "system";
user = "user";
nspawn = "nspawn";
}).${type};
in pkgs.runCommand "${type}-units"
{ preferLocalBuild = true;
allowSubstitutes = false;
} ''
@ -131,7 +138,7 @@ in rec {
# Copy the upstream systemd units we're interested in.
for i in ${toString upstreamUnits}; do
fn=${cfg.package}/example/systemd/${type}/$i
fn=${package}/example/systemd/${typeDir}/$i
if ! [ -e $fn ]; then echo "missing $fn"; false; fi
if [ -L $fn ]; then
target="$(readlink "$fn")"
@ -148,7 +155,7 @@ in rec {
# Copy .wants links, but only those that point to units that
# we're interested in.
for i in ${toString upstreamWants}; do
fn=${cfg.package}/example/systemd/${type}/$i
fn=${package}/example/systemd/${typeDir}/$i
if ! [ -e $fn ]; then echo "missing $fn"; false; fi
x=$out/$(basename $fn)
mkdir $x
@ -160,14 +167,14 @@ in rec {
done
# Symlink all units provided listed in systemd.packages.
packages="${toString cfg.packages}"
packages="${toString packages}"
# Filter duplicate directories
declare -A unique_packages
for k in $packages ; do unique_packages[$k]=1 ; done
for i in ''${!unique_packages[@]}; do
for fn in $i/etc/systemd/${type}/* $i/lib/systemd/${type}/*; do
for fn in $i/etc/systemd/${typeDir}/* $i/lib/systemd/${typeDir}/*; do
if ! [[ "$fn" =~ .wants$ ]]; then
if [[ -d "$fn" ]]; then
targetDir="$out/$(basename "$fn")"
@ -268,9 +275,9 @@ in rec {
{ Conflicts = toString config.conflicts; }
// optionalAttrs (config.requisite != [])
{ Requisite = toString config.requisite; }
// optionalAttrs (config.restartTriggers != [])
// optionalAttrs (config ? restartTriggers && config.restartTriggers != [])
{ X-Restart-Triggers = toString config.restartTriggers; }
// optionalAttrs (config.reloadTriggers != [])
// optionalAttrs (config ? reloadTriggers && config.reloadTriggers != [])
{ X-Reload-Triggers = toString config.reloadTriggers; }
// optionalAttrs (config.description != "") {
Description = config.description; }
@ -286,45 +293,24 @@ in rec {
};
};
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;
})
];
serviceConfig = { config, ... }: {
config.environment.PATH = mkIf (config.path != []) "${makeBinPath config.path}:${makeSearchPathOutput "bin" "sbin" config.path}";
};
stage2ServiceConfig = {
imports = [ serviceConfig ];
# Default path for systemd services. Should be quite minimal.
config.path = mkAfter [
pkgs.coreutils
pkgs.findutils
pkgs.gnugrep
pkgs.gnused
systemd
];
};
stage1ServiceConfig = serviceConfig;
mountConfig = { config, ... }: {
config = {
mountConfig =
@ -372,12 +358,12 @@ in rec {
# 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 ''
${if def ? reloadIfChanged && def.reloadIfChanged then ''
X-ReloadIfChanged=true
'' else if !def.restartIfChanged then ''
'' else if (def ? restartIfChanged && !def.restartIfChanged) then ''
X-RestartIfChanged=false
'' else ""}
${optionalString (!def.stopIfChanged) "X-StopIfChanged=false"}
${optionalString (def ? stopIfChanged && !def.stopIfChanged) "X-StopIfChanged=false"}
${attrsToSection def.serviceConfig}
'';
};

@ -0,0 +1,37 @@
{ lib, systemdUtils }:
with systemdUtils.lib;
with systemdUtils.unitOptions;
with lib;
rec {
units = with types;
attrsOf (submodule ({ name, config, ... }: {
options = concreteUnitOptions;
config = { unit = mkDefault (systemdUtils.lib.makeUnit name config); };
}));
services = with types; attrsOf (submodule [ stage2ServiceOptions unitConfig stage2ServiceConfig ]);
initrdServices = with types; attrsOf (submodule [ stage1ServiceOptions unitConfig stage1ServiceConfig ]);
targets = with types; attrsOf (submodule [ stage2CommonUnitOptions unitConfig ]);
initrdTargets = with types; attrsOf (submodule [ stage1CommonUnitOptions unitConfig ]);
sockets = with types; attrsOf (submodule [ stage2SocketOptions unitConfig ]);
initrdSockets = with types; attrsOf (submodule [ stage1SocketOptions unitConfig ]);
timers = with types; attrsOf (submodule [ stage2TimerOptions unitConfig ]);
initrdTimers = with types; attrsOf (submodule [ stage1TimerOptions unitConfig ]);
paths = with types; attrsOf (submodule [ stage2PathOptions unitConfig ]);
initrdPaths = with types; attrsOf (submodule [ stage1PathOptions unitConfig ]);
slices = with types; attrsOf (submodule [ stage2SliceOptions unitConfig ]);
initrdSlices = with types; attrsOf (submodule [ stage1SliceOptions unitConfig ]);
mounts = with types; listOf (submodule [ stage2MountOptions unitConfig mountConfig ]);
initrdMounts = with types; listOf (submodule [ stage1MountOptions unitConfig mountConfig ]);
automounts = with types; listOf (submodule [ stage2AutomountOptions unitConfig automountConfig ]);
initrdAutomounts = with types; attrsOf (submodule [ stage1AutomountOptions unitConfig automountConfig ]);
}

@ -55,6 +55,7 @@ class Driver:
tmp_dir = get_tmp_dir()
with rootlog.nested("start all VLans"):
vlans = list(set(vlans))
self.vlans = [VLan(nr, tmp_dir) for nr in vlans]
def cmd(scripts: List[str]) -> Iterator[NixStartScript]:
@ -85,7 +86,7 @@ class Driver:
def subtest(self, name: str) -> Iterator[None]:
"""Group logs under a given test name"""
with rootlog.nested(name):
with rootlog.nested("subtest: " + name):
try:
yield
return True

@ -1,4 +1,4 @@
from colorama import Style
from colorama import Style, Fore
from contextlib import contextmanager
from typing import Any, Dict, Iterator
from queue import Queue, Empty
@ -81,7 +81,11 @@ class Logger:
@contextmanager
def nested(self, message: str, attributes: Dict[str, str] = {}) -> Iterator[None]:
self._eprint(self.maybe_prefix(message, attributes))
self._eprint(
self.maybe_prefix(
Style.BRIGHT + Fore.GREEN + message + Style.RESET_ALL, attributes
)
)
self.xml.startElement("nest", attrs={})
self.xml.startElement("head", attributes)

@ -198,7 +198,7 @@ class StartCommand:
) -> subprocess.Popen:
return subprocess.Popen(
self.cmd(monitor_socket_path, shell_socket_path),
stdin=subprocess.DEVNULL,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
@ -526,10 +526,17 @@ class Machine:
self.run_callbacks()
self.connect()
# Always run command with shell opts
command = f"set -euo pipefail; {command}"
timeout_str = ""
if timeout is not None:
command = "timeout {} sh -c {}".format(timeout, shlex.quote(command))
timeout_str = f"timeout {timeout}"
out_command = (
f"{timeout_str} sh -c {shlex.quote(command)} | (base64 --wrap 0; echo)\n"
)
out_command = f"( set -euo pipefail; {command} ) | (base64 --wrap 0; echo)\n"
assert self.shell
self.shell.send(out_command.encode())
@ -558,6 +565,28 @@ class Machine:
pass_fds=[self.shell.fileno()],
)
def console_interact(self) -> None:
"""Allows you to interact with QEMU's stdin
The shell can be exited with Ctrl+D. Note that Ctrl+C is not allowed to be used.
QEMU's stdout is read line-wise.
Should only be used during test development, not in the production test."""
self.log("Terminal is ready (there is no prompt):")
assert self.process
assert self.process.stdin
while True:
try:
char = sys.stdin.buffer.read(1)
except KeyboardInterrupt:
break
if char == b"": # ctrl+d
self.log("Closing connection to the console")
break
self.send_console(char.decode())
def succeed(self, *commands: str, timeout: Optional[int] = None) -> str:
"""Execute each command and check that it succeeds."""
output = ""
@ -834,6 +863,12 @@ class Machine:
self.send_monitor_command("sendkey {}".format(key))
time.sleep(0.01)
def send_console(self, chars: str) -> None:
assert self.process
assert self.process.stdin
self.process.stdin.write(chars.encode())
self.process.stdin.flush()
def start(self) -> None:
if self.booted:
return

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

@ -194,8 +194,25 @@ rec {
(( ! $inherit_errexit_enabled )) && shopt -u inherit_errexit
'';
/* Remove packages of packagesToRemove from packages, based on their names.
Relies on package names and has quadratic complexity so use with caution!
Type:
removePackagesByName :: [package] -> [package] -> [package]
Example:
removePackagesByName [ nautilus file-roller ] [ file-roller totem ]
=> [ nautilus ]
*/
removePackagesByName = packages: packagesToRemove:
let
namesToRemove = map lib.getName packagesToRemove;
in
lib.filter (x: !(builtins.elem (lib.getName x) namesToRemove)) packages;
systemdUtils = {
lib = import ./systemd-lib.nix { inherit lib config pkgs; };
unitOptions = import ./systemd-unit-options.nix { inherit lib systemdUtils; };
types = import ./systemd-types.nix { inherit lib systemdUtils; };
};
}

@ -73,7 +73,7 @@ in {
}
'';
zfsBuilder = import ../../../lib/make-zfs-image.nix {
zfsBuilder = import ../../../lib/make-multi-disk-zfs-image.nix {
inherit lib config configFile;
inherit (cfg) contents format name;
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package

@ -0,0 +1,101 @@
# nix-build '<nixpkgs/nixos>' -A config.system.build.openstackImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/openstack-image.nix ]; }"
{ config, lib, pkgs, ... }:
let
inherit (lib) mkOption types;
copyChannel = true;
cfg = config.openstackImage;
imageBootMode = if config.openstack.efi then "uefi" else "legacy-bios";
in
{
imports = [
../../../modules/virtualisation/openstack-config.nix
] ++ (lib.optional copyChannel ../../../modules/installer/cd-dvd/channel.nix);
options.openstackImage = {
name = mkOption {
type = types.str;
description = "The name of the generated derivation";
default = "nixos-openstack-image-${config.system.nixos.label}-${pkgs.stdenv.hostPlatform.system}";
};
sizeMB = mkOption {
type = types.int;
default = 8192;
description = "The size in MB of the image";
};
format = mkOption {
type = types.enum [ "raw" "qcow2" ];
default = "qcow2";
description = "The image format to output";
};
};
config = {
documentation.enable = copyChannel;
openstack = {
efi = true;
zfs = {
enable = true;
datasets = {
"tank/system/root".mount = "/";
"tank/system/var".mount = "/var";
"tank/local/nix".mount = "/nix";
"tank/user/home".mount = "/home";
};
};
};
system.build.openstackImage = import ../../../lib/make-single-disk-zfs-image.nix {
inherit lib config;
inherit (cfg) contents format name;
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
configFile = pkgs.writeText "configuration.nix"
''
{ modulesPath, ... }: {
imports = [ "''${modulesPath}/virtualisation/openstack-config.nix" ];
openstack.zfs.enable = true;
}
'';
includeChannel = copyChannel;
bootSize = 1000;
rootSize = cfg.sizeMB;
rootPoolProperties = {
ashift = 12;
autoexpand = "on";
};
datasets = config.openstack.zfs.datasets;
postVM = ''
extension=''${rootDiskImage##*.}
friendlyName=$out/${cfg.name}
rootDisk="$friendlyName.root.$extension"
mv "$rootDiskImage" "$rootDisk"
mkdir -p $out/nix-support
echo "file ${cfg.format} $rootDisk" >> $out/nix-support/hydra-build-products
${pkgs.jq}/bin/jq -n \
--arg system_label ${lib.escapeShellArg config.system.nixos.label} \
--arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \
--arg root_logical_bytes "$(${pkgs.qemu}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \
--arg boot_mode "${imageBootMode}" \
--arg root "$rootDisk" \
'{}
| .label = $system_label
| .boot_mode = $boot_mode
| .system = $system
| .disks.root.logical_bytes = $root_logical_bytes
| .disks.root.file = $root
' > $out/nix-support/image-info.json
'';
};
};
}

@ -1,17 +1,18 @@
# nix-build '<nixpkgs/nixos>' -A config.system.build.openstackImage --arg configuration "{ imports = [ ./nixos/maintainers/scripts/openstack/openstack-image.nix ]; }"
{ config, lib, pkgs, ... }:
with lib;
let
copyChannel = true;
in
{
imports =
[ ../../../modules/installer/cd-dvd/channel.nix
../../../modules/virtualisation/openstack-config.nix
];
imports = [
../../../modules/virtualisation/openstack-config.nix
] ++ (lib.optional copyChannel ../../../modules/installer/cd-dvd/channel.nix);
documentation.enable = copyChannel;
system.build.openstackImage = import ../../../lib/make-disk-image.nix {
inherit lib config;
inherit lib config copyChannel;
additionalSpace = "1024M";
pkgs = import ../../../.. { inherit (pkgs) system; }; # ensure we use the regular qemu-kvm package
format = "qcow2";

@ -12,7 +12,7 @@ let
optimizedKeymap = pkgs.runCommand "keymap" {
nativeBuildInputs = [ pkgs.buildPackages.kbd ];
LOADKEYS_KEYMAP_PATH = "${consoleEnv}/share/keymaps/**";
LOADKEYS_KEYMAP_PATH = "${consoleEnv pkgs.kbd}/share/keymaps/**";
preferLocalBuild = true;
} ''
loadkeys -b ${optionalString isUnicode "-u"} "${cfg.keyMap}" > $out
@ -24,9 +24,9 @@ let
FONT=${cfg.font}
'';
consoleEnv = pkgs.buildEnv {
consoleEnv = kbd: pkgs.buildEnv {
name = "console-env";
paths = [ pkgs.kbd ] ++ cfg.packages;
paths = [ kbd ] ++ cfg.packages;
pathsToLink = [
"/share/consolefonts"
"/share/consoletrans"
@ -136,9 +136,9 @@ in
# virtual consoles.
environment.etc."vconsole.conf".source = vconsoleConf;
# Provide kbd with additional packages.
environment.etc.kbd.source = "${consoleEnv}/share";
environment.etc.kbd.source = "${consoleEnv pkgs.kbd}/share";
boot.initrd.preLVMCommands = mkBefore ''
boot.initrd.preLVMCommands = mkIf (!config.boot.initrd.systemd.enable) (mkBefore ''
kbd_mode ${if isUnicode then "-u" else "-a"} -C /dev/console
printf "\033%%${if isUnicode then "G" else "@"}" >> /dev/console
loadkmap < ${optimizedKeymap}
@ -146,12 +146,23 @@ in
${optionalString cfg.earlySetup ''
setfont -C /dev/console $extraUtils/share/consolefonts/font.psf
''}
'';
'');
boot.initrd.systemd.contents = {
"/etc/kbd".source = "${consoleEnv config.boot.initrd.systemd.package.kbd}/share";
"/etc/vconsole.conf".source = vconsoleConf;
};
boot.initrd.systemd.storePaths = [
"${config.boot.initrd.systemd.package}/lib/systemd/systemd-vconsole-setup"
"${config.boot.initrd.systemd.package.kbd}/bin/setfont"
"${config.boot.initrd.systemd.package.kbd}/bin/loadkeys"
"${config.boot.initrd.systemd.package.kbd.gzip}/bin/gzip" # keyboard layouts are compressed
];
systemd.services.reload-systemd-vconsole-setup =
{ description = "Reset console on configuration changes";
wantedBy = [ "multi-user.target" ];
restartTriggers = [ vconsoleConf consoleEnv ];
restartTriggers = [ vconsoleConf (consoleEnv pkgs.kbd) ];
reloadIfChanged = true;
serviceConfig =
{ RemainAfterExit = true;
@ -175,7 +186,7 @@ in
${if substring 0 1 cfg.font == "/" then ''
font="${cfg.font}"
'' else ''
font="$(echo ${consoleEnv}/share/consolefonts/${cfg.font}.*)"
font="$(echo ${consoleEnv pkgs.kbd}/share/consolefonts/${cfg.font}.*)"
''}
if [[ $font == *.gz ]]; then
gzip -cd $font > $out/share/consolefonts/font.psf
@ -183,6 +194,10 @@ in
cp -L $font $out/share/consolefonts/font.psf
fi
'';
assertions = [{
assertion = !config.boot.initrd.systemd.enable;
message = "console.earlySetup is implied by systemd stage 1";
}];
})
]))
];

@ -95,11 +95,14 @@ with lib;
config = {
assertions = [
{
# Prevent users from disabling nscd, with nssModules being set.
# If disabling nscd is really necessary, it's still possible to opt out
# by forcing config.system.nssModules to [].
assertion = config.system.nssModules.path != "" -> config.services.nscd.enable;
message = "Loading NSS modules from system.nssModules (${config.system.nssModules.path}), requires services.nscd.enable being set to true.";
message = ''
Loading NSS modules from system.nssModules (${config.system.nssModules.path}),
requires services.nscd.enable being set to true.
If disabling nscd is really necessary, it is possible to disable loading NSS modules
by setting `system.nssModules = lib.mkForce [];` in your configuration.nix.
'';
}
];

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

@ -1,9 +1,33 @@
# This module manages the terminfo database
# and its integration in the system.
{ config, ... }:
{ config, lib, pkgs, ... }:
with lib;
{
options.environment.enableAllTerminfo = with lib; mkOption {
default = false;
type = types.bool;
description = ''
Whether to install all terminfo outputs
'';
};
config = {
# can be generated with: filter (drv: (builtins.tryEval (drv ? terminfo)).value) (attrValues pkgs)
environment.systemPackages = mkIf config.environment.enableAllTerminfo (map (x: x.terminfo) (with pkgs; [
alacritty
foot
kitty
mtm
rxvt-unicode-unwrapped
rxvt-unicode-unwrapped-emoji
termite
wezterm
]));
environment.pathsToLink = [
"/share/terminfo"
];

@ -51,9 +51,10 @@ in
(isYes "KALLSYMS_ALL")
];
boot.initrd.extraUdevRulesCommands = ''
boot.initrd.extraUdevRulesCommands = mkIf (!config.boot.initrd.systemd.enable) ''
cp -v ${package}/etc/udev/rules.d/*.rules $out/
'';
boot.initrd.services.udev.packages = [ package ];
environment.systemPackages =
[ package.vulkan ] ++

@ -24,6 +24,7 @@ let
primeEnabled = syncCfg.enable || offloadCfg.enable;
nvidiaPersistencedEnabled = cfg.nvidiaPersistenced;
nvidiaSettings = cfg.nvidiaSettings;
busIDType = types.strMatching "([[:print:]]+\:[0-9]{1,3}\:[0-9]{1,2}\:[0-9])?";
in
{
@ -68,7 +69,7 @@ in
};
hardware.nvidia.prime.nvidiaBusId = mkOption {
type = types.str;
type = busIDType;
default = "";
example = "PCI:1:0:0";
description = ''
@ -78,7 +79,7 @@ in
};
hardware.nvidia.prime.intelBusId = mkOption {
type = types.str;
type = busIDType;
default = "";
example = "PCI:0:2:0";
description = ''
@ -88,7 +89,7 @@ in
};
hardware.nvidia.prime.amdgpuBusId = mkOption {
type = types.str;
type = busIDType;
default = "";
example = "PCI:4:0:0";
description = ''
@ -244,7 +245,7 @@ in
modules = optional (igpuDriver == "amdgpu") [ pkgs.xorg.xf86videoamdgpu ];
deviceSection = ''
BusID "${igpuBusId}"
${optionalString syncCfg.enable ''Option "AccelMethod" "none"''}
${optionalString (syncCfg.enable && igpuDriver != "amdgpu") ''Option "AccelMethod" "none"''}
'';
} ++ singleton {
name = "nvidia";
@ -269,9 +270,15 @@ in
Option "AllowNVIDIAGPUScreens"
'';
services.xserver.displayManager.setupCommands = optionalString syncCfg.enable ''
services.xserver.displayManager.setupCommands = let
sinkGpuProviderName = if igpuDriver == "amdgpu" then
# find the name of the provider if amdgpu
"`${pkgs.xorg.xrandr}/bin/xrandr --listproviders | ${pkgs.gnugrep}/bin/grep -i AMD | ${pkgs.gnused}/bin/sed -n 's/^.*name://p'`"
else
igpuDriver;
in optionalString syncCfg.enable ''
# Added by nvidia configuration module for Optimus/PRIME.
${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource ${igpuDriver} NVIDIA-0
${pkgs.xorg.xrandr}/bin/xrandr --setprovideroutputsource "${sinkGpuProviderName}" NVIDIA-0
${pkgs.xorg.xrandr}/bin/xrandr --auto
'';
@ -283,14 +290,14 @@ in
environment.etc."egl/egl_external_platform.d".source =
"/run/opengl-driver/share/egl/egl_external_platform.d/";
hardware.opengl.package = mkIf (!offloadCfg.enable) nvidia_x11.out;
hardware.opengl.package32 = mkIf (!offloadCfg.enable) nvidia_x11.lib32;
hardware.opengl.extraPackages = [
nvidia_x11.out
pkgs.nvidia-vaapi-driver
] ++ optional offloadCfg.enable nvidia_x11.out;
];
hardware.opengl.extraPackages32 = [
nvidia_x11.lib32
pkgs.pkgsi686Linux.nvidia-vaapi-driver
] ++ optional offloadCfg.enable nvidia_x11.lib32;
];
environment.systemPackages = [ nvidia_x11.bin ]
++ optionals cfg.nvidiaSettings [ nvidia_x11.settings ]

@ -16,11 +16,6 @@ in
config = mkIf cfg.enable {
assertions = singleton {
assertion = versionAtLeast kernelPackages.kernel.version "3.19";
message = "facetimehd is not supported for kernels older than 3.19";
};
boot.kernelModules = [ "facetimehd" ];
boot.blacklistedKernelModules = [ "bdc_pci" ];

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

Loading…
Cancel
Save