Merge commit 'cf3ab54b4afe2b7477faa1dd0b65bf74c055d70c' into newmain

Update on 2022-07-01
main
Katharina Fey 2 years ago
commit 52e4445b26
Signed by: kookie
GPG Key ID: 90734A9E619C8A6C
  1. 4
      infra/libkookie/nixpkgs/unstable/.gitignore
  2. 4
      infra/libkookie/nixpkgs/unstable/doc/build-aux/pandoc-filters/docbook-writer/rst-roles.lua
  3. 2
      infra/libkookie/nixpkgs/unstable/doc/builders/images/dockertools.section.md
  4. 4
      infra/libkookie/nixpkgs/unstable/doc/contributing/coding-conventions.chapter.md
  5. 20
      infra/libkookie/nixpkgs/unstable/doc/contributing/contributing-to-documentation.chapter.md
  6. 105
      infra/libkookie/nixpkgs/unstable/doc/contributing/reviewing-contributions.chapter.md
  7. 2
      infra/libkookie/nixpkgs/unstable/doc/contributing/submitting-changes.chapter.md
  8. 15
      infra/libkookie/nixpkgs/unstable/doc/doc-support/default.nix
  9. 2
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/coq.section.md
  10. 2
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/dotnet.section.md
  11. 67
      infra/libkookie/nixpkgs/unstable/doc/languages-frameworks/python.section.md
  12. 650
      infra/libkookie/nixpkgs/unstable/doc/release-notes.xml
  13. 18
      infra/libkookie/nixpkgs/unstable/doc/stdenv/cross-compilation.chapter.md
  14. 4
      infra/libkookie/nixpkgs/unstable/lib/default.nix
  15. 1
      infra/libkookie/nixpkgs/unstable/lib/modules.nix
  16. 23
      infra/libkookie/nixpkgs/unstable/lib/options.nix
  17. 31
      infra/libkookie/nixpkgs/unstable/lib/tests/maintainer-module.nix
  18. 37
      infra/libkookie/nixpkgs/unstable/lib/tests/maintainers.nix
  19. 7
      infra/libkookie/nixpkgs/unstable/lib/tests/modules.sh
  20. 20
      infra/libkookie/nixpkgs/unstable/lib/tests/modules/deferred-module-error.nix
  21. 58
      infra/libkookie/nixpkgs/unstable/lib/tests/modules/deferred-module.nix
  22. 3
      infra/libkookie/nixpkgs/unstable/lib/tests/modules/define-settingsDict-a-is-b.nix
  23. 4
      infra/libkookie/nixpkgs/unstable/lib/tests/release.nix
  24. 50
      infra/libkookie/nixpkgs/unstable/lib/tests/teams.nix
  25. 30
      infra/libkookie/nixpkgs/unstable/lib/types.nix
  26. 379
      infra/libkookie/nixpkgs/unstable/maintainers/maintainer-list.nix
  27. 1
      infra/libkookie/nixpkgs/unstable/maintainers/scripts/luarocks-packages.csv
  28. 16
      infra/libkookie/nixpkgs/unstable/maintainers/team-list.nix
  29. 11
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/configuration/xfce.chapter.md
  30. 6
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/default.nix
  31. 2
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/development/activation-script.section.md
  32. 9
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/development/option-declarations.section.md
  33. 19
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/development/option-types.section.md
  34. 14
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/configuration/xfce.chapter.xml
  35. 2
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/development/activation-script.section.xml
  36. 12
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/development/option-declarations.section.xml
  37. 37
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/development/option-types.section.xml
  38. 14
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/release-notes/rl-2205.section.xml
  39. 155
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
  40. 6
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/release-notes/rl-2205.section.md
  41. 53
      infra/libkookie/nixpkgs/unstable/nixos/doc/manual/release-notes/rl-2211.section.md
  42. 9
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-ext4-fs.nix
  43. 23
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-options-doc/default.nix
  44. 152
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-options-doc/mergeJSON.py
  45. 21
      infra/libkookie/nixpkgs/unstable/nixos/lib/make-options-doc/options-to-docbook.xsl
  46. 11
      infra/libkookie/nixpkgs/unstable/nixos/lib/systemd-unit-options.nix
  47. 1
      infra/libkookie/nixpkgs/unstable/nixos/lib/test-driver/setup.py
  48. 4
      infra/libkookie/nixpkgs/unstable/nixos/lib/testing-python.nix
  49. 4
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/console.nix
  50. 19
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/debug-info.nix
  51. 17
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/fonts/fontconfig.nix
  52. 13
      infra/libkookie/nixpkgs/unstable/nixos/modules/config/i18n.nix
  53. 18
      infra/libkookie/nixpkgs/unstable/nixos/modules/hardware/device-tree.nix
  54. 19
      infra/libkookie/nixpkgs/unstable/nixos/modules/hardware/video/nvidia.nix
  55. 3
      infra/libkookie/nixpkgs/unstable/nixos/modules/installer/cd-dvd/installation-cd-graphical-calamares-gnome.nix
  56. 15
      infra/libkookie/nixpkgs/unstable/nixos/modules/installer/sd-card/sd-image.nix
  57. 7
      infra/libkookie/nixpkgs/unstable/nixos/modules/installer/tools/get-version-suffix
  58. 9
      infra/libkookie/nixpkgs/unstable/nixos/modules/installer/tools/nixos-generate-config.pl
  59. 31
      infra/libkookie/nixpkgs/unstable/nixos/modules/misc/documentation.nix
  60. 6
      infra/libkookie/nixpkgs/unstable/nixos/modules/misc/ids.nix
  61. 8
      infra/libkookie/nixpkgs/unstable/nixos/modules/misc/man-db.nix
  62. 108
      infra/libkookie/nixpkgs/unstable/nixos/modules/misc/nixpkgs.nix
  63. 61
      infra/libkookie/nixpkgs/unstable/nixos/modules/misc/nixpkgs/test.nix
  64. 8
      infra/libkookie/nixpkgs/unstable/nixos/modules/module-list.nix
  65. 3
      infra/libkookie/nixpkgs/unstable/nixos/modules/profiles/minimal.nix
  66. 21
      infra/libkookie/nixpkgs/unstable/nixos/modules/programs/clickshare.nix
  67. 44
      infra/libkookie/nixpkgs/unstable/nixos/modules/programs/thunar.nix
  68. 1
      infra/libkookie/nixpkgs/unstable/nixos/modules/rename.nix
  69. 11
      infra/libkookie/nixpkgs/unstable/nixos/modules/security/systemd-confinement.nix
  70. 3
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/audio/navidrome.nix
  71. 21
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/cluster/k3s/default.nix
  72. 127
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/databases/cassandra.nix
  73. 148
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/databases/dgraph.nix
  74. 162
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/databases/riak.nix
  75. 5
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/desktops/pipewire/pipewire.nix
  76. 15
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/desktops/pipewire/wireplumber.nix
  77. 58
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/hardware/argonone.nix
  78. 19
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/home-automation/home-assistant.nix
  79. 2
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/logging/logrotate.nix
  80. 162
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/mail/schleuder.nix
  81. 3
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/matrix/appservice-irc.nix
  82. 18
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/matrix/synapse.nix
  83. 53
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/misc/geoipupdate.nix
  84. 28
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/misc/gitlab.nix
  85. 9
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/misc/gollum.nix
  86. 2
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/misc/paperless.nix
  87. 10
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/misc/radarr.nix
  88. 143
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/monitoring/grafana-agent.nix
  89. 163
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/monitoring/parsedmarc.nix
  90. 2
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/monitoring/prometheus/exporters/postfix.nix
  91. 4
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/network-filesystems/ipfs.nix
  92. 1
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/networking/bitlbee.nix
  93. 40
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/networking/mosquitto.nix
  94. 79
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/networking/prosody.nix
  95. 84
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/networking/routedns.nix
  96. 110
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/networking/syncthing.nix
  97. 13
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/networking/tailscale.nix
  98. 20
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/networking/trickster.nix
  99. 72
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/security/vaultwarden/default.nix
  100. 9
      infra/libkookie/nixpkgs/unstable/nixos/modules/services/web-apps/nextcloud.nix
  101. Some files were not shown because too many files have changed in this diff Show More

@ -5,13 +5,13 @@
.idea/
.vscode/
outputs/
result
result-*
source/
/doc/NEWS.html
/doc/NEWS.txt
/doc/manual.html
/doc/manual.pdf
/result
/source/
.version-suffix
.DS_Store

@ -27,6 +27,10 @@ function Code(elem)
content = '<refentrytitle>' .. title .. '</refentrytitle>' .. (volnum ~= nil and ('<manvolnum>' .. volnum .. '</manvolnum>') or '')
elseif elem.attributes['role'] == 'file' then
tag = 'filename'
elseif elem.attributes['role'] == 'command' then
tag = 'command'
elseif elem.attributes['role'] == 'option' then
tag = 'option'
end
if tag ~= nil then

@ -302,7 +302,7 @@ buildImage {
runAsRoot = ''
#!${pkgs.runtimeShell}
${shadowSetup}
${pkgs.dockerTools.shadowSetup}
groupadd -r redis
useradd -r -g redis redis
mkdir /data

@ -338,6 +338,10 @@ A (typically large) program with a distinct user interface, primarily used inter
- `applications/terminal-emulators` (e.g. `alacritty` or `rxvt` or `termite`)
- **If it’s a _file manager_:**
- `applications/file-managers` (e.g. `mc` or `ranger` or `pcmanfm`)
- **If it’s for _video playback / editing_:**
- `applications/video` (e.g. `vlc`)

@ -27,7 +27,7 @@ If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.
As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
Additionally, the following syntax extensions are currently used:
Additional syntax extensions are available, though not all extensions can be used in NixOS option documentation. The following extensions are currently used:
- []{#ssec-contributing-markup-anchors}
Explicitly defined **anchors** on headings, to allow linking to sections. These should be always used, to ensure the anchors can be linked even when the heading text changes, and to prevent conflicts between [automatically assigned identifiers](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/auto_identifiers.md).
@ -53,12 +53,22 @@ Additionally, the following syntax extensions are currently used:
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/using/syntax.html#targets-and-cross-referencing).
- []{#ssec-contributing-markup-inline-roles}
If you want to link to a man page, you can use `` {manpage}`nix.conf(5)` ``, which will turn into {manpage}`nix.conf(5)`.
If you want to link to a man page, you can use `` {manpage}`nix.conf(5)` ``, which will turn into {manpage}`nix.conf(5)`. The references will turn into links when a mapping exists in {file}`doc/build-aux/pandoc-filters/link-unix-man-references.lua`.
The references will turn into links when a mapping exists in {file}`doc/build-aux/pandoc-filters/link-unix-man-references.lua`.
A few markups for other kinds of literals are also available:
- `` {command}`rm -rfi` `` turns into {command}`rm -rfi`
- `` {option}`networking.useDHCP` `` turns into {option}`networking.useDHCP`
- `` {file}`/etc/passwd` `` turns into {file}`/etc/passwd`
These literal kinds are used mostly in NixOS option documentation.
This syntax is taken from [MyST](https://myst-parser.readthedocs.io/en/latest/syntax/syntax.html#roles-an-in-line-extension-point). Though, the feature originates from [reStructuredText](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-manpage) with slightly different syntax.
::: {.note}
Inline roles are available for option documentation.
:::
- []{#ssec-contributing-markup-admonitions}
**Admonitions**, set off from the text to bring attention to something.
@ -84,6 +94,10 @@ Additionally, the following syntax extensions are currently used:
- [`tip`](https://tdg.docbook.org/tdg/5.0/tip.html)
- [`warning`](https://tdg.docbook.org/tdg/5.0/warning.html)
::: {.note}
Admonitions are available for option documentation.
:::
- []{#ssec-contributing-markup-definition-lists}
[**Definition lists**](https://github.com/jgm/commonmark-hs/blob/master/commonmark-extensions/test/definition_lists.md), for defining a group of terms:

@ -185,6 +185,111 @@ Sample template for a new module review is provided below.
##### Comments
```
## Individual maintainer list {#reviewing-contributions-indvidual-maintainer-list}
When adding users to `maintainers/maintainer-list.nix`, the following
checks should be performed:
- If the user has specified a GPG key, verify that the commit is
signed by their key.
First, validate that the commit adding the maintainer is signed by
the key the maintainer listed. Check out the pull request and
compare its signing key with the listed key in the commit.
If the commit is not signed or it is signed by a different user, ask
them to either recommit using that key or to remove their key
information.
Given a maintainter entry like this:
``` nix
{
example = {
email = "user@example.com";
name = "Example User";
keys = [{
fingerprint = "0000 0000 2A70 6423 0AED 3C11 F04F 7A19 AAA6 3AFE";
}];
}
};
```
First receive their key from a keyserver:
$ gpg --recv-keys 0xF04F7A19AAA63AFE
gpg: key 0xF04F7A19AAA63AFE: public key "Example <user@example.com>" imported
gpg: Total number processed: 1
gpg: imported: 1
Then check the commit is signed by that key:
$ git log --show-signature
commit b87862a4f7d32319b1de428adb6cdbdd3a960153
gpg: Signature made Wed Mar 12 13:32:24 2003 +0000
gpg: using RSA key 000000002A7064230AED3C11F04F7A19AAA63AFE
gpg: Good signature from "Example User <user@example.com>
Author: Example User <user@example.com>
Date: Wed Mar 12 13:32:24 2003 +0000
maintainers: adding example
and validate that there is a `Good signature` and the printed key
matches the user's submitted key.
Note: GitHub's "Verified" label does not display the user's full key
fingerprint, and should not be used for validating the key matches.
- If the user has specified a `github` account name, ensure they have
also specified a `githubId` and verify the two match.
Maintainer entries that include a `github` field must also include
their `githubId`. People can and do change their GitHub name
frequently, and the ID is used as the official and stable identity
of the maintainer.
Given a maintainer entry like this:
``` nix
{
example = {
email = "user@example.com";
name = "Example User";
github = "ghost";
githubId = 10137;
}
};
```
First, make sure that the listed GitHub handle matches the author of
the commit.
Then, visit the URL `https://api.github.com/users/ghost` and
validate that the `id` field matches the provided `githubId`.
## Maintainer teams {#reviewing-contributions-maintainer-teams}
Feel free to create a new maintainer team in `maintainers/team-list.nix`
when a group is collectively responsible for a collection of packages.
Use taste and personal judgement when deciding if a team is warranted.
Teams are allowed to define their own rules about membership.
For example, some teams will represent a business or other group which
wants to carefully track its members. Other teams may be very open about
who can join, and allow anybody to participate.
When reviewing changes to a team, read the team's scope and the context
around the member list for indications about the team's membership
policy.
In any case, request reviews from the existing team members. If the team
lists no specific membership policy, feel free to merge changes to the
team after giving the existing members a few days to respond.
*Important:* If a team says it is a closed group, do not merge additions
to the team without an approval by at least one existing member.
## Other submissions {#reviewing-contributions-other-submissions}
Other type of submissions requires different reviewing steps.

@ -227,7 +227,7 @@ digraph {
}
```
[This GitHub Action](https://github.com/NixOS/nixpkgs/blob/master/.github/workflows/periodic-merge-6h.yml) brings changes from `master` to `staging-next` and from `staging-next` to `staging` every 6 hours.
[This GitHub Action](https://github.com/NixOS/nixpkgs/blob/master/.github/workflows/periodic-merge-6h.yml) brings changes from `master` to `staging-next` and from `staging-next` to `staging` every 6 hours; these are the blue arrows in the diagram above. The purple arrows in the diagram above are done manually and much less frequently. You can get an idea of how often these merges occur by looking at the git history.
### Master branch {#submitting-changes-master-branch}

@ -1,5 +1,8 @@
{ pkgs ? (import ../.. {}), nixpkgs ? { }}:
let
inherit (pkgs) lib;
inherit (lib) hasPrefix removePrefix;
locationsXml = import ./lib-function-locations.nix { inherit pkgs nixpkgs; };
functionDocs = import ./lib-function-docs.nix { inherit locationsXml pkgs; };
version = pkgs.lib.version;
@ -29,6 +32,18 @@ let
optionsDoc = pkgs.nixosOptionsDoc {
inherit (pkgs.lib.evalModules { modules = [ ../../pkgs/top-level/config.nix ]; }) options;
documentType = "none";
transformOptions = opt:
opt // {
declarations =
map
(decl:
if hasPrefix (toString ../..) (toString decl)
then
let subpath = removePrefix "/" (removePrefix (toString ../..) (toString decl));
in { url = "https://github.com/NixOS/nixpkgs/blob/master/${subpath}"; name = subpath; }
else decl)
opt.declarations;
};
};
in pkgs.runCommand "doc-support" {}

@ -41,7 +41,7 @@ The recommended way of defining a derivation for a Coq library, is to use the `c
* `useDune2` (optional, defaults to `false`) uses Dune2 to build the package if set to true, the presence of this attribute overrides the behavior of the previous one.
* `opam-name` (optional, defaults to concatenating with a dash separator the components of `namePrefix` and `pname`), name of the Dune package to build.
* `enableParallelBuilding` (optional, defaults to `true`), since it is activated by default, we provide a way to disable it.
* `extraInstallFlags` (optional), allows to extend `installFlags` which initializes the variables `DESTDIR` and `COQMF_COQLIB` so as to install in the proper subdirectory. Indeed Coq libraries should be installed in `$(out)/lib/coq/${coq.coq-version}/user-contrib/`. Such directories are automatically added to the `$COQPATH` environment variable by the hook defined in the Coq derivation.
* `extraInstallFlags` (optional), allows to extend `installFlags` which initializes the variable `COQMF_COQLIB` so as to install in the proper subdirectory. Indeed Coq libraries should be installed in `$(out)/lib/coq/${coq.coq-version}/user-contrib/`. Such directories are automatically added to the `$COQPATH` environment variable by the hook defined in the Coq derivation.
* `setCOQBIN` (optional, defaults to `true`), by default, the environment variable `$COQBIN` is set to the current Coq's binary, but one can disable this behavior by setting it to `false`,
* `useMelquiondRemake` (optional, default to `null`) is an attribute set, which, if given, overloads the `preConfigurePhases`, `configureFlags`, `buildPhase`, and `installPhase` attributes of the derivation for a specific use in libraries using `remake` as set up by Guillaume Melquiond for `flocq`, `gappalib`, `interval`, and `coquelicot` (see the corresponding derivation for concrete examples of use of this option). For backward compatibility, the attribute `useMelquiondRemake.logpath` must be set to the logical root of the library (otherwise, one can pass `useMelquiondRemake = {}` to activate this without backward compatibility).
* `dropAttrs`, `keepAttrs`, `dropDerivationAttrs` are all optional and allow to tune which attribute is added or removed from the final call to `mkDerivation`.

@ -72,7 +72,7 @@ The `dotnetCorePackages.sdk` contains both a runtime and the full sdk of a given
To package Dotnet applications, you can use `buildDotnetModule`. This has similar arguments to `stdenv.mkDerivation`, with the following additions:
* `projectFile` has to be used for specifying the dotnet project file relative to the source root. These usually have `.sln` or `.csproj` file extensions. This can be an array of multiple projects as well.
* `nugetDeps` has to be used to specify the NuGet dependency file. Unfortunately, these cannot be deterministically fetched without a lockfile. A script to fetch these is available as `passthru.fetch-deps`. This file can also be generated manually using `nuget-to-nix` tool, which is available in nixpkgs.
* `nugetDeps` takes either a path to a `deps.nix` file, or a derivation. The `deps.nix` file can be generated using the script attached to `passthru.fetch-deps`. This file can also be generated manually using `nuget-to-nix` tool, which is available in nixpkgs. If the argument is a derivation, it will be used directly and assume it has the same output as `mkNugetDeps`.
* `packNupkg` is used to pack project as a `nupkg`, and installs it to `$out/share`. If set to `true`, the derivation can be used as a dependency for another dotnet project by adding it to `projectReferences`.
* `projectReferences` can be used to resolve `ProjectReference` project items. Referenced projects can be packed with `buildDotnetModule` by setting the `packNupkg = true` attribute and passing a list of derivations to `projectReferences`. Since we are sharing referenced projects as NuGets they must be added to csproj/fsproj files as `PackageReference` as well.
For example, your project has a local dependency:

@ -8,9 +8,9 @@
Several versions of the Python interpreter are available on Nix, as well as a
high amount of packages. The attribute `python3` refers to the default
interpreter, which is currently CPython 3.9. The attribute `python` refers to
interpreter, which is currently CPython 3.10. The attribute `python` refers to
CPython 2.7 for backwards-compatibility. It is also possible to refer to
specific versions, e.g. `python38` refers to CPython 3.8, and `pypy` refers to
specific versions, e.g. `python39` refers to CPython 3.9, and `pypy` refers to
the default PyPy interpreter.
Python is used a lot, and in different ways. This affects also how it is
@ -26,10 +26,10 @@ however, are in separate sets, with one set per interpreter version.
The interpreters have several common attributes. One of these attributes is
`pkgs`, which is a package set of Python libraries for this specific
interpreter. E.g., the `toolz` package corresponding to the default interpreter
is `python.pkgs.toolz`, and the CPython 3.8 version is `python38.pkgs.toolz`.
is `python.pkgs.toolz`, and the CPython 3.9 version is `python39.pkgs.toolz`.
The main package set contains aliases to these package sets, e.g.
`pythonPackages` refers to `python.pkgs` and `python38Packages` to
`python38.pkgs`.
`pythonPackages` refers to `python.pkgs` and `python39Packages` to
`python39.pkgs`.
#### Installing Python and packages {#installing-python-and-packages}
@ -54,7 +54,7 @@ with `python.buildEnv` or `python.withPackages` where the interpreter and other
executables are wrapped to be able to find each other and all of the modules.
In the following examples we will start by creating a simple, ad-hoc environment
with a nix-shell that has `numpy` and `toolz` in Python 3.8; then we will create
with a nix-shell that has `numpy` and `toolz` in Python 3.9; then we will create
a re-usable environment in a single-file Python script; then we will create a
full Python environment for development with this same environment.
@ -70,10 +70,10 @@ temporary shell session with a Python and a *precise* list of packages (plus
their runtime dependencies), with no other Python packages in the Python
interpreter's scope.
To create a Python 3.8 session with `numpy` and `toolz` available, run:
To create a Python 3.9 session with `numpy` and `toolz` available, run:
```sh
$ nix-shell -p 'python38.withPackages(ps: with ps; [ numpy toolz ])'
$ nix-shell -p 'python39.withPackages(ps: with ps; [ numpy toolz ])'
```
By default `nix-shell` will start a `bash` session with this interpreter in our
@ -81,8 +81,8 @@ By default `nix-shell` will start a `bash` session with this interpreter in our
```Python console
[nix-shell:~/src/nixpkgs]$ python3
Python 3.8.1 (default, Dec 18 2019, 19:06:26)
[GCC 9.2.0] on linux
Python 3.9.12 (main, Mar 23 2022, 21:36:19)
[GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy; import toolz
```
@ -102,13 +102,16 @@ will still get 1 wrapped Python interpreter. We can start the interpreter
directly like so:
```sh
$ nix-shell -p 'python38.withPackages(ps: with ps; [ numpy toolz requests ])' --run python3
these derivations will be built:
/nix/store/xbdsrqrsfa1yva5s7pzsra8k08gxlbz1-python3-3.8.1-env.drv
building '/nix/store/xbdsrqrsfa1yva5s7pzsra8k08gxlbz1-python3-3.8.1-env.drv'...
created 277 symlinks in user environment
Python 3.8.1 (default, Dec 18 2019, 19:06:26)
[GCC 9.2.0] on linux
$ nix-shell -p "python39.withPackages (ps: with ps; [ numpy toolz requests ])" --run python3
this derivation will be built:
/nix/store/mpn7k6bkjl41fm51342rafaqfsl10qs4-python3-3.9.12-env.drv
this path will be fetched (0.09 MiB download, 0.41 MiB unpacked):
/nix/store/5gaiacnzi096b6prc6aa1pwrhncmhc8b-python3.9-toolz-0.11.2
copying path '/nix/store/5gaiacnzi096b6prc6aa1pwrhncmhc8b-python3.9-toolz-0.11.2' from 'https://cache.nixos.org'...
building '/nix/store/mpn7k6bkjl41fm51342rafaqfsl10qs4-python3-3.9.12-env.drv'...
created 279 symlinks in user environment
Python 3.9.12 (main, Mar 23 2022, 21:36:19)
[GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>>
@ -147,7 +150,7 @@ Executing this script requires a `python3` that has `numpy`. Using what we learn
in the previous section, we could startup a shell and just run it like so:
```ShellSession
$ nix-shell -p 'python38.withPackages(ps: with ps; [ numpy ])' --run 'python3 foo.py'
$ nix-shell -p 'python39.withPackages(ps: with ps; [ numpy ])' --run 'python3 foo.py'
The dot product of [1 2] and [3 4] is: 11
```
@ -210,12 +213,12 @@ create a single script with Python dependencies, but in the course of normal
development we're usually working in an entire package repository.
As explained in the Nix manual, `nix-shell` can also load an expression from a
`.nix` file. Say we want to have Python 3.8, `numpy` and `toolz`, like before,
`.nix` file. Say we want to have Python 3.9, `numpy` and `toolz`, like before,
in an environment. We can add a `shell.nix` file describing our dependencies:
```nix
with import <nixpkgs> {};
(python38.withPackages (ps: [ps.numpy ps.toolz])).env
(python39.withPackages (ps: [ps.numpy ps.toolz])).env
```
And then at the command line, just typing `nix-shell` produces the same
@ -229,7 +232,7 @@ What's happening here?
imports the `<nixpkgs>` function, `{}` calls it and the `with` statement
brings all attributes of `nixpkgs` in the local scope. These attributes form
the main package set.
2. Then we create a Python 3.8 environment with the `withPackages` function, as before.
2. Then we create a Python 3.9 environment with the `withPackages` function, as before.
3. The `withPackages` function expects us to provide a function as an argument
that takes the set of all Python packages and returns a list of packages to
include in the environment. Here, we select the packages `numpy` and `toolz`
@ -240,7 +243,7 @@ To combine this with `mkShell` you can:
```nix
with import <nixpkgs> {};
let
pythonEnv = python38.withPackages (ps: [
pythonEnv = python39.withPackages (ps: [
ps.numpy
ps.toolz
]);
@ -378,8 +381,8 @@ information. The output of the function is a derivation.
An expression for `toolz` can be found in the Nixpkgs repository. As explained
in the introduction of this Python section, a derivation of `toolz` is available
for each interpreter version, e.g. `python38.pkgs.toolz` refers to the `toolz`
derivation corresponding to the CPython 3.8 interpreter.
for each interpreter version, e.g. `python39.pkgs.toolz` refers to the `toolz`
derivation corresponding to the CPython 3.9 interpreter.
The above example works when you're directly working on
`pkgs/top-level/python-packages.nix` in the Nixpkgs repository. Often though,
@ -392,11 +395,11 @@ and adds it along with a `numpy` package to a Python environment.
with import <nixpkgs> {};
( let
my_toolz = python38.pkgs.buildPythonPackage rec {
my_toolz = python39.pkgs.buildPythonPackage rec {
pname = "toolz";
version = "0.10.0";
src = python38.pkgs.fetchPypi {
src = python39.pkgs.fetchPypi {
inherit pname version;
sha256 = "08fdd5ef7c96480ad11c12d472de21acd32359996f69a5259299b540feba4560";
};
@ -414,7 +417,7 @@ with import <nixpkgs> {};
```
Executing `nix-shell` will result in an environment in which you can use
Python 3.8 and the `toolz` package. As you can see we had to explicitly mention
Python 3.9 and the `toolz` package. As you can see we had to explicitly mention
for which Python version we want to build a package.
So, what did we do here? Well, we took the Nix expression that we used earlier
@ -742,7 +745,7 @@ If we create a `shell.nix` file which calls `buildPythonPackage`, and if `src`
is a local source, and if the local source has a `setup.py`, then development
mode is activated.
In the following example we create a simple environment that has a Python 3.8
In the following example we create a simple environment that has a Python 3.9
version of our package in it, as well as its dependencies and other packages we
like to have in the environment, all specified with `propagatedBuildInputs`.
Indeed, we can just add any package we like to have in our environment to
@ -750,7 +753,7 @@ Indeed, we can just add any package we like to have in our environment to
```nix
with import <nixpkgs> {};
with python38Packages;
with python39Packages;
buildPythonPackage rec {
name = "mypackage";
@ -828,9 +831,9 @@ and in this case the `python38` interpreter is automatically used.
### Interpreters {#interpreters}
Versions 2.7, 3.7, 3.8 and 3.9 of the CPython interpreter are available as
respectively `python27`, `python37`, `python38` and `python39`. The
aliases `python2` and `python3` correspond to respectively `python27` and
Versions 2.7, 3.7, 3.8, 3.9 and 3.10 of the CPython interpreter are available
as respectively `python27`, `python37`, `python38`, `python39` and `python310`.
The aliases `python2` and `python3` correspond to respectively `python27` and
`python39`. The attribute `python` maps to `python2`. The PyPy interpreters
compatible with Python 2.7 and 3 are available as `pypy27` and `pypy3`, with
aliases `pypy2` mapping to `pypy27` and `pypy` mapping to `pypy2`. The Nix

@ -1,650 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<article xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Nixpkgs Release Notes</title>
<section xml:id="release-notes-0.14">
<title>Release 0.14 (June 4, 2012)</title>
<para>
In preparation for the switch from Subversion to Git, this release is mainly the prevent the Nixpkgs version number from going backwards. (This would happen because prerelease version numbers produced for the Git repository are lower than those for the Subversion repository.)
</para>
<para>
Since the last release, there have been thousands of changes and new packages by numerous contributors. For details, see the commit logs.
</para>
</section>
<section xml:id="release-notes-0.13">
<title>Release 0.13 (February 5, 2010)</title>
<para>
As always, there are many changes. Some of the most important updates are:
<itemizedlist>
<listitem>
<para>
Glibc 2.9.
</para>
</listitem>
<listitem>
<para>
GCC 4.3.3.
</para>
</listitem>
<listitem>
<para>
Linux 2.6.32.
</para>
</listitem>
<listitem>
<para>
X.org 7.5.
</para>
</listitem>
<listitem>
<para>
KDE 4.3.4.
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section xml:id="release-notes-0.12">
<title>Release 0.12 (April 24, 2009)</title>
<para>
There are way too many additions to Nixpkgs since the last release to list here: for example, the number of packages on Linux has increased from 1002 to 2159. However, some specific improvements are worth listing:
<itemizedlist>
<listitem>
<para>
Nixpkgs now has a manual. In particular, it describes the standard build environment in detail.
</para>
</listitem>
<listitem>
<para>
Major new packages:
<itemizedlist>
<listitem>
<para>
KDE 4.
</para>
</listitem>
<listitem>
<para>
TeXLive.
</para>
</listitem>
<listitem>
<para>
VirtualBox.
</para>
</listitem>
</itemizedlist>
… and many others.
</para>
</listitem>
<listitem>
<para>
Important updates:
<itemizedlist>
<listitem>
<para>
Glibc 2.7.
</para>
</listitem>
<listitem>
<para>
GCC 4.2.4.
</para>
</listitem>
<listitem>
<para>
Linux 2.6.25 — 2.6.28.
</para>
</listitem>
<listitem>
<para>
Firefox 3.
</para>
</listitem>
<listitem>
<para>
X.org 7.3.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
Support for building derivations in a virtual machine, including RPM and Debian builds in automatically generated VM images. See <filename>pkgs/build-support/vm/default.nix</filename> for details.
</para>
</listitem>
<listitem>
<para>
Improved support for building Haskell packages.
</para>
</listitem>
</itemizedlist>
</para>
<para>
The following people contributed to this release: Andres Löh, Arie Middelkoop, Armijn Hemel, Eelco Dolstra, Lluís Batlle, Ludovic Courtès, Marc Weber, Mart Kolthof, Martin Bravenboer, Michael Raskin, Nicolas Pierron, Peter Simons, Pjotr Prins, Rob Vermaas, Sander van der Burg, Tobias Hammerschmidt, Valentin David, Wouter den Breejen and Yury G. Kudryashov. In addition, several people contributed patches on the <literal>nix-dev</literal> mailing list.
</para>
</section>
<section xml:id="release-notes-0.11">
<title>Release 0.11 (September 11, 2007)</title>
<para>
This release has the following improvements:
<itemizedlist>
<listitem>
<para>
The standard build environment (<literal>stdenv</literal>) is now pure on the <literal>x86_64-linux</literal> and <literal>powerpc-linux</literal> platforms, just as on <literal>i686-linux</literal>. (Purity means that building and using the standard environment has no dependencies outside of the Nix store. For instance, it doesn’t require an external C compiler such as <filename>/usr/bin/gcc</filename>.) Also, the statically linked binaries used in the bootstrap process are now automatically reproducible, making it easy to update the bootstrap tools and to add support for other Linux platforms. See <filename>pkgs/stdenv/linux/make-bootstrap-tools.nix</filename> for details.
</para>
</listitem>
<listitem>
<para>
Hook variables in the generic builder are now executed using the <function>eval</function> shell command. This has a major advantage: you can write hooks directly in Nix expressions. For instance, rather than writing a builder like this:
<programlisting>
source $stdenv/setup
postInstall=postInstall
postInstall() {
ln -sf gzip $out/bin/gunzip
ln -sf gzip $out/bin/zcat
}
genericBuild</programlisting>
(the <literal>gzip</literal> builder), you can just add this attribute to the derivation:
<programlisting>
postInstall = "ln -sf gzip $out/bin/gunzip; ln -sf gzip $out/bin/zcat";</programlisting>
and so a separate build script becomes unnecessary. This should allow us to get rid of most builders in Nixpkgs.
</para>
</listitem>
<listitem>
<para>
It is now possible to have the generic builder pass arguments to <command>configure</command> and <command>make</command> that contain whitespace. Previously, for example, you could say in a builder,
<programlisting>
configureFlags="CFLAGS=-O0"</programlisting>
but not
<programlisting>
configureFlags="CFLAGS=-O0 -g"</programlisting>
since the <literal>-g</literal> would be interpreted as a separate argument to <command>configure</command>. Now you can say
<programlisting>
configureFlagsArray=("CFLAGS=-O0 -g")</programlisting>
or similarly
<programlisting>
configureFlagsArray=("CFLAGS=-O0 -g" "LDFLAGS=-L/foo -L/bar")</programlisting>
which does the right thing. Idem for <literal>makeFlags</literal>, <literal>installFlags</literal>, <literal>checkFlags</literal> and <literal>distFlags</literal>.
</para>
<para>
Unfortunately you can't pass arrays to Bash through the environment, so you can't put the array above in a Nix expression, e.g.,
<programlisting>
configureFlagsArray = ["CFLAGS=-O0 -g"];</programlisting>
since it would just be flattened to a since string. However, you <emphasis>can</emphasis> use the inline hooks described above:
<programlisting>
preConfigure = "configureFlagsArray=(\"CFLAGS=-O0 -g\")";</programlisting>
</para>
</listitem>
<listitem>
<para>
The function <function>fetchurl</function> now has support for two different kinds of mirroring of files. First, it has support for <emphasis>content-addressable mirrors</emphasis>. For example, given the <function>fetchurl</function> call
<programlisting>
fetchurl {
url = "http://releases.mozilla.org/<replaceable>...</replaceable>/firefox-2.0.0.6-source.tar.bz2";
sha1 = "eb72f55e4a8bf08e8c6ef227c0ade3d068ba1082";
}</programlisting>
<function>fetchurl</function> will first try to download this file from <link
xlink:href="http://tarballs.nixos.org/sha1/eb72f55e4a8bf08e8c6ef227c0ade3d068ba1082"/>. If that file doesn’t exist, it will try the original URL. In general, the “content-addressed” location is <replaceable>mirror</replaceable><literal>/</literal><replaceable>hash-type</replaceable><literal>/</literal><replaceable>hash</replaceable>. There is currently only one content-addressable mirror (<link
xlink:href="http://tarballs.nixos.org"/>), but more can be specified in the <varname>hashedMirrors</varname> attribute in <filename>pkgs/build-support/fetchurl/mirrors.nix</filename>, or by setting the <envar>NIX_HASHED_MIRRORS</envar> environment variable to a whitespace-separated list of URLs.
</para>
<para>
Second, <function>fetchurl</function> has support for widely-mirrored distribution sites such as SourceForge or the Linux kernel archives. Given a URL of the form <literal>mirror://<replaceable>site</replaceable>/<replaceable>path</replaceable></literal>, it will try to download <replaceable>path</replaceable> from a configurable list of mirrors for <replaceable>site</replaceable>. (This idea was borrowed from Gentoo Linux.) Example:
<programlisting>
fetchurl {
url = mirror://gnu/gcc/gcc-4.2.0/gcc-core-4.2.0.tar.bz2;
sha256 = "0ykhzxhr8857dr97z0j9wyybfz1kjr71xk457cfapfw5fjas4ny1";
}</programlisting>
Currently <replaceable>site</replaceable> can be <literal>sourceforge</literal>, <literal>gnu</literal> and <literal>kernel</literal>. The list of mirrors is defined in <filename>pkgs/build-support/fetchurl/mirrors.nix</filename>. You can override the list of mirrors for a particular site by setting the environment variable <envar>NIX_MIRRORS_<replaceable>site</replaceable></envar>, e.g.
<programlisting>
export NIX_MIRRORS_sourceforge=http://osdn.dl.sourceforge.net/sourceforge/</programlisting>
</para>
</listitem>
<listitem>
<para>
Important updates:
<itemizedlist>
<listitem>
<para>
Glibc 2.5.
</para>
</listitem>
<listitem>
<para>
GCC 4.1.2.
</para>
</listitem>
<listitem>
<para>
Gnome 2.16.3.
</para>
</listitem>
<listitem>
<para>
X11R7.2.
</para>
</listitem>
<listitem>
<para>
Linux 2.6.21.7 and 2.6.22.6.
</para>
</listitem>
<listitem>
<para>
Emacs 22.1.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
Major new packages:
<itemizedlist>
<listitem>
<para>
KDE 3.5.6 Base.
</para>
</listitem>
<listitem>
<para>
Wine 0.9.43.
</para>
</listitem>
<listitem>
<para>
OpenOffice 2.2.1.
</para>
</listitem>
<listitem>
<para>
Many Linux system packages to support NixOS.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
<para>
The following people contributed to this release: Andres Löh, Arie Middelkoop, Armijn Hemel, Eelco Dolstra, Marc Weber, Mart Kolthof, Martin Bravenboer, Michael Raskin, Wouter den Breejen and Yury G. Kudryashov.
</para>
</section>
<section xml:id="release-notes-0.10">
<title>Release 0.10 (October 12, 2006)</title>
<note>
<para>
This release of Nixpkgs requires <link
xlink:href='https://nixos.org/releases/nix/nix-0.10/'>Nix 0.10</link> or higher.
</para>
</note>
<para>
This release has the following improvements:
</para>
<itemizedlist>
<listitem>
<para>
<filename>pkgs/system/all-packages-generic.nix</filename> is gone, we now just have <filename>pkgs/top-level/all-packages.nix</filename> that contains all available packages. This should cause much less confusion with users. <filename>all-packages.nix</filename> is a function that by default returns packages for the current platform, but you can override this by specifying a different <varname>system</varname> argument.
</para>
</listitem>
<listitem>
<para>
Certain packages in Nixpkgs are now user-configurable through a configuration file, i.e., without having to edit the Nix expressions in Nixpkgs. For instance, the Firefox provided in the Nixpkgs channel is built without the RealPlayer plugin (for legal reasons). Previously, you could easily enable RealPlayer support by editing the call to the Firefox function in <filename>all-packages.nix</filename>, but such changes are not respected when Firefox is subsequently updated through the Nixpkgs channel.
</para>
<para>
The Nixpkgs configuration file (found in <filename>~/.nixpkgs/config.nix</filename> or through the <envar>NIXPKGS_CONFIG</envar> environment variable) is an attribute set that contains configuration options that <filename>all-packages.nix</filename> reads and uses for certain packages. For instance, the following configuration file:
<programlisting>
{
firefox = {
enableRealPlayer = true;
};
}</programlisting>
persistently enables RealPlayer support in the Firefox build.
</para>
<para>
(Actually, <literal>firefox.enableRealPlayer</literal> is the <emphasis>only</emphasis> configuration option currently available, but more are sure to be added.)
</para>
</listitem>
<listitem>
<para>
Support for new platforms:
<itemizedlist>
<listitem>
<para>
<literal>i686-cygwin</literal>, i.e., Windows (using <link xlink:href="http://www.cygwin.com/">Cygwin</link>). The standard environment on <literal>i686-cygwin</literal> by default builds binaries for the Cygwin environment (i.e., it uses Cygwin tools and produces executables that use the Cygwin library). However, there is also a standard environment that produces binaries that use <link
xlink:href="http://www.mingw.org/">MinGW</link>. You can use it by calling <filename>all-package.nix</filename> with the <varname>stdenvType</varname> argument set to <literal>"i686-mingw"</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>i686-darwin</literal>, i.e., Mac OS X on Intel CPUs.
</para>
</listitem>
<listitem>
<para>
<literal>powerpc-linux</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>x86_64-linux</literal>, i.e., Linux on 64-bit AMD/Intel CPUs. Unlike <literal>i686-linux</literal>, this platform doesn’t have a pure <literal>stdenv</literal> yet.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
The default compiler is now GCC 4.1.1.
</para>
</listitem>
<listitem>
<para>
X11 updated to X.org’s X11R7.1.
</para>
</listitem>
<listitem>
<para>
Notable new packages:
<itemizedlist>
<listitem>
<para>
Opera.
</para>
</listitem>
<listitem>
<para>
Microsoft Visual C++ 2005 Express Edition and the Windows SDK.
</para>
</listitem>
</itemizedlist>
In total there are now around 809 packages in Nixpkgs.
</para>
</listitem>
<listitem>
<para>
It is now <emphasis>much</emphasis> easier to override the default C compiler and other tools in <literal>stdenv</literal> for specific packages. <filename>all-packages.nix</filename> provides two utility functions for this purpose: <function>overrideGCC</function> and <function>overrideInStdenv</function>. Both take a <literal>stdenv</literal> and return an augmented <literal>stdenv</literal>; the formed changes the C compiler, and the latter adds additional packages to the front of <literal>stdenv</literal>’s initial <envar>PATH</envar>, allowing tools to be overridden.
</para>
<para>
For instance, the package <varname>strategoxt</varname> doesn’t build with the GNU Make in <literal>stdenv</literal> (version 3.81), so we call it with an augmented <literal>stdenv</literal> that uses GNU Make 3.80:
<programlisting>
strategoxt = (import ../development/compilers/strategoxt) {
inherit fetchurl pkgconfig sdf aterm;
stdenv = overrideInStdenv stdenv [gnumake380];
};
gnumake380 = <replaceable>...</replaceable>;</programlisting>
Likewise, there are many packages that don’t compile with the default GCC (4.1.1), but that’s easily fixed:
<programlisting>
exult = import ../games/exult {
inherit fetchurl SDL SDL_mixer zlib libpng unzip;
stdenv = overrideGCC stdenv gcc34;
};</programlisting>
</para>
</listitem>
<listitem>
<para>
It has also become much easier to experiment with changes to the <literal>stdenv</literal> setup script (which notably contains the generic builder). Since edits to <filename>pkgs/stdenv/generic/setup.sh</filename> trigger a rebuild of <emphasis>everything</emphasis>, this was formerly quite painful. But now <literal>stdenv</literal> contains a function to “regenerate” <literal>stdenv</literal> with a different setup script, allowing the use of a different setup script for specific packages:
<programlisting>
pkg = import <replaceable>...</replaceable> {
stdenv = stdenv.regenerate ./my-setup.sh;
<replaceable>...</replaceable>
}</programlisting>
</para>
</listitem>
<listitem>
<para>
Packages can now have a human-readable <emphasis>description</emphasis> field. Package descriptions are shown by <literal>nix-env -qa --description</literal>. In addition, they’re shown on the Nixpkgs release page. A description can be added to a package as follows:
<programlisting>
stdenv.mkDerivation {
name = "exult-1.2";
<replaceable>...</replaceable>
meta = {
description = "A reimplementation of the Ultima VII game engine";
};
}</programlisting>
The <varname>meta</varname> attribute is not passed to the builder, so changes to the description do not trigger a rebuild. Additional <varname>meta</varname> attributes may be defined in the future (such as the URL of the package’s homepage, the license, etc.).
</para>
</listitem>
</itemizedlist>
<para>
The following people contributed to this release: Andres Löh, Armijn Hemel, Christof Douma, Eelco Dolstra, Eelco Visser, Mart Kolthof, Martin Bravenboer, Merijn de Jonge, Rob Vermaas and Roy van den Broek.
</para>
</section>
<section xml:id="release-notes-0.9">
<title>Release 0.9 (January 31, 2006)</title>
<para>
There have been zillions of changes since the last release of Nixpkgs. Many packages have been added or updated. The following are some of the more notable changes:
</para>
<itemizedlist>
<listitem>
<para>
Distribution files have been moved to <link
xlink:href="https://nixos.org/" />.
</para>
</listitem>
<listitem>
<para>
The C library on Linux, Glibc, has been updated to version 2.3.6.
</para>
</listitem>
<listitem>
<para>
The default compiler is now GCC 3.4.5. GCC 4.0.2 is also available.
</para>
</listitem>
<listitem>
<para>
The old, unofficial Xlibs has been replaced by the official modularised X11 distribution from X.org, i.e., X11R7.0. X11R7.0 consists of 287 (!) packages, all of which are in Nixpkgs though not all have been tested. It is now possible to build a working X server (previously we only had X client libraries). We use a fully Nixified X server on NixOS.
</para>
</listitem>
<listitem>
<para>
The Sun JDK 5 has been purified, i.e., it doesn’t require any non-Nix components such as <filename>/lib/ld-linux.so.2</filename>. This means that Java applications such as Eclipse and Azureus can run on NixOS.
</para>
</listitem>
<listitem>
<para>
Hardware-accelerated OpenGL support, used by games like Quake 3 (which is now built from source).
</para>
</listitem>
<listitem>
<para>
Improved support for FreeBSD on x86.
</para>
</listitem>
<listitem>
<para>
Improved Haskell support; e.g., the GHC build is now pure.
</para>
</listitem>
<listitem>
<para>
Some support for cross-compilation: cross-compiling builds of GCC and Binutils, and cross-compiled builds of the C library uClibc.
</para>
</listitem>
<listitem>
<para>
Notable new packages:
<itemizedlist>
<listitem>
<para>
teTeX, including support for building LaTeX documents using Nix (with automatic dependency determination).
</para>
</listitem>
<listitem>
<para>
Ruby.
</para>
</listitem>
<listitem>
<para>
System-level packages to support NixOS, e.g. Grub, GNU <literal>parted</literal> and so on.
</para>
</listitem>
<listitem>
<para>
<literal>ecj</literal>, the Eclipse Compiler for Java, so we finally have a freely distributable compiler that supports Java 5.0.
</para>
</listitem>
<listitem>
<para>
<literal>php</literal>.
</para>
</listitem>
<listitem>
<para>
The GIMP.
</para>
</listitem>
<listitem>
<para>
Inkscape.
</para>
</listitem>
<listitem>
<para>
GAIM.
</para>
</listitem>
<listitem>
<para>
<literal>kdelibs</literal>. This allows us to add KDE-based packages (such as <literal>kcachegrind</literal>).
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
<para>
The following people contributed to this release: Andres Löh, Armijn Hemel, Bogdan Dumitriu, Christof Douma, Eelco Dolstra, Eelco Visser, Mart Kolthof, Martin Bravenboer, Rob Vermaas and Roy van den Broek.
</para>
</section>
<section xml:id="release-notes-0.8">
<title>Release 0.8 (April 11, 2005)</title>
<para>
This release is mostly to remain synchronised with the changed hashing scheme in Nix 0.8.
</para>
<para>
Notable updates:
<itemizedlist>
<listitem>
<para>
Adobe Reader 7.0
</para>
</listitem>
<listitem>
<para>
Various security updates (zlib 1.2.2, etc.)
</para>
</listitem>
</itemizedlist>
</para>
</section>
<section xml:id="release-notes-0.7">
<title>Release 0.7 (March 14, 2005)</title>
<itemizedlist>
<listitem>
<para>
The bootstrap process for the standard build environment on Linux (stdenv-linux) has been improved. It is no longer dependent in its initial bootstrap stages on the system Glibc, GCC, and other tools. Rather, Nixpkgs contains a statically linked bash and curl, and uses that to download other statically linked tools. These are then used to build a Glibc and dynamically linked versions of all other tools.
</para>
<para>
This change also makes the bootstrap process faster. For instance, GCC is built only once instead of three times.
</para>
<para>
(Contributed by Armijn Hemel.)
</para>
</listitem>
<listitem>
<para>
Tarballs used by Nixpkgs are now obtained from the same server that hosts Nixpkgs (<link
xlink:href="http://catamaran.labs.cs.uu.nl/" />). This reduces the risk of packages being unbuildable due to moved or deleted files on various servers.
</para>
</listitem>
<listitem>
<para>
There now is a generic mechanism for building Perl modules. See the various Perl modules defined in pkgs/system/all-packages-generic.nix.
</para>
</listitem>
<listitem>
<para>
Notable new packages:
<itemizedlist>
<listitem>
<para>
Qt 3
</para>
</listitem>
<listitem>
<para>
MySQL
</para>
</listitem>
<listitem>
<para>
MythTV
</para>
</listitem>
<listitem>
<para>
Mono
</para>
</listitem>
<listitem>
<para>
MonoDevelop (alpha)
</para>
</listitem>
<listitem>
<para>
Xine
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
<listitem>
<para>
Notable updates:
<itemizedlist>
<listitem>
<para>
GCC 3.4.3
</para>
</listitem>
<listitem>
<para>
Glibc 2.3.4
</para>
</listitem>
<listitem>
<para>
GTK 2.6
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</section>
</article>

@ -153,6 +153,24 @@ Add the following to your `mkDerivation` invocation.
doCheck = stdenv.hostPlatform == stdenv.buildPlatform;
```
#### Package using Meson needs to run binaries for the host platform during build. {#cross-meson-runs-host-code}
Add `mesonEmulatorHook` cross conditionally to `nativeBuildInputs`.
e.g.
```
nativeBuildInputs = [
meson
] ++ lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
mesonEmulatorHook
];
```
Example of an error which this fixes.
`[Errno 8] Exec format error: './gdk3-scan'`
## Cross-building packages {#sec-cross-usage}
Nixpkgs can be instantiated with `localSystem` alone, in which case there is no cross-compiling and everything is built by and for that system, or also with `crossSystem`, in which case packages run on the latter, but all building happens on the former. Both parameters take the same schema as the 3 (build, host, and target) platforms defined in the previous section. As mentioned above, `lib.systems.examples` has some platforms which are used as arguments for these parameters in practice. You can use them programmatically, or on the command line:

@ -131,7 +131,9 @@ let
getValues getFiles
optionAttrSetToDocList optionAttrSetToDocList'
scrubOptionValue literalExpression literalExample literalDocBook
showOption showFiles unknownModule mkOption mkPackageOption;
showOption showOptionWithDefLocs showFiles
unknownModule mkOption mkPackageOption
mdDoc literalMD;
inherit (self.types) isType setType defaultTypeMerge defaultFunctor
isOptionType mkOptionType;
inherit (self.asserts)

@ -462,6 +462,7 @@ rec {
config = addFreeformType (addMeta (m.config or {}));
}
else
lib.throwIfNot (isAttrs m) "module ${file} (${key}) does not look like a module."
{ _file = toString m._file or file;
key = toString m.key or key;
disabledModules = m.disabledModules or [];

@ -7,6 +7,7 @@ let
collect
concatLists
concatMap
concatMapStringsSep
elemAt
filter
foldl'
@ -241,6 +242,8 @@ rec {
in if ss != {} then optionAttrSetToDocList' opt.loc ss else [];
subOptionsVisible = docOption.visible && opt.visible or null != "shallow";
in
# To find infinite recursion in NixOS option docs:
# builtins.trace opt.loc
[ docOption ] ++ optionals subOptionsVisible subOptions) (collect isOption options);
@ -280,6 +283,21 @@ rec {
if ! isString text then throw "literalDocBook expects a string."
else { _type = "literalDocBook"; inherit text; };
/* Transition marker for documentation that's already migrated to markdown
syntax.
*/
mdDoc = text:
if ! isString text then throw "mdDoc expects a string."
else { _type = "mdDoc"; inherit text; };
/* For use in the `defaultText` and `example` option attributes. Causes the
given MD text to be inserted verbatim in the documentation, for when
a `literalExpression` would be too hard to read.
*/
literalMD = text:
if ! isString text then throw "literalMD expects a string."
else { _type = "literalMD"; inherit text; };
# Helper functions.
/* Convert an option, described as a list of the option parts in to a
@ -325,6 +343,11 @@ rec {
in "\n- In `${def.file}'${result}"
) defs;
showOptionWithDefLocs = opt: ''
${showOption opt.loc}, with values defined in:
${concatMapStringsSep "\n" (defFile: " - ${defFile}") opt.files}
'';
unknownModule = "<unknown-file>";
}

@ -0,0 +1,31 @@
{ lib, ... }:
let
inherit (lib) types;
in {
options = {
name = lib.mkOption {
type = types.str;
};
email = lib.mkOption {
type = types.str;
};
matrix = lib.mkOption {
type = types.nullOr types.str;
default = null;
};
github = lib.mkOption {
type = types.nullOr types.str;
default = null;
};
githubId = lib.mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
};
keys = lib.mkOption {
type = types.listOf (types.submodule {
options.fingerprint = lib.mkOption { type = types.str; };
});
default = [];
};
};
}

@ -1,50 +1,19 @@
# to run these tests (and the others)
# nix-build nixpkgs/lib/tests/release.nix
{ # The pkgs used for dependencies for the testing itself
pkgs
, lib
pkgs ? import ../.. {}
, lib ? pkgs.lib
}:
let
inherit (lib) types;
maintainerModule = { config, ... }: {
options = {
name = lib.mkOption {
type = types.str;
};
email = lib.mkOption {
type = types.str;
};
matrix = lib.mkOption {
type = types.nullOr types.str;
default = null;
};
github = lib.mkOption {
type = types.nullOr types.str;
default = null;
};
githubId = lib.mkOption {
type = types.nullOr types.ints.unsigned;
default = null;
};
keys = lib.mkOption {
type = types.listOf (types.submodule {
options.longkeyid = lib.mkOption { type = types.str; };
options.fingerprint = lib.mkOption { type = types.str; };
});
default = [];
};
};
};
checkMaintainer = handle: uncheckedAttrs:
let
prefix = [ "lib" "maintainers" handle ];
checkedAttrs = (lib.modules.evalModules {
inherit prefix;
modules = [
maintainerModule
./maintainer-module.nix
{
_file = toString ../../maintainers/maintainer-list.nix;
config = uncheckedAttrs;

@ -194,6 +194,13 @@ checkConfigOutput '^"submodule"$' options.submodule.type.description ./declare-s
## Paths should be allowed as values and work as expected
checkConfigOutput '^true$' config.submodule.enable ./declare-submoduleWith-path.nix
## deferredModule
# default module is merged into nodes.foo
checkConfigOutput '"beta"' config.nodes.foo.settingsDict.c ./deferred-module.nix
# errors from the default module are reported with accurate location
checkConfigError 'In `the-file-that-contains-the-bad-config.nix, via option default'\'': "bogus"' config.nodes.foo.bottom ./deferred-module.nix
checkConfigError '.*lib/tests/modules/deferred-module-error.nix, via option deferred [(]:anon-1:anon-1:anon-1[)] does not look like a module.' config.result ./deferred-module-error.nix
# Check the file location information is propagated into submodules
checkConfigOutput the-file.nix config.submodule.internalFiles.0 ./submoduleFiles.nix

@ -0,0 +1,20 @@
{ config, lib, ... }:
let
inherit (lib) types mkOption setDefaultModuleLocation evalModules;
inherit (types) deferredModule lazyAttrsOf submodule str raw enum;
in
{
options = {
deferred = mkOption {
type = deferredModule;
};
result = mkOption {
default = (evalModules { modules = [ config.deferred ]; }).config.result;
};
};
config = {
deferred = { ... }:
# this should be an attrset, so this fails
true;
};
}

@ -0,0 +1,58 @@
{ lib, ... }:
let
inherit (lib) types mkOption setDefaultModuleLocation;
inherit (types) deferredModule lazyAttrsOf submodule str raw enum;
in
{
imports = [
# generic module, declaring submodules:
# - nodes.<name>
# - default
# where all nodes include the default
({ config, ... }: {
_file = "generic.nix";
options.nodes = mkOption {
type = lazyAttrsOf (submodule { imports = [ config.default ]; });
default = {};
};
options.default = mkOption {
type = deferredModule;
default = { };
description = ''
Module that is included in all nodes.
'';
};
})
{
_file = "default-1.nix";
default = { config, ... }: {
options.settingsDict = lib.mkOption { type = lazyAttrsOf str; default = {}; };
options.bottom = lib.mkOption { type = enum []; };
};
}
{
_file = "default-a-is-b.nix";
default = ./define-settingsDict-a-is-b.nix;
}
{
_file = "nodes-foo.nix";
nodes.foo.settingsDict.b = "beta";
}
{
_file = "the-file-that-contains-the-bad-config.nix";
default.bottom = "bogus";
}
{
_file = "nodes-foo-c-is-a.nix";
nodes.foo = { config, ... }: {
settingsDict.c = config.settingsDict.a;
};
}
];
}

@ -0,0 +1,3 @@
{ config, ... }: {
settingsDict.a = config.settingsDict.b;
}

@ -11,6 +11,10 @@ pkgs.runCommand "nixpkgs-lib-tests" {
inherit pkgs;
lib = import ../.;
})
(import ./teams.nix {
inherit pkgs;
lib = import ../.;
})
];
} ''
datadir="${pkgs.nix}/share"

@ -0,0 +1,50 @@
# to run these tests:
# nix-build nixpkgs/lib/tests/teams.nix
# If it builds, all tests passed
{ pkgs ? import ../.. {}, lib ? pkgs.lib }:
let
inherit (lib) types;
teamModule = { config, ... }: {
options = {
shortName = lib.mkOption {
type = types.str;
};
scope = lib.mkOption {
type = types.str;
};
enableFeatureFreezePing = lib.mkOption {
type = types.bool;
default = false;
};
members = lib.mkOption {
type = types.listOf (types.submodule
(import ./maintainer-module.nix { inherit lib; })
);
default = [];
};
githubTeams = lib.mkOption {
type = types.listOf types.str;
default = [];
};
};
};
checkTeam = team: uncheckedAttrs:
let
prefix = [ "lib" "maintainer-team" team ];
checkedAttrs = (lib.modules.evalModules {
inherit prefix;
modules = [
teamModule
{
_file = toString ../../maintainers/team-list.nix;
config = uncheckedAttrs;
}
];
}).config;
in checkedAttrs;
checkedTeams = lib.mapAttrs checkTeam lib.teams;
in pkgs.writeTextDir "maintainer-teams.json" (builtins.toJSON checkedTeams)

@ -539,6 +539,36 @@ rec {
modules = toList modules;
};
# A module to be imported in some other part of the configuration.
deferredModule = deferredModuleWith { };
# A module to be imported in some other part of the configuration.
# `staticModules`' options will be added to the documentation, unlike
# options declared via `config`.
deferredModuleWith = attrs@{ staticModules ? [] }: mkOptionType {
name = "deferredModule";
description = "module";
check = x: isAttrs x || isFunction x || path.check x;
merge = loc: defs: {
imports = staticModules ++ map (def: lib.setDefaultModuleLocation "${def.file}, via option ${showOption loc}" def.value) defs;
};
inherit (submoduleWith { modules = staticModules; })
getSubOptions
getSubModules;
substSubModules = m: deferredModuleWith (attrs // {
staticModules = m;
});
functor = defaultFunctor "deferredModuleWith" // {
type = types.deferredModuleWith;
payload = {
inherit staticModules;
};
binOp = lhs: rhs: {
staticModules = lhs.staticModules ++ rhs.staticModules;
};
};
};
# The type of a type!
optionType = mkOptionType {
name = "optionType";

@ -86,6 +86,7 @@ plenary.nvim,https://github.com/nvim-lua/plenary.nvim.git,,,,lua5_1,
rapidjson,https://github.com/xpol/lua-rapidjson.git,,,,,
readline,,,,,,
say,https://github.com/Olivine-Labs/say.git,,,,,
sqlite,,,,,,
std._debug,https://github.com/lua-stdlib/_debug.git,,,,,
std.normalize,https://github.com/lua-stdlib/normalize.git,,,,,
stdlib,,,,41.2.2,,vyp

Can't render this file because it has a wrong number of fields in line 72.

@ -19,7 +19,10 @@
More fields may be added in the future.
Please keep the list alphabetically sorted.
When editing this file:
* keep the list alphabetically sorted
* test the validity of the format with:
nix-build lib/tests/teams.nix
*/
{ lib }:
@ -91,6 +94,16 @@ with lib.maintainers; {
enableFeatureFreezePing = true;
};
c3d2 = {
members = [
astro
SuperSandro2000
];
scope = "Maintain packages used in the C3D2 hackspace";
shortName = "c3d2";
enableFeatureFreezePing = true;
};
cinnamon = {
members = [
mkg20001
@ -139,6 +152,7 @@ with lib.maintainers; {
tomberek
];
scope = "Maintain the Cosmopolitan LibC and related programs.";
shortName = "Cosmopolitan";
};
deshaw = {

@ -24,11 +24,16 @@ Some Xfce programs are not installed automatically. To install them
manually (system wide), put them into your
[](#opt-environment.systemPackages) from `pkgs.xfce`.
## Thunar Plugins {#sec-xfce-thunar-plugins .unnumbered}
## Thunar {#sec-xfce-thunar-plugins .unnumbered}
Thunar (the Xfce file manager) is automatically enabled when Xfce is
enabled. To enable Thunar without enabling Xfce, use the configuration
option [](#opt-programs.thunar.enable) instead of simply adding
`pkgs.xfce.thunar` to [](#opt-environment.systemPackages).
If you\'d like to add extra plugins to Thunar, add them to
[](#opt-services.xserver.desktopManager.xfce.thunarPlugins).
You shouldn\'t just add them to [](#opt-environment.systemPackages).
[](#opt-programs.thunar.plugins). You shouldn\'t just add them to
[](#opt-environment.systemPackages).
## Troubleshooting {#sec-xfce-troubleshooting .unnumbered}

@ -133,12 +133,12 @@ let
# ^ redirect assumes xmllint doesn’t print to stdout
}
lintrng manual-combined.xml
lintrng man-pages-combined.xml
mkdir $out
cp manual-combined.xml $out/
cp man-pages-combined.xml $out/
lintrng $out/manual-combined.xml
lintrng $out/man-pages-combined.xml
'';
olinkDB = runCommand "manual-olinkdb"

@ -54,7 +54,7 @@ possiblility into account that they have to create them first.
## NixOS snippets {#sec-activation-script-nixos-snippets}
There are some snippets NixOS enables by default because disabling them would
most likely break you system. This section lists a few of them and what they
most likely break your system. This section lists a few of them and what they
do:
- `binsh` creates `/bin/sh` which points to the runtime shell

@ -56,7 +56,14 @@ The function `mkOption` accepts the following arguments.
`description`
: A textual description of the option, in DocBook format, that will be
included in the NixOS manual.
included in the NixOS manual. During the migration process from DocBook
to CommonMark the description may also be written in CommonMark, but has
to be wrapped in `lib.mdDoc` to differentiate it from DocBook. See
the nixpkgs manual for [the list of CommonMark extensions](
https://nixos.org/nixpkgs/manual/#sec-contributing-markup)
supported by NixOS documentation.
New documentation should preferably be written as CommonMark.
## Utility functions for common option patterns {#sec-option-declarations-util}

@ -220,6 +220,25 @@ Value types are types that take a value parameter.
requires using a function:
`the-submodule = { ... }: { options = { ... }; }`.
`types.deferredModule`
: Whereas `submodule` represents an option tree, `deferredModule` represents
a module value, such as a module file or a configuration.
It can be set multiple times.
Module authors can use its value in `imports`, in `submoduleWith`'s `modules`
or in `evalModules`' `modules` parameter, among other places.
Note that `imports` must be evaluated before the module fixpoint. Because
of this, deferred modules can only be imported into "other" fixpoints, such
as submodules.
One use case for this type is the type of a "default" module that allow the
user to affect all submodules in an `attrsOf submodule` at once. This is
more convenient and discoverable than expecting the module user to
type-merge with the `attrsOf submodule` option.
## Composed Types {#sec-option-types-composed}
Composed types are types that take a type as parameter. `listOf

@ -27,13 +27,19 @@ services.picom = {
<literal>pkgs.xfce</literal>.
</para>
<section xml:id="sec-xfce-thunar-plugins">
<title>Thunar Plugins</title>
<title>Thunar</title>
<para>
If you'd like to add extra plugins to Thunar, add them to
<xref linkend="opt-services.xserver.desktopManager.xfce.thunarPlugins" />.
You shouldn't just add them to
Thunar (the Xfce file manager) is automatically enabled when Xfce
is enabled. To enable Thunar without enabling Xfce, use the
configuration option <xref linkend="opt-programs.thunar.enable" />
instead of simply adding <literal>pkgs.xfce.thunar</literal> to
<xref linkend="opt-environment.systemPackages" />.
</para>
<para>
If you'd like to add extra plugins to Thunar, add them to
<xref linkend="opt-programs.thunar.plugins" />. You shouldn't just
add them to <xref linkend="opt-environment.systemPackages" />.
</para>
</section>
<section xml:id="sec-xfce-troubleshooting">
<title>Troubleshooting</title>

@ -73,7 +73,7 @@ system.activationScripts.my-activation-script = {
<title>NixOS snippets</title>
<para>
There are some snippets NixOS enables by default because disabling
them would most likely break you system. This section lists a few
them would most likely break your system. This section lists a few
of them and what they do:
</para>
<itemizedlist spacing="compact">

@ -94,7 +94,17 @@ options = {
<listitem>
<para>
A textual description of the option, in DocBook format, that
will be included in the NixOS manual.
will be included in the NixOS manual. During the migration
process from DocBook to CommonMark the description may also be
written in CommonMark, but has to be wrapped in
<literal>lib.mdDoc</literal> to differentiate it from DocBook.
See the nixpkgs manual for
<link xlink:href="https://nixos.org/nixpkgs/manual/#sec-contributing-markup">the
list of CommonMark extensions</link> supported by NixOS
documentation.
</para>
<para>
New documentation should preferably be written as CommonMark.
</para>
</listitem>
</varlistentry>

@ -427,6 +427,43 @@
</itemizedlist>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>types.deferredModule</literal>
</term>
<listitem>
<para>
Whereas <literal>submodule</literal> represents an option
tree, <literal>deferredModule</literal> represents a module
value, such as a module file or a configuration.
</para>
<para>
It can be set multiple times.
</para>
<para>
Module authors can use its value in
<literal>imports</literal>, in
<literal>submoduleWith</literal><quote>s
<literal>modules</literal> or in
<literal>evalModules</literal></quote>
<literal>modules</literal> parameter, among other places.
</para>
<para>
Note that <literal>imports</literal> must be evaluated
before the module fixpoint. Because of this, deferred
modules can only be imported into <quote>other</quote>
fixpoints, such as submodules.
</para>
<para>
One use case for this type is the type of a
<quote>default</quote> module that allow the user to affect
all submodules in an <literal>attrsOf submodule</literal> at
once. This is more convenient and discoverable than
expecting the module user to type-merge with the
<literal>attrsOf submodule</literal> option.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="sec-option-types-composed">

@ -146,6 +146,14 @@
a kernel module for mounting the Apple File System (APFS).
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://gitlab.com/DarkElvenAngel/argononed">argonone</link>,
a replacement daemon for the Raspberry Pi Argon One power
button and cooler. Available at
<link xlink:href="options.html#opt-services.hardware.argonone.enable">services.hardware.argonone</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/JustArchiNET/ArchiSteamFarm">ArchiSteamFarm</link>,
@ -2776,6 +2784,12 @@ sudo cp /var/lib/redis/dump.rdb /var/lib/redis-peertube/dump.rdb
runs a PostgreSQL server for the duration of package checks.
</para>
</listitem>
<listitem>
<para>
<literal>zfs</literal> was updated from 2.1.4 to 2.1.5,
enabling it to be used with Linux kernel 5.18.
</para>
</listitem>
<listitem>
<para>
<literal>stdenv.mkDerivation</literal> now supports a

@ -31,11 +31,82 @@
<literal>stdenv.buildPlatform.canExecute stdenv.hostPlatform</literal>.
</para>
</listitem>
<listitem>
<para>
The <literal>nixpkgs.hostPlatform</literal> and
<literal>nixpkgs.buildPlatform</literal> options have been
added. These cover and override the
<literal>nixpkgs.{system,localSystem,crossSystem}</literal>
options.
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
<literal>hostPlatform</literal> is the platform or
<quote><literal>system</literal></quote> string of the
NixOS system described by the configuration.
</para>
</listitem>
<listitem>
<para>
<literal>buildPlatform</literal> is the platform that is
responsible for building the NixOS configuration. It
defaults to the <literal>hostPlatform</literal>, for a
non-cross build configuration. To cross compile, set
<literal>buildPlatform</literal> to a different value.
</para>
</listitem>
</itemizedlist>
<para>
The new options convey the same information, but with fewer
options, and following the Nixpkgs terminology.
</para>
<para>
The existing options
<literal>nixpkgs.{system,localSystem,crossSystem}</literal>
have not been formally deprecated, to allow for evaluation of
the change and to allow for a transition period so that in
time the ecosystem can switch without breaking compatibility
with any supported NixOS release.
</para>
</listitem>
<listitem>
<para>
<literal>nixos-generate-config</literal> now generates
configurations that can be built in pure mode. This is
achieved by setting the new
<literal>nixpkgs.hostPlatform</literal> option.
</para>
<para>
You may have to unset the <literal>system</literal> parameter
in <literal>lib.nixosSystem</literal>, or similarly remove
definitions of the
<literal>nixpkgs.{system,localSystem,crossSystem}</literal>
options.
</para>
<para>
Alternatively, you can remove the
<literal>hostPlatform</literal> line and use NixOS like you
would in NixOS 22.05 and earlier.
</para>
</listitem>
<listitem>
<para>
PHP now defaults to PHP 8.1, updated from 8.0.
</para>
</listitem>
<listitem>
<para>
<literal>hardware.nvidia</literal> has a new option
<literal>open</literal> that can be used to opt in the
opensource version of NVIDIA kernel driver. Note that the
driver’s support for GeForce and Workstation GPUs is still
alpha quality, see
<link xlink:href="https://developer.nvidia.com/blog/nvidia-releases-open-source-gpu-kernel-modules/">NVIDIA
Releases Open-Source GPU Kernel Modules</link> for the
official announcement.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-release-22.11-new-services">
@ -71,6 +142,13 @@
<link linkend="opt-services.persistent-evdev.enable">services.persistent-evdev</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://schleuder.org/">schleuder</link>, a
mailing list manager with PGP support. Enable using
<link linkend="opt-services.schleuder.enable">services.schleuder</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://www.expressvpn.com">expressvpn</link>,
@ -100,6 +178,29 @@
compatible</emphasis>.
</para>
</listitem>
<listitem>
<para>
<literal>ngrok</literal> has been upgraded from 2.3.40 to
3.0.4. Please see
<link xlink:href="https://ngrok.com/docs/guides/upgrade-v2-v3">the
upgrade guide</link> and
<link xlink:href="https://ngrok.com/docs/ngrok-agent/changelog">changelog</link>.
Notably, breaking changes are that the config file format has
changed and support for single hypen arguments was dropped.
</para>
</listitem>
<listitem>
<para>
<literal>i18n.supportedLocales</literal> is now by default
only generated with the locales set in
<literal>i18n.defaultLocale</literal> and
<literal>i18n.extraLocaleSettings</literal>. This got
partially copied over from the minimal profile and reduces the
final system size by up to 200MB. If you require all locales
installed set the option to
<literal>[ &quot;all&quot; ]</literal>.
</para>
</listitem>
<listitem>
<para>
The <literal>isPowerPC</literal> predicate, found on
@ -115,12 +216,40 @@
<literal>(with foo; isPower &amp;&amp; is32bit &amp;&amp; isBigEndian)</literal>.
</para>
</listitem>
<listitem>
<para>
<literal>bsp-layout</literal> no longer uses the command
<literal>cycle</literal> to switch to other window layouts, as
it got replaced by the commands <literal>previous</literal>
and <literal>next</literal>.
</para>
</listitem>
<listitem>
<para>
The Barco ClickShare driver/client package
<literal>pkgs.clickshare-csc1</literal> and the option
<literal>programs.clickshare-csc1.enable</literal> have been
removed, as it requires <literal>qt4</literal>, which reached
its end-of-life 2015 and will no longer be supported by
nixpkgs.
<link xlink:href="https://www.barco.com/de/support/knowledge-base/4380-can-i-use-linux-os-with-clickshare-base-units">According
to Barco</link> many of their base unit models can be used
with Google Chrome and the Google Cast extension.
</para>
</listitem>
<listitem>
<para>
PHP 7.4 is no longer supported due to upstream not supporting
this version for the entire lifecycle of the 22.11 release.
</para>
</listitem>
<listitem>
<para>
riak package removed along with
<literal>services.riak</literal> module, due to lack of
maintainer to update the package.
</para>
</listitem>
<listitem>
<para>
(Neo)Vim can not be configured with
@ -129,11 +258,25 @@
instead.
</para>
</listitem>
<listitem>
<para>
<literal>k3s</literal> no longer supports docker as runtime
due to upstream dropping support.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-release-22.11-notable-changes">
<title>Other Notable Changes</title>
<itemizedlist>
<listitem>
<para>
The <literal>xplr</literal> package has been updated from
0.18.0 to 0.19.0, which brings some breaking changes. See the
<link xlink:href="https://github.com/sayanarijit/xplr/releases/tag/v0.19.0">upstream
release notes</link> for more details.
</para>
</listitem>
<listitem>
<para>
A new module was added for the Saleae Logic device family,
@ -160,6 +303,18 @@
as coreboot’s fork is no longer available.
</para>
</listitem>
<listitem>
<para>
There is a new module for the <literal>thunar</literal>
program (the Xfce file manager), which depends on the
<literal>xfconf</literal> dbus service, and also has a dbus
service and a systemd unit. The option
<literal>services.xserver.desktopManager.xfce.thunarPlugins</literal>
has been renamed to
<literal>programs.thunar.plugins</literal>, and in a future
release it may be removed.
</para>
</listitem>
</itemizedlist>
</section>
</section>

@ -61,6 +61,8 @@ In addition to numerous new and upgraded packages, this release has the followin
- [apfs](https://github.com/linux-apfs/linux-apfs-rw), a kernel module for mounting the Apple File System (APFS).
- [argonone](https://gitlab.com/DarkElvenAngel/argononed), a replacement daemon for the Raspberry Pi Argon One power button and cooler. Available at [services.hardware.argonone](options.html#opt-services.hardware.argonone.enable).
- [ArchiSteamFarm](https://github.com/JustArchiNET/ArchiSteamFarm), a C# application with primary purpose of idling Steam cards from multiple accounts simultaneously. Available as [services.archisteamfarm](#opt-services.archisteamfarm.enable).
- [BaGet](https://loic-sharma.github.io/BaGet/), a lightweight NuGet and symbol server. Available at [services.baget](#opt-services.baget.enable).
@ -971,7 +973,9 @@ In addition to numerous new and upgraded packages, this release has the followin
was changed.
- The new [`postgresqlTestHook`](https://nixos.org/manual/nixpkgs/stable/#sec-postgresqlTestHook) runs a PostgreSQL server for the duration of package checks.
- `zfs` was updated from 2.1.4 to 2.1.5, enabling it to be used with Linux kernel 5.18.
- `stdenv.mkDerivation` now supports a self-referencing `finalAttrs:` parameter
containing the final `mkDerivation` arguments including overrides.
`drv.overrideAttrs` now supports two parameters `finalAttrs: previousAttrs:`.

@ -17,8 +17,37 @@ In addition to numerous new and upgraded packages, this release has the followin
built for `stdenv.hostPlatform` (i.e. produced by `stdenv.cc`) by evaluating
`stdenv.buildPlatform.canExecute stdenv.hostPlatform`.
- The `nixpkgs.hostPlatform` and `nixpkgs.buildPlatform` options have been added.
These cover and override the `nixpkgs.{system,localSystem,crossSystem}` options.
- `hostPlatform` is the platform or "`system`" string of the NixOS system
described by the configuration.
- `buildPlatform` is the platform that is responsible for building the NixOS
configuration. It defaults to the `hostPlatform`, for a non-cross
build configuration. To cross compile, set `buildPlatform` to a different
value.
The new options convey the same information, but with fewer options, and
following the Nixpkgs terminology.
The existing options `nixpkgs.{system,localSystem,crossSystem}` have not
been formally deprecated, to allow for evaluation of the change and to allow
for a transition period so that in time the ecosystem can switch without
breaking compatibility with any supported NixOS release.
- `nixos-generate-config` now generates configurations that can be built in pure
mode. This is achieved by setting the new `nixpkgs.hostPlatform` option.
You may have to unset the `system` parameter in `lib.nixosSystem`, or similarly
remove definitions of the `nixpkgs.{system,localSystem,crossSystem}` options.
Alternatively, you can remove the `hostPlatform` line and use NixOS like you
would in NixOS 22.05 and earlier.
- PHP now defaults to PHP 8.1, updated from 8.0.
- `hardware.nvidia` has a new option `open` that can be used to opt in the opensource version of NVIDIA kernel driver. Note that the driver's support for GeForce and Workstation GPUs is still alpha quality, see [NVIDIA Releases Open-Source GPU Kernel Modules](https://developer.nvidia.com/blog/nvidia-releases-open-source-gpu-kernel-modules/) for the official announcement.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
## New Services {#sec-release-22.11-new-services}
@ -31,6 +60,8 @@ In addition to numerous new and upgraded packages, this release has the followin
Available as [services.infnoise](options.html#opt-services.infnoise.enable).
- [persistent-evdev](https://github.com/aiberia/persistent-evdev), a daemon to add virtual proxy devices that mirror a physical input device but persist even if the underlying hardware is hot-plugged. Available as [services.persistent-evdev](#opt-services.persistent-evdev.enable).
- [schleuder](https://schleuder.org/), a mailing list manager with PGP support. Enable using [services.schleuder](#opt-services.schleuder.enable).
- [expressvpn](https://www.expressvpn.com), the CLI client for ExpressVPN. Available as [services.expressvpn](#opt-services.expressvpn.enable).
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
@ -45,22 +76,44 @@ In addition to numerous new and upgraded packages, this release has the followin
`lib.systems.parse.isCompatible` still exists, but has changed semantically:
Architectures with differing endianness modes are *no longer considered compatible*.
- `ngrok` has been upgraded from 2.3.40 to 3.0.4. Please see [the upgrade guide](https://ngrok.com/docs/guides/upgrade-v2-v3)
and [changelog](https://ngrok.com/docs/ngrok-agent/changelog). Notably, breaking changes are that the config file format has
changed and support for single hypen arguments was dropped.
- `i18n.supportedLocales` is now by default only generated with the locales set in `i18n.defaultLocale` and `i18n.extraLocaleSettings`.
This got partially copied over from the minimal profile and reduces the final system size by up to 200MB.
If you require all locales installed set the option to ``[ "all" ]``.
- The `isPowerPC` predicate, found on `platform` attrsets (`hostPlatform`, `buildPlatform`, `targetPlatform`, etc) has been removed in order to reduce confusion. The predicate was was defined such that it matches only the 32-bit big-endian members of the POWER/PowerPC family, despite having a name which would imply a broader set of systems. If you were using this predicate, you can replace `foo.isPowerPC` with `(with foo; isPower && is32bit && isBigEndian)`.
- `bsp-layout` no longer uses the command `cycle` to switch to other window layouts, as it got replaced by the commands `previous` and `next`.
- The Barco ClickShare driver/client package `pkgs.clickshare-csc1` and the option `programs.clickshare-csc1.enable` have been removed,
as it requires `qt4`, which reached its end-of-life 2015 and will no longer be supported by nixpkgs.
[According to Barco](https://www.barco.com/de/support/knowledge-base/4380-can-i-use-linux-os-with-clickshare-base-units) many of their base unit models can be used with Google Chrome and the Google Cast extension.
- PHP 7.4 is no longer supported due to upstream not supporting this
version for the entire lifecycle of the 22.11 release.
- riak package removed along with `services.riak` module, due to lack of maintainer to update the package.
- (Neo)Vim can not be configured with `configure.pathogen` anymore to reduce maintainance burden.
Use `configure.packages` instead.
- `k3s` no longer supports docker as runtime due to upstream dropping support.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
## Other Notable Changes {#sec-release-22.11-notable-changes}
- The `xplr` package has been updated from 0.18.0 to 0.19.0, which brings some breaking changes. See the [upstream release notes](https://github.com/sayanarijit/xplr/releases/tag/v0.19.0) for more details.
- A new module was added for the Saleae Logic device family, providing the options `hardware.saleae-logic.enable` and `hardware.saleae-logic.package`.
- Matrix Synapse now requires entries in the `state_group_edges` table to be unique, in order to prevent accidentally introducing duplicate information (for example, because a database backup was restored multiple times). If your Synapse database already has duplicate rows in this table, this could fail with an error and require manual remediation.
- memtest86+ was updated from 5.00-coreboot-002 to 6.00-beta2. It is now the upstream version from https://www.memtest.org/, as coreboot's fork is no longer available.
- There is a new module for the `thunar` program (the Xfce file manager), which depends on the `xfconf` dbus service, and also has a dbus service and a systemd unit. The option `services.xserver.desktopManager.xfce.thunarPlugins` has been renamed to `programs.thunar.plugins`, and in a future release it may be removed.
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->

@ -78,6 +78,15 @@ pkgs.stdenv.mkDerivation {
# get rid of the unnecessary slack here--but see
# https://github.com/NixOS/nixpkgs/issues/125121 for caveats.
# shrink to fit
resize2fs -M $img
# Add 16 MebiByte to the current_size
new_size=$(dumpe2fs -h $img | awk -F: \
'/Block count/{count=$2} /Block size/{size=$2} END{print (count*size+16*2**20)/size}')
resize2fs $img $new_size
if [ ${builtins.toString compressImage} ]; then
echo "Compressing image"
zstd -v --no-progress ./$img -o $out

@ -22,6 +22,10 @@
, transformOptions ? lib.id # function for additional tranformations of the options
, documentType ? "appendix" # TODO deprecate "appendix" in favor of "none"
# and/or rename function to moduleOptionDoc for clean slate
# If you include more than one option list into a document, you need to
# provide different ids.
, variablelistId ? "configuration-variable-list"
, revision ? "" # Specify revision for the options
# a set of options the docs we are generating will be merged into, as if by recursiveUpdate.
# used to split the options doc build into a static part (nixos/modules) and a dynamic part
@ -112,7 +116,15 @@ in rec {
optionsJSON = pkgs.runCommand "options.json"
{ meta.description = "List of NixOS options in JSON format";
buildInputs = [ pkgs.brotli ];
buildInputs = [
pkgs.brotli
(let
self = (pkgs.python3Minimal.override {
inherit self;
includeSiteCustomize = true;
});
in self.withPackages (p: [ p.mistune_2_0 ]))
];
options = builtins.toFile "options.json"
(builtins.unsafeDiscardStringContext (builtins.toJSON optionsNix));
}
@ -123,9 +135,13 @@ in rec {
${
if baseOptionsJSON == null
then "cp $options $dst/options.json"
then ''
# `cp $options $dst/options.json`, but with temporary
# markdown processing
python ${./mergeJSON.py} $options <(echo '{}') > $dst/options.json
''
else ''
${pkgs.python3Minimal}/bin/python ${./mergeJSON.py} \
python ${./mergeJSON.py} \
${lib.optionalString warningsAreErrors "--warnings-are-errors"} \
${baseOptionsJSON} $options \
> $dst/options.json
@ -165,6 +181,7 @@ in rec {
${pkgs.libxslt.bin}/bin/xsltproc \
--stringparam documentType '${documentType}' \
--stringparam revision '${revision}' \
--stringparam variablelistId '${variablelistId}' \
-o intermediate.xml ${./options-to-docbook.xsl} sorted.xml
${pkgs.libxslt.bin}/bin/xsltproc \
-o "$out" ${./postprocess-option-descriptions.xsl} intermediate.xml

@ -41,6 +41,154 @@ def unpivot(options: Dict[Key, Option]) -> Dict[str, JSON]:
result[opt.name] = opt.value
return result
# converts in-place!
def convertMD(options: Dict[str, Any]) -> str:
import mistune
import re
from xml.sax.saxutils import escape, quoteattr
admonitions = {
'.warning': 'warning',
'.important': 'important',
'.note': 'note'
}
class Renderer(mistune.renderers.BaseRenderer):
def _get_method(self, name):
try:
return super(Renderer, self)._get_method(name)
except AttributeError:
def not_supported(*args, **kwargs):
raise NotImplementedError("md node not supported yet", name, args, **kwargs)
return not_supported
def text(self, text):
return escape(text)
def paragraph(self, text):
return text + "\n\n"
def newline(self):
return "<literallayout>\n</literallayout>"
def codespan(self, text):
return f"<literal>{escape(text)}</literal>"
def block_code(self, text, info=None):
info = f" language={quoteattr(info)}" if info is not None else ""
return f"<programlisting{info}>\n{escape(text)}</programlisting>"
def link(self, link, text=None, title=None):
if link[0:1] == '#':
attr = "linkend"
link = quoteattr(link[1:])
else:
# try to faithfully reproduce links that were of the form <link href="..."/>
# in docbook format
if text == link:
text = ""
attr = "xlink:href"
link = quoteattr(link)
return f"<link {attr}={link}>{text}</link>"
def list(self, text, ordered, level, start=None):
if ordered:
raise NotImplementedError("ordered lists not supported yet")
return f"<itemizedlist>\n{text}\n</itemizedlist>"
def list_item(self, text, level):
return f"<listitem><para>{text}</para></listitem>\n"
def block_text(self, text):
return text
def emphasis(self, text):
return f"<emphasis>{text}</emphasis>"
def strong(self, text):
return f"<emphasis role=\"strong\">{text}</emphasis>"
def admonition(self, text, kind):
if kind not in admonitions:
raise NotImplementedError(f"admonition {kind} not supported yet")
tag = admonitions[kind]
# we don't keep whitespace here because usually we'll contain only
# a single paragraph and the original docbook string is no longer
# available to restore the trailer.
return f"<{tag}><para>{text.rstrip()}</para></{tag}>"
def block_quote(self, text):
return f"<blockquote><para>{text}</para></blockquote>"
def command(self, text):
return f"<command>{escape(text)}</command>"
def option(self, text):
return f"<option>{escape(text)}</option>"
def file(self, text):
return f"<filename>{escape(text)}</filename>"
def manpage(self, page, section):
title = f"<refentrytitle>{escape(page)}</refentrytitle>"
vol = f"<manvolnum>{escape(section)}</manvolnum>"
return f"<citerefentry>{title}{vol}</citerefentry>"
def finalize(self, data):
return "".join(data)
plugins = []
COMMAND_PATTERN = r'\{command\}`(.*?)`'
def command(md):
def parse(self, m, state):
return ('command', m.group(1))
md.inline.register_rule('command', COMMAND_PATTERN, parse)
md.inline.rules.append('command')
plugins.append(command)
FILE_PATTERN = r'\{file\}`(.*?)`'
def file(md):
def parse(self, m, state):
return ('file', m.group(1))
md.inline.register_rule('file', FILE_PATTERN, parse)
md.inline.rules.append('file')
plugins.append(file)
OPTION_PATTERN = r'\{option\}`(.*?)`'
def option(md):
def parse(self, m, state):
return ('option', m.group(1))
md.inline.register_rule('option', OPTION_PATTERN, parse)
md.inline.rules.append('option')
plugins.append(option)
MANPAGE_PATTERN = r'\{manpage\}`(.*?)\((.+?)\)`'
def manpage(md):
def parse(self, m, state):
return ('manpage', m.group(1), m.group(2))
md.inline.register_rule('manpage', MANPAGE_PATTERN, parse)
md.inline.rules.append('manpage')
plugins.append(manpage)
ADMONITION_PATTERN = re.compile(r'^::: \{([^\n]*?)\}\n(.*?)^:::\n', flags=re.MULTILINE|re.DOTALL)
def admonition(md):
def parse(self, m, state):
return {
'type': 'admonition',
'children': self.parse(m.group(2), state),
'params': [ m.group(1) ],
}
md.block.register_rule('admonition', ADMONITION_PATTERN, parse)
md.block.rules.append('admonition')
plugins.append(admonition)
def convertString(text: str) -> str:
rendered = mistune.markdown(text, renderer=Renderer(), plugins=plugins)
# keep trailing spaces so we can diff the generated XML to check for conversion bugs.
return rendered.rstrip() + text[len(text.rstrip()):]
def optionIs(option: Dict[str, Any], key: str, typ: str) -> bool:
if key not in option: return False
if type(option[key]) != dict: return False
if '_type' not in option[key]: return False
return option[key]['_type'] == typ
for (name, option) in options.items():
if optionIs(option, 'description', 'mdDoc'):
option['description'] = convertString(option['description']['text'])
if optionIs(option, 'example', 'literalMD'):
docbook = convertString(option['example']['text'])
option['example'] = { '_type': 'literalDocBook', 'text': docbook }
if optionIs(option, 'default', 'literalMD'):
docbook = convertString(option['default']['text'])
option['default'] = { '_type': 'literalDocBook', 'text': docbook }
return options
warningsAreErrors = sys.argv[1] == "--warnings-are-errors"
optOffset = 1 if warningsAreErrors else 0
options = pivot(json.load(open(sys.argv[1 + optOffset], 'r')))
@ -50,7 +198,7 @@ overrides = pivot(json.load(open(sys.argv[2 + optOffset], 'r')))
for (k, v) in options.items():
# 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']))
v.value['declarations'] = list(map(lambda s: f'nixos/modules/{s}' if isinstance(s, str) else s, v.value['declarations']))
# merge both descriptions
for (k, v) in overrides.items():
@ -92,4 +240,4 @@ if hasWarnings and warningsAreErrors:
file=sys.stderr)
sys.exit(1)
json.dump(unpivot(options), fp=sys.stdout)
json.dump(convertMD(unpivot(options)), fp=sys.stdout)

@ -14,6 +14,7 @@
<xsl:param name="revision" />
<xsl:param name="documentType" />
<xsl:param name="program" />
<xsl:param name="variablelistId" />
<xsl:template match="/expr/list">
@ -31,7 +32,8 @@
</xsl:template>
<xsl:template name="variable-list">
<variablelist xml:id="configuration-variable-list">
<variablelist>
<xsl:attribute name="id" namespace="http://www.w3.org/XML/1998/namespace"><xsl:value-of select="$variablelistId"/></xsl:attribute>
<xsl:for-each select="attrs">
<xsl:variable name="id" select="
concat('opt-',
@ -213,6 +215,23 @@
<xsl:template match="attr[@name = 'declarations' or @name = 'definitions']">
<simplelist>
<!--
Example:
opt.declarations = [ { name = "foo/bar.nix"; url = "https://github.com/....."; } ];
-->
<xsl:for-each select="list/attrs[attr[@name = 'name']]">
<member><filename>
<xsl:if test="attr[@name = 'url']">
<xsl:attribute name="xlink:href"><xsl:value-of select="attr[@name = 'url']/string/@value"/></xsl:attribute>
</xsl:if>
<xsl:value-of select="attr[@name = 'name']/string/@value"/>
</filename></member>
</xsl:for-each>
<!--
When the declarations/definitions are raw strings,
fall back to hardcoded location logic, specific to Nixpkgs.
-->
<xsl:for-each select="list/string">
<member><filename>
<!-- Hyperlink the filename either to the NixOS Subversion

@ -20,10 +20,15 @@ in rec {
merge = loc: defs:
let
defs' = filterOverrides defs;
defs'' = getValues defs';
in
if isList (head defs'')
then concatLists defs''
if isList (head defs').value
then concatMap (def:
if builtins.typeOf def.value == "list"
then def.value
else
throw "The definitions for systemd unit options should be either all lists, representing repeatable options, or all non-lists, but for the option ${showOption loc}, the definitions are a mix of list and non-list ${lib.options.showDefs defs'}"
) defs'
else mergeEqualOption loc defs';
};

@ -4,6 +4,7 @@ setup(
name="nixos-test-driver",
version='1.1',
packages=find_packages(),
package_data={"test_driver": ["py.typed"]},
entry_points={
"console_scripts": [
"nixos-test-driver=test_driver:main",

@ -119,6 +119,7 @@ rec {
{
inherit testName;
nativeBuildInputs = [ makeWrapper mypy ];
buildInputs = [ testDriver ];
testScript = testScript';
preferLocalBuild = true;
passthru = passthru // {
@ -138,13 +139,10 @@ rec {
echo "${builtins.toString vlanNames}" >> testScriptWithTypes
echo -n "$testScript" >> testScriptWithTypes
# set pythonpath so mypy knows where to find the imports. this requires the py.typed file.
export PYTHONPATH='${./test-driver}'
mypy --no-implicit-optional \
--pretty \
--no-color-output \
testScriptWithTypes
unset PYTHONPATH
''}
echo -n "$testScript" >> $out/test-script

@ -46,9 +46,9 @@ in
type = with types; either str path;
default = "Lat2-Terminus16";
example = "LatArCyrHeb-16";
description = ''
description = mdDoc ''
The font used for the virtual consoles. Leave empty to use
whatever the <command>setfont</command> program considers the
whatever the {command}`setfont` program considers the
default font.
Can be either a font name or a path to a PSF font file.
'';

@ -9,21 +9,20 @@ with lib;
environment.enableDebugInfo = mkOption {
type = types.bool;
default = false;
description = ''
description = mdDoc ''
Some NixOS packages provide debug symbols. However, these are
not included in the system closure by default to save disk
space. Enabling this option causes the debug symbols to appear
in <filename>/run/current-system/sw/lib/debug/.build-id</filename>,
where tools such as <command>gdb</command> can find them.
in {file}`/run/current-system/sw/lib/debug/.build-id`,
where tools such as {command}`gdb` can find them.
If you need debug symbols for a package that doesn't
provide them by default, you can enable them as follows:
<programlisting>
nixpkgs.config.packageOverrides = pkgs: {
hello = pkgs.hello.overrideAttrs (oldAttrs: {
separateDebugInfo = true;
});
};
</programlisting>
nixpkgs.config.packageOverrides = pkgs: {
hello = pkgs.hello.overrideAttrs (oldAttrs: {
separateDebugInfo = true;
});
};
'';
};

@ -65,7 +65,7 @@ let
${fcBool cfg.hinting.autohint}
</edit>
<edit mode="append" name="hintstyle">
<const>hintslight</const>
<const>${cfg.hinting.style}</const>
</edit>
<edit mode="append" name="antialias">
${fcBool cfg.antialias}
@ -226,7 +226,6 @@ in
(mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "useEmbeddedBitmaps" ] [ "fonts" "fontconfig" "useEmbeddedBitmaps" ])
(mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "forceAutohint" ] [ "fonts" "fontconfig" "forceAutohint" ])
(mkRenamedOptionModule [ "fonts" "fontconfig" "ultimate" "renderMonoTTFAsBitmap" ] [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ])
(mkRemovedOptionModule [ "fonts" "fontconfig" "hinting" "style" ] "")
(mkRemovedOptionModule [ "fonts" "fontconfig" "forceAutohint" ] "")
(mkRemovedOptionModule [ "fonts" "fontconfig" "renderMonoTTFAsBitmap" ] "")
(mkRemovedOptionModule [ "fonts" "fontconfig" "dpi" ] "Use display server-specific options")
@ -349,6 +348,20 @@ in
fonts, but better than unhinted fonts.
'';
};
style = mkOption {
type = types.enum [ "hintnone" "hintslight" "hintmedium" "hintfull" ];
default = "hintslight";
description = ''
Hintstyle is the amount of font reshaping done to line up
to the grid.
hintslight will make the font more fuzzy to line up to the grid
but will be better in retaining font shape, while hintfull will
be a crisp font that aligns well to the pixel grid but will lose
a greater amount of font shape.
'';
};
};
includeUserConf = mkOption {

@ -53,7 +53,18 @@ with lib;
supportedLocales = mkOption {
type = types.listOf types.str;
default = ["all"];
default = builtins.map (l: l + "/UTF-8")
(unique (
[ config.i18n.defaultLocale ] ++
(attrValues (filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
));
defaultText = literalExpression ''
builtins.map (l: l + "/UTF-8")
(unique (
[ config.i18n.defaultLocale ] ++
(attrValues (filterAttrs (n: v: n != "LANGUAGE") config.i18n.extraLocaleSettings))
))
'';
example = ["en_US.UTF-8/UTF-8" "nl_NL.UTF-8/UTF-8" "nl_NL/ISO-8859-1"];
description = ''
List of locales that the system should support. The value

@ -36,14 +36,11 @@ let
/plugin/;
/ {
compatible = "raspberrypi";
fragment@0 {
target-path = "/soc";
__overlay__ {
pps {
compatible = "pps-gpio";
status = "okay";
};
};
};
&{/soc} {
pps {
compatible = "pps-gpio";
status = "okay";
};
};
'';
@ -88,13 +85,14 @@ let
# Compile single Device Tree overlay source
# file (.dts) into its compiled variant (.dtbo)
compileDTS = name: f: pkgs.callPackage({ dtc }: pkgs.stdenv.mkDerivation {
compileDTS = name: f: pkgs.callPackage({ stdenv, dtc }: stdenv.mkDerivation {
name = "${name}-dtbo";
nativeBuildInputs = [ dtc ];
buildCommand = ''
dtc -I dts ${f} -O dtb -@ -o $out
$CC -E -nostdinc -I${getDev cfg.kernelPackage}/lib/modules/${cfg.kernelPackage.modDirVersion}/source/scripts/dtc/include-prefixes -undef -D__DTS__ -x assembler-with-cpp ${f} | \
dtc -I dts -O dtb -@ -o $out
'';
}) {};

@ -183,6 +183,14 @@ in
'';
example = literalExpression "config.boot.kernelPackages.nvidiaPackages.legacy_340";
};
hardware.nvidia.open = lib.mkOption {
type = lib.types.bool;
default = false;
description = ''
Whether to use the open source kernel module
'';
};
};
config = let
@ -231,6 +239,11 @@ in
);
message = "Required files for driver based power management don't exist.";
}
{
assertion = cfg.open -> (cfg.package ? open && cfg.package ? firmware);
message = "This version of NVIDIA driver does not provide a corresponding opensource kernel driver";
}
];
# If Optimus/PRIME is enabled, we:
@ -364,7 +377,8 @@ in
++ optional (nvidia_x11.persistenced != null && config.virtualisation.docker.enableNvidia)
"L+ /run/nvidia-docker/extras/bin/nvidia-persistenced - - - - ${nvidia_x11.persistenced}/origBin/nvidia-persistenced";
boot.extraModulePackages = [ nvidia_x11.bin ];
boot.extraModulePackages = if cfg.open then [ nvidia_x11.open ] else [ nvidia_x11.bin ];
hardware.firmware = lib.optional cfg.open nvidia_x11.firmware;
# nvidia-uvm is required by CUDA applications.
boot.kernelModules = [ "nvidia-uvm" ] ++
@ -372,7 +386,8 @@ in
# If requested enable modesetting via kernel parameter.
boot.kernelParams = optional (offloadCfg.enable || cfg.modesetting.enable) "nvidia-drm.modeset=1"
++ optional cfg.powerManagement.enable "nvidia.NVreg_PreserveVideoMemoryAllocations=1";
++ optional cfg.powerManagement.enable "nvidia.NVreg_PreserveVideoMemoryAllocations=1"
++ optional cfg.open "nvidia.NVreg_OpenRmEnableUnsupportedGpus=1";
services.udev.extraRules =
''

@ -18,7 +18,8 @@
extraGSettingsOverrides = ''
[org.gnome.shell]
welcome-dialog-last-shown-version='9999999999'
[org.gnome.desktop.session]
idle-delay=0
[org.gnome.settings-daemon.plugins.power]
sleep-inactive-ac-type='nothing'
sleep-inactive-battery-type='nothing'

@ -18,7 +18,7 @@ with lib;
let
rootfsImage = pkgs.callPackage ../../../lib/make-ext4-fs.nix ({
inherit (config.sdImage) storePaths;
compressImage = true;
compressImage = config.sdImage.compressImage;
populateImageCommands = config.sdImage.populateRootCommands;
volumeLabel = "NIXOS_SD";
} // optionalAttrs (config.sdImage.rootPartitionUUID != null) {
@ -174,7 +174,8 @@ in
mtools, libfaketime, util-linux, zstd }: stdenv.mkDerivation {
name = config.sdImage.imageName;
nativeBuildInputs = [ dosfstools e2fsprogs mtools libfaketime util-linux zstd ];
nativeBuildInputs = [ dosfstools e2fsprogs libfaketime mtools util-linux ]
++ lib.optional config.sdImage.compressImage zstd;
inherit (config.sdImage) imageName compressImage;
@ -189,14 +190,18 @@ in
echo "file sd-image $img" >> $out/nix-support/hydra-build-products
fi
root_fs=${rootfsImage}
${lib.optionalString config.sdImage.compressImage ''
root_fs=./root-fs.img
echo "Decompressing rootfs image"
zstd -d --no-progress "${rootfsImage}" -o ./root-fs.img
zstd -d --no-progress "${rootfsImage}" -o $root_fs
''}
# Gap in front of the first partition, in MiB
gap=${toString config.sdImage.firmwarePartitionOffset}
# Create the image file sized to fit /boot/firmware and /, plus slack for the gap.
rootSizeBlocks=$(du -B 512 --apparent-size ./root-fs.img | awk '{ print $1 }')
rootSizeBlocks=$(du -B 512 --apparent-size $root_fs | awk '{ print $1 }')
firmwareSizeBlocks=$((${toString config.sdImage.firmwareSize} * 1024 * 1024 / 512))
imageSize=$((rootSizeBlocks * 512 + firmwareSizeBlocks * 512 + gap * 1024 * 1024))
truncate -s $imageSize $img
@ -214,7 +219,7 @@ in
# Copy the rootfs into the SD image
eval $(partx $img -o START,SECTORS --nr 2 --pairs)
dd conv=notrunc if=./root-fs.img of=$img seek=$START count=$SECTORS
dd conv=notrunc if=$root_fs of=$img seek=$START count=$SECTORS
# Create a FAT32 /boot/firmware partition of suitable size into firmware_part.img
eval $(partx $img -o START,SECTORS --nr 1 --pairs)

@ -1,14 +1,15 @@
getVersion() {
local dir="$1"
rev=
if [ -e "$dir/.git" ]; then
gitDir="$dir/.git"
if [ -e "$gitDir" ]; then
if [ -z "$(type -P git)" ]; then
echo "warning: Git not found; cannot figure out revision of $dir" >&2
return
fi
cd "$dir"
rev=$(git rev-parse --short HEAD)
if git describe --always --dirty | grep -q dirty; then
rev=$(git --git-dir="$gitDir" rev-parse --short HEAD)
if git --git-dir="$gitDir" describe --always --dirty | grep -q dirty; then
rev+=M
fi
fi

@ -84,6 +84,15 @@ sub debug {
}
# nixpkgs.system
my ($status, @systemLines) = runCommand("nix-instantiate --impure --eval --expr builtins.currentSystem");
if ($status != 0 || join("", @systemLines) =~ /error/) {
die "Failed to retrieve current system type from nix.\n";
}
chomp(my $system = @systemLines[0]);
push @attrs, "nixpkgs.hostPlatform = lib.mkDefault $system;";
my $cpuinfo = read_file "/proc/cpuinfo";

@ -178,19 +178,12 @@ in
man.generateCaches = mkOption {
type = types.bool;
default = false;
description = ''
description = mdDoc ''
Whether to generate the manual page index caches.
This allows searching for a page or
keyword using utilities like
<citerefentry>
<refentrytitle>apropos</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>
and the <literal>-k</literal> option of
<citerefentry>
<refentrytitle>man</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>.
keyword using utilities like {manpage}`apropos(1)`
and the `-k` option of
{manpage}`man(1)`.
'';
};
@ -216,16 +209,14 @@ in
dev.enable = mkOption {
type = types.bool;
default = false;
description = ''
description = mdDoc ''
Whether to install documentation targeted at developers.
<itemizedlist>
<listitem><para>This includes man pages targeted at developers if <option>documentation.man.enable</option> is
set (this also includes "devman" outputs).</para></listitem>
<listitem><para>This includes info pages targeted at developers if <option>documentation.info.enable</option>
is set (this also includes "devinfo" outputs).</para></listitem>
<listitem><para>This includes other pages targeted at developers if <option>documentation.doc.enable</option>
is set (this also includes "devdoc" outputs).</para></listitem>
</itemizedlist>
* This includes man pages targeted at developers if {option}`documentation.man.enable` is
set (this also includes "devman" outputs).
* This includes info pages targeted at developers if {option}`documentation.info.enable`
is set (this also includes "devinfo" outputs).
* This includes other pages targeted at developers if {option}`documentation.doc.enable`
is set (this also includes "devdoc" outputs).
'';
};

@ -3,7 +3,7 @@
# IMPORTANT!
# We only add static uids and gids for services where it is not feasible
# to change uids/gids on service start, in example a service with a lot of
# to change uids/gids on service start, for example a service with a lot of
# files. Please also check if the service is applicable for systemd's
# DynamicUser option and does not need a uid/gid allocation at all.
# Systemd can also change ownership of service directories using the
@ -236,7 +236,7 @@ in
gitit = 202;
riemanntools = 203;
subsonic = 204;
riak = 205;
# riak = 205; # unused, remove 2022-07-22
#shout = 206; # dynamically allocated as of 2021-09-18
gateone = 207;
namecoin = 208;
@ -553,7 +553,7 @@ in
gitit = 202;
riemanntools = 203;
subsonic = 204;
riak = 205;
# riak = 205;#unused, removed 2022-06-22
#shout = 206; #unused
gateone = 207;
namecoin = 208;

@ -23,11 +23,11 @@ in
++ lib.optionals config.documentation.dev.enable [ "devman" ];
ignoreCollisions = true;
};
defaultText = lib.literalDocBook "all man pages in <option>config.environment.systemPackages</option>";
description = ''
The manual pages to generate caches for if <option>documentation.man.generateCaches</option>
defaultText = lib.literalMD "all man pages in {option}`config.environment.systemPackages`";
description = lib.mdDoc ''
The manual pages to generate caches for if {option}`documentation.man.generateCaches`
is enabled. Must be a path to a directory with man pages under
<literal>/share/man</literal>; see the source for an example.
`/share/man`; see the source for an example.
Advanced users can make this a content-addressed derivation to save a few rebuilds.
'';
};

@ -55,9 +55,46 @@ let
check = builtins.isAttrs;
};
defaultPkgs = import ../../.. {
inherit (cfg) config overlays localSystem crossSystem;
};
hasBuildPlatform = opt.buildPlatform.highestPrio < (mkOptionDefault {}).priority;
hasHostPlatform = opt.hostPlatform.isDefined;
hasPlatform = hasHostPlatform || hasBuildPlatform;
# Context for messages
hostPlatformLine = optionalString hasHostPlatform "${showOptionWithDefLocs opt.hostPlatform}";
buildPlatformLine = optionalString hasBuildPlatform "${showOptionWithDefLocs opt.buildPlatform}";
platformLines = optionalString hasPlatform ''
Your system configuration configures nixpkgs with platform parameters:
${hostPlatformLine
}${buildPlatformLine
}'';
legacyOptionsDefined =
optional (opt.localSystem.highestPrio < (mkDefault {}).priority) opt.system
++ optional (opt.localSystem.highestPrio < (mkOptionDefault {}).priority) opt.localSystem
++ optional (opt.crossSystem.highestPrio < (mkOptionDefault {}).priority) opt.crossSystem
;
defaultPkgs =
if opt.hostPlatform.isDefined
then
let isCross = cfg.buildPlatform != cfg.hostPlatform;
systemArgs =
if isCross
then {
localSystem = cfg.buildPlatform;
crossSystem = cfg.hostPlatform;
}
else {
localSystem = cfg.hostPlatform;
};
in
import ../../.. ({
inherit (cfg) config overlays;
} // systemArgs)
else
import ../../.. {
inherit (cfg) config overlays localSystem crossSystem;
};
finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs;
@ -157,6 +194,46 @@ in
'';
};
hostPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
example = { system = "aarch64-linux"; config = "aarch64-unknown-linux-gnu"; };
# Make sure that the final value has all fields for sake of other modules
# referring to this. TODO make `lib.systems` itself use the module system.
apply = lib.systems.elaborate;
defaultText = literalExpression
''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform'';
description = ''
Specifies the platform where the NixOS configuration will run.
To cross-compile, set also <code>nixpkgs.buildPlatform</code>.
Ignored when <code>nixpkgs.pkgs</code> is set.
'';
};
buildPlatform = mkOption {
type = types.either types.str types.attrs; # TODO utilize lib.systems.parsedPlatform
default = cfg.hostPlatform;
example = { system = "x86_64-linux"; config = "x86_64-unknown-linux-gnu"; };
# Make sure that the final value has all fields for sake of other modules
# referring to this.
apply = lib.systems.elaborate;
defaultText = literalExpression
''config.nixpkgs.hostPlatform'';
description = ''
Specifies the platform on which NixOS should be built.
By default, NixOS is built on the system where it runs, but you can
change where it's built. Setting this option will cause NixOS to be
cross-compiled.
For instance, if you're doing distributed multi-platform deployment,
or if you're building machines, you can set this to match your
development system and/or build farm.
Ignored when <code>nixpkgs.pkgs</code> is set.
'';
};
localSystem = mkOption {
type = types.attrs; # TODO utilize lib.systems.parsedPlatform
default = { inherit (cfg) system; };
@ -176,10 +253,13 @@ in
deployment, or when building virtual machines. See its
description in the Nixpkgs manual for more details.
Ignored when <code>nixpkgs.pkgs</code> is set.
Ignored when <code>nixpkgs.pkgs</code> or <code>hostPlatform</code> is set.
'';
};
# TODO deprecate. "crossSystem" is a nonsense identifier, because "cross"
# is a relation between at least 2 systems in the context of a
# specific build step, not a single system.
crossSystem = mkOption {
type = types.nullOr types.attrs; # TODO utilize lib.systems.parsedPlatform
default = null;
@ -193,7 +273,7 @@ in
should be set as null, the default. See its description in the
Nixpkgs manual for more details.
Ignored when <code>nixpkgs.pkgs</code> is set.
Ignored when <code>nixpkgs.pkgs</code> or <code>hostPlatform</code> is set.
'';
};
@ -216,8 +296,7 @@ in
</programlisting>
See <code>nixpkgs.localSystem</code> for more information.
Ignored when <code>nixpkgs.localSystem</code> is set.
Ignored when <code>nixpkgs.pkgs</code> is set.
Ignored when <code>nixpkgs.pkgs</code>, <code>nixpkgs.localSystem</code> or <code>nixpkgs.hostPlatform</code> is set.
'';
};
};
@ -240,10 +319,23 @@ in
else "nixpkgs.localSystem";
pkgsSystem = finalPkgs.stdenv.targetPlatform.system;
in {
assertion = nixosExpectedSystem == pkgsSystem;
assertion = !hasPlatform -> nixosExpectedSystem == pkgsSystem;
message = "The NixOS nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but NixOS was configured for system ${nixosExpectedSystem} via NixOS option ${nixosOption}. The NixOS system settings must match the Nixpkgs target system.";
}
)
{
assertion = hasPlatform -> legacyOptionsDefined == [];
message = ''
Your system configures nixpkgs with the platform parameter${optionalString hasBuildPlatform "s"}:
${hostPlatformLine
}${buildPlatformLine
}
However, it also defines the legacy options:
${concatMapStrings showOptionWithDefLocs legacyOptionsDefined}
For a future proof system configuration, we recommend to remove
the legacy definitions.
'';
}
];
};

@ -1,8 +1,63 @@
{ evalMinimalConfig, pkgs, lib, stdenv }:
let
eval = mod: evalMinimalConfig {
imports = [ ../nixpkgs.nix mod ];
};
withHost = eval {
nixpkgs.hostPlatform = "aarch64-linux";
};
withHostAndBuild = eval {
nixpkgs.hostPlatform = "aarch64-linux";
nixpkgs.buildPlatform = "aarch64-darwin";
};
ambiguous = {
_file = "ambiguous.nix";
nixpkgs.hostPlatform = "aarch64-linux";
nixpkgs.buildPlatform = "aarch64-darwin";
nixpkgs.system = "x86_64-linux";
nixpkgs.localSystem.system = "x86_64-darwin";
nixpkgs.crossSystem.system = "i686-linux";
imports = [
{ _file = "repeat.nix";
nixpkgs.hostPlatform = "aarch64-linux";
}
];
};
getErrors = module:
let
uncheckedEval = lib.evalModules { modules = [ ../nixpkgs.nix module ]; };
in map (ass: ass.message) (lib.filter (ass: !ass.assertion) uncheckedEval.config.assertions);
in
lib.recurseIntoAttrs {
invokeNixpkgsSimple =
(evalMinimalConfig ({ config, modulesPath, ... }: {
imports = [ (modulesPath + "/misc/nixpkgs.nix") ];
(eval {
nixpkgs.system = stdenv.hostPlatform.system;
}))._module.args.pkgs.hello;
})._module.args.pkgs.hello;
assertions =
assert withHost._module.args.pkgs.stdenv.hostPlatform.system == "aarch64-linux";
assert withHost._module.args.pkgs.stdenv.buildPlatform.system == "aarch64-linux";
assert withHostAndBuild._module.args.pkgs.stdenv.hostPlatform.system == "aarch64-linux";
assert withHostAndBuild._module.args.pkgs.stdenv.buildPlatform.system == "aarch64-darwin";
assert builtins.trace (lib.head (getErrors ambiguous))
getErrors ambiguous ==
[''
Your system configures nixpkgs with the platform parameters:
nixpkgs.hostPlatform, with values defined in:
- repeat.nix
- ambiguous.nix
nixpkgs.buildPlatform, with values defined in:
- ambiguous.nix
However, it also defines the legacy options:
nixpkgs.system, with values defined in:
- ambiguous.nix
nixpkgs.localSystem, with values defined in:
- ambiguous.nix
nixpkgs.crossSystem, with values defined in:
- ambiguous.nix
For a future proof system configuration, we recommend to remove
the legacy definitions.
''];
pkgs.emptyFile;
}

@ -141,7 +141,6 @@
./programs/cdemu.nix
./programs/cfs-zen-tweaks.nix
./programs/chromium.nix
./programs/clickshare.nix
./programs/cnping.nix
./programs/command-not-found/command-not-found.nix
./programs/criu.nix
@ -218,6 +217,7 @@
./programs/sway.nix
./programs/system-config-printer.nix
./programs/thefuck.nix
./programs/thunar.nix
./programs/tmux.nix
./programs/traceroute.nix
./programs/tsm-client.nix
@ -351,6 +351,7 @@
./services/databases/cockroachdb.nix
./services/databases/couchdb.nix
./services/databases/dragonflydb.nix
./services/databases/dgraph.nix
./services/databases/firebird.nix
./services/databases/foundationdb.nix
./services/databases/hbase.nix
@ -366,7 +367,6 @@
./services/databases/pgmanage.nix
./services/databases/postgresql.nix
./services/databases/redis.nix
./services/databases/riak.nix
./services/databases/victoriametrics.nix
./services/desktops/accountsservice.nix
./services/desktops/bamf.nix
@ -431,6 +431,7 @@
./services/games/terraria.nix
./services/hardware/acpid.nix
./services/hardware/actkbd.nix
./services/hardware/argonone.nix
./services/hardware/auto-cpufreq.nix
./services/hardware/bluetooth.nix
./services/hardware/bolt.nix
@ -516,6 +517,7 @@
./services/mail/rspamd.nix
./services/mail/rss2email.nix
./services/mail/roundcube.nix
./services/mail/schleuder.nix
./services/mail/sympa.nix
./services/mail/nullmailer.nix
./services/matrix/appservice-discord.nix
@ -660,6 +662,7 @@
./services/monitoring/do-agent.nix
./services/monitoring/fusion-inventory.nix
./services/monitoring/grafana.nix
./services/monitoring/grafana-agent.nix
./services/monitoring/grafana-image-renderer.nix
./services/monitoring/grafana-reporter.nix
./services/monitoring/graphite.nix
@ -893,6 +896,7 @@
./services/networking/redsocks.nix
./services/networking/resilio.nix
./services/networking/robustirc-bridge.nix
./services/networking/routedns.nix
./services/networking/rpcbind.nix
./services/networking/rxe.nix
./services/networking/sabnzbd.nix

@ -8,9 +8,6 @@ with lib;
{
environment.noXlibs = mkDefault true;
# This isn't perfect, but let's expect the user specifies an UTF-8 defaultLocale
i18n.supportedLocales = [ (config.i18n.defaultLocale + "/UTF-8") ];
documentation.enable = mkDefault false;
documentation.nixos.enable = mkDefault false;

@ -1,21 +0,0 @@
{ config, lib, pkgs, ... }:
{
options.programs.clickshare-csc1.enable =
lib.options.mkEnableOption ''
Barco ClickShare CSC-1 driver/client.
This allows users in the <literal>clickshare</literal>
group to access and use a ClickShare USB dongle
that is connected to the machine
'';
config = lib.modules.mkIf config.programs.clickshare-csc1.enable {
environment.systemPackages = [ pkgs.clickshare-csc1 ];
services.udev.packages = [ pkgs.clickshare-csc1 ];
users.groups.clickshare = {};
};
meta.maintainers = [ lib.maintainers.yarny ];
}

@ -0,0 +1,44 @@
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.programs.thunar;
in {
meta = {
maintainers = teams.xfce.members;
};
options = {
programs.thunar = {
enable = mkEnableOption "Thunar, the Xfce file manager";
plugins = mkOption {
default = [];
type = types.listOf types.package;
description = "List of thunar plugins to install.";
example = literalExpression "with pkgs.xfce; [ thunar-archive-plugin thunar-volman ]";
};
};
};
config = mkIf cfg.enable (
let package = pkgs.xfce.thunar.override { thunarPlugins = cfg.plugins; };
in {
environment.systemPackages = [
package
];
services.dbus.packages = [
package
pkgs.xfce.xfconf
];
systemd.packages = [
package
];
}
);
}

@ -97,6 +97,7 @@ with lib;
(mkRemovedOptionModule [ "services" "gogoclient" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "virtuoso" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "openfire" ] "The corresponding package was removed from nixpkgs.")
(mkRemovedOptionModule [ "services" "riak" ] "The corresponding package was removed from nixpkgs.")
# Do NOT add any option renames here, see top of the file
];

@ -22,16 +22,17 @@ in {
options.confinement.fullUnit = lib.mkOption {
type = types.bool;
default = false;
description = ''
description = lib.mdDoc ''
Whether to include the full closure of the systemd unit file into the
chroot, instead of just the dependencies for the executables.
<warning><para>While it may be tempting to just enable this option to
::: {.warning}
While it may be tempting to just enable this option to
make things work quickly, please be aware that this might add paths
to the closure of the chroot that you didn't anticipate. It's better
to use <option>confinement.packages</option> to <emphasis
role="strong">explicitly</emphasis> add additional store paths to the
chroot.</para></warning>
to use {option}`confinement.packages` to **explicitly** add additional store paths to the
chroot.
:::
'';
};

@ -45,7 +45,10 @@ in {
RootDirectory = "/run/navidrome";
ReadWritePaths = "";
BindReadOnlyPaths = [
# navidrome uses online services to download additional album metadata / covers
"${config.environment.etc."ssl/certs/ca-certificates.crt".source}:/etc/ssl/certs/ca-certificates.crt"
builtins.storeDir
"/etc"
] ++ lib.optional (cfg.settings ? MusicFolder) cfg.settings.MusicFolder;
CapabilityBoundingSet = "";
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];

@ -3,8 +3,14 @@
with lib;
let
cfg = config.services.k3s;
removeOption = config: instruction:
lib.mkRemovedOptionModule ([ "services" "k3s" ] ++ config) instruction;
in
{
imports = [
(removeOption [ "docker" ] "k3s docker option is no longer supported.")
];
# interface
options.services.k3s = {
enable = mkEnableOption "k3s";
@ -48,12 +54,6 @@ in
default = null;
};
docker = mkOption {
type = types.bool;
default = false;
description = "Use docker to run containers rather than the built-in containerd.";
};
extraFlags = mkOption {
description = "Extra flags to pass to the k3s command.";
type = types.str;
@ -88,14 +88,11 @@ in
}
];
virtualisation.docker = mkIf cfg.docker {
enable = mkDefault true;
};
environment.systemPackages = [ config.services.k3s.package ];
systemd.services.k3s = {
description = "k3s service";
after = [ "network.service" "firewall.service" ] ++ (optional cfg.docker "docker.service");
after = [ "network.service" "firewall.service" ];
wants = [ "network.service" "firewall.service" ];
wantedBy = [ "multi-user.target" ];
path = optional config.boot.zfs.enabled config.boot.zfs.package;
@ -113,8 +110,8 @@ in
ExecStart = concatStringsSep " \\\n " (
[
"${cfg.package}/bin/k3s ${cfg.role}"
] ++ (optional cfg.docker "--docker")
++ (optional (cfg.docker && config.systemd.enableUnifiedCgroupHierarchy) "--kubelet-arg=cgroup-driver=systemd")
]
++ (optional (config.systemd.enableUnifiedCgroupHierarchy) "--kubelet-arg=cgroup-driver=systemd")
++ (optional cfg.disableAgent "--disable-agent")
++ (optional (cfg.serverAddr != "") "--server ${cfg.serverAddr}")
++ (optional (cfg.token != "") "--token ${cfg.token}")

@ -4,11 +4,12 @@ let
inherit (lib)
concatStringsSep
flip
literalDocBook
literalMD
literalExpression
optionalAttrs
optionals
recursiveUpdate
mdDoc
mkEnableOption
mkIf
mkOption
@ -107,7 +108,7 @@ in
clusterName = mkOption {
type = types.str;
default = "Test Cluster";
description = ''
description = mdDoc ''
The name of the cluster.
This setting prevents nodes in one logical cluster from joining
another. All nodes in a cluster must have the same value.
@ -117,19 +118,19 @@ in
user = mkOption {
type = types.str;
default = defaultUser;
description = "Run Apache Cassandra under this user.";
description = mdDoc "Run Apache Cassandra under this user.";
};
group = mkOption {
type = types.str;
default = defaultUser;
description = "Run Apache Cassandra under this group.";
description = mdDoc "Run Apache Cassandra under this group.";
};
homeDir = mkOption {
type = types.path;
default = "/var/lib/cassandra";
description = ''
description = mdDoc ''
Home directory for Apache Cassandra.
'';
};
@ -139,7 +140,7 @@ in
default = pkgs.cassandra;
defaultText = literalExpression "pkgs.cassandra";
example = literalExpression "pkgs.cassandra_3_11";
description = ''
description = mdDoc ''
The Apache Cassandra package to use.
'';
};
@ -147,8 +148,8 @@ in
jvmOpts = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
Populate the JVM_OPT environment variable.
description = mdDoc ''
Populate the `JVM_OPT` environment variable.
'';
};
@ -156,20 +157,20 @@ in
type = types.nullOr types.str;
default = "127.0.0.1";
example = null;
description = ''
description = mdDoc ''
Address or interface to bind to and tell other Cassandra nodes
to connect to. You _must_ change this if you want multiple
nodes to be able to communicate!
Set listenAddress OR listenInterface, not both.
Set {option}`listenAddress` OR {option}`listenInterface`, not both.
Leaving it blank leaves it up to
InetAddress.getLocalHost(). This will always do the Right
Thing _if_ the node is properly configured (hostname, name
`InetAddress.getLocalHost()`. This will always do the "Right
Thing" _if_ the node is properly configured (hostname, name
resolution, etc), and the Right Thing is to use the address
associated with the hostname (it might not be).
Setting listen_address to 0.0.0.0 is always wrong.
Setting {option}`listenAddress` to `0.0.0.0` is always wrong.
'';
};
@ -177,8 +178,8 @@ in
type = types.nullOr types.str;
default = null;
example = "eth1";
description = ''
Set listenAddress OR listenInterface, not both. Interfaces
description = mdDoc ''
Set `listenAddress` OR `listenInterface`, not both. Interfaces
must correspond to a single address, IP aliasing is not
supported.
'';
@ -188,18 +189,18 @@ in
type = types.nullOr types.str;
default = "127.0.0.1";
example = null;
description = ''
description = mdDoc ''
The address or interface to bind the native transport server to.
Set rpcAddress OR rpcInterface, not both.
Set {option}`rpcAddress` OR {option}`rpcInterface`, not both.
Leaving rpcAddress blank has the same effect as on
listenAddress (i.e. it will be based on the configured hostname
Leaving {option}`rpcAddress` blank has the same effect as on
{option}`listenAddress` (i.e. it will be based on the configured hostname
of the node).
Note that unlike listenAddress, you can specify 0.0.0.0, but you
must also set extraConfig.broadcast_rpc_address to a value other
than 0.0.0.0.
Note that unlike {option}`listenAddress`, you can specify `"0.0.0.0"`, but you
must also set `extraConfig.broadcast_rpc_address` to a value other
than `"0.0.0.0"`.
For security reasons, you should not expose this port to the
internet. Firewall it if needed.
@ -210,8 +211,8 @@ in
type = types.nullOr types.str;
default = null;
example = "eth1";
description = ''
Set rpcAddress OR rpcInterface, not both. Interfaces must
description = mdDoc ''
Set {option}`rpcAddress` OR {option}`rpcInterface`, not both. Interfaces must
correspond to a single address, IP aliasing is not supported.
'';
};
@ -233,7 +234,7 @@ in
<logger name="com.thinkaurelius.thrift" level="ERROR"/>
</configuration>
'';
description = ''
description = mdDoc ''
XML logback configuration for cassandra
'';
};
@ -241,24 +242,24 @@ in
seedAddresses = mkOption {
type = types.listOf types.str;
default = [ "127.0.0.1" ];
description = ''
description = mdDoc ''
The addresses of hosts designated as contact points in the cluster. A
joining node contacts one of the nodes in the seeds list to learn the
topology of the ring.
Set to 127.0.0.1 for a single node cluster.
Set to `[ "127.0.0.1" ]` for a single node cluster.
'';
};
allowClients = mkOption {
type = types.bool;
default = true;
description = ''
description = mdDoc ''
Enables or disables the native transport server (CQL binary protocol).
This server uses the same address as the <literal>rpcAddress</literal>,
but the port it uses is not <literal>rpc_port</literal> but
<literal>native_transport_port</literal>. See the official Cassandra
This server uses the same address as the {option}`rpcAddress`,
but the port it uses is not `rpc_port` but
`native_transport_port`. See the official Cassandra
docs for more information on these variables and set them using
<literal>extraConfig</literal>.
{option}`extraConfig`.
'';
};
@ -269,8 +270,8 @@ in
{
commitlog_sync_batch_window_in_ms = 3;
};
description = ''
Extra options to be merged into cassandra.yaml as nix attribute set.
description = mdDoc ''
Extra options to be merged into {file}`cassandra.yaml` as nix attribute set.
'';
};
@ -278,8 +279,8 @@ in
type = types.lines;
default = "";
example = literalExpression ''"CLASSPATH=$CLASSPATH:''${extraJar}"'';
description = ''
Extra shell lines to be appended onto cassandra-env.sh.
description = mdDoc ''
Extra shell lines to be appended onto {file}`cassandra-env.sh`.
'';
};
@ -287,13 +288,13 @@ in
type = types.nullOr types.str;
default = "3w";
example = null;
description = ''
description = mdDoc ''
Set the interval how often full repairs are run, i.e.
<literal>nodetool repair --full</literal> is executed. See
https://cassandra.apache.org/doc/latest/operating/repair.html
{command}`nodetool repair --full` is executed. See
<https://cassandra.apache.org/doc/latest/operating/repair.html>
for more information.
Set to <literal>null</literal> to disable full repairs.
Set to `null` to disable full repairs.
'';
};
@ -301,7 +302,7 @@ in
type = types.listOf types.str;
default = [ ];
example = [ "--partitioner-range" ];
description = ''
description = mdDoc ''
Options passed through to the full repair command.
'';
};
@ -310,13 +311,13 @@ in
type = types.nullOr types.str;
default = "3d";
example = null;
description = ''
description = mdDoc ''
Set the interval how often incremental repairs are run, i.e.
<literal>nodetool repair</literal> is executed. See
https://cassandra.apache.org/doc/latest/operating/repair.html
{command}`nodetool repair` is executed. See
<https://cassandra.apache.org/doc/latest/operating/repair.html>
for more information.
Set to <literal>null</literal> to disable incremental repairs.
Set to `null` to disable incremental repairs.
'';
};
@ -324,7 +325,7 @@ in
type = types.listOf types.str;
default = [ ];
example = [ "--partitioner-range" ];
description = ''
description = mdDoc ''
Options passed through to the incremental repair command.
'';
};
@ -333,15 +334,15 @@ in
type = types.nullOr types.str;
default = null;
example = "4G";
description = ''
Must be left blank or set together with heapNewSize.
description = mdDoc ''
Must be left blank or set together with {option}`heapNewSize`.
If left blank a sensible value for the available amount of RAM and CPU
cores is calculated.
Override to set the amount of memory to allocate to the JVM at
start-up. For production use you may wish to adjust this for your
environment. MAX_HEAP_SIZE is the total amount of memory dedicated
to the Java heap. HEAP_NEWSIZE refers to the size of the young
environment. `MAX_HEAP_SIZE` is the total amount of memory dedicated
to the Java heap. `HEAP_NEWSIZE` refers to the size of the young
generation.
The main trade-off for the young generation is that the larger it
@ -354,21 +355,21 @@ in
type = types.nullOr types.str;
default = null;
example = "800M";
description = ''
Must be left blank or set together with heapNewSize.
description = mdDoc ''
Must be left blank or set together with {option}`heapNewSize`.
If left blank a sensible value for the available amount of RAM and CPU
cores is calculated.
Override to set the amount of memory to allocate to the JVM at
start-up. For production use you may wish to adjust this for your
environment. HEAP_NEWSIZE refers to the size of the young
environment. `HEAP_NEWSIZE` refers to the size of the young
generation.
The main trade-off for the young generation is that the larger it
is, the longer GC pause times will be. The shorter it is, the more
expensive GC will be (usually).
The example HEAP_NEWSIZE assumes a modern 8-core+ machine for decent pause
The example `HEAP_NEWSIZE` assumes a modern 8-core+ machine for decent pause
times. If in doubt, and if you do not particularly want to tweak, go with
100 MB per physical CPU core.
'';
@ -378,7 +379,7 @@ in
type = types.nullOr types.int;
default = null;
example = 4;
description = ''
description = mdDoc ''
Set this to control the amount of arenas per-thread in glibc.
'';
};
@ -386,19 +387,19 @@ in
remoteJmx = mkOption {
type = types.bool;
default = false;
description = ''
description = mdDoc ''
Cassandra ships with JMX accessible *only* from localhost.
To enable remote JMX connections set to true.
Be sure to also enable authentication and/or TLS.
See: https://wiki.apache.org/cassandra/JmxSecurity
See: <https://wiki.apache.org/cassandra/JmxSecurity>
'';
};
jmxPort = mkOption {
type = types.int;
default = 7199;
description = ''
description = mdDoc ''
Specifies the default port over which Cassandra will be available for
JMX connections.
For security reasons, you should not expose this port to the internet.
@ -408,11 +409,11 @@ in
jmxRoles = mkOption {
default = [ ];
description = ''
Roles that are allowed to access the JMX (e.g. nodetool)
BEWARE: The passwords will be stored world readable in the nix-store.
description = mdDoc ''
Roles that are allowed to access the JMX (e.g. {command}`nodetool`)
BEWARE: The passwords will be stored world readable in the nix store.
It's recommended to use your own protected file using
<literal>jmxRolesFile</literal>
{option}`jmxRolesFile`
Doesn't work in versions older than 3.11 because they don't like that
it's world readable.
@ -437,7 +438,7 @@ in
if versionAtLeast cfg.package.version "3.11"
then pkgs.writeText "jmx-roles-file" defaultJmxRolesFile
else null;
defaultText = literalDocBook ''generated configuration file if version is at least 3.11, otherwise <literal>null</literal>'';
defaultText = literalMD ''generated configuration file if version is at least 3.11, otherwise `null`'';
example = "/var/lib/cassandra/jmx.password";
description = ''
Specify your own jmx roles file.

@ -0,0 +1,148 @@
{ config, pkgs, lib, ... }:
with lib;
let
cfg = config.services.dgraph;
settingsFormat = pkgs.formats.json {};
configFile = settingsFormat.generate "config.json" cfg.settings;
dgraphWithNode = pkgs.runCommand "dgraph" {
nativeBuildInputs = [ pkgs.makeWrapper ];
}
''
mkdir -p $out/bin
makeWrapper ${cfg.package}/bin/dgraph $out/bin/dgraph \
--set PATH '${lib.makeBinPath [ pkgs.nodejs ]}:$PATH' \
'';
securityOptions = {
NoNewPrivileges = true;
AmbientCapabilities = "";
CapabilityBoundingSet = "";
DeviceAllow = "";
LockPersonality = true;
PrivateTmp = true;
PrivateDevices = true;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RemoveIPC = true;
RestrictNamespaces = true;
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" "AF_UNIX" ];
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallErrorNumber = "EPERM";
SystemCallFilter = [
"@system-service"
"~@cpu-emulation" "~@debug" "~@keyring" "~@memlock" "~@obsolete" "~@privileged" "~@setuid"
];
};
in
{
options = {
services.dgraph = {
enable = mkEnableOption "Dgraph native GraphQL database with a graph backend";
package = lib.mkPackageOption pkgs "dgraph" { };
settings = mkOption {
type = settingsFormat.type;
default = {};
description = ''
Contents of the dgraph config. For more details see https://dgraph.io/docs/deploy/config
'';
};
alpha = {
host = mkOption {
type = types.str;
default = "localhost";
description = ''
The host which dgraph alpha will be run on.
'';
};
port = mkOption {
type = types.port;
default = 7080;
description = ''
The port which to run dgraph alpha on.
'';
};
};
zero = {
host = mkOption {
type = types.str;
default = "localhost";
description = ''
The host which dgraph zero will be run on.
'';
};
port = mkOption {
type = types.port;
default = 5080;
description = ''
The port which to run dgraph zero on.
'';
};
};
};
};
config = mkIf cfg.enable {
services.dgraph.settings = {
badger.compression = mkDefault "zstd:3";
};
systemd.services.dgraph-zero = {
description = "Dgraph native GraphQL database with a graph backend. Zero controls node clustering";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
StateDirectory = "dgraph-zero";
WorkingDirectory = "/var/lib/dgraph-zero";
DynamicUser = true;
ExecStart = "${cfg.package}/bin/dgraph zero --my ${cfg.zero.host}:${toString cfg.zero.port}";
Restart = "on-failure";
} // securityOptions;
};
systemd.services.dgraph-alpha = {
description = "Dgraph native GraphQL database with a graph backend. Alpha serves data";
after = [ "network.target" "dgraph-zero.service" ];
requires = [ "dgraph-zero.service" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
StateDirectory = "dgraph-alpha";
WorkingDirectory = "/var/lib/dgraph-alpha";
DynamicUser = true;
ExecStart = "${dgraphWithNode}/bin/dgraph alpha --config ${configFile} --my ${cfg.alpha.host}:${toString cfg.alpha.port} --zero ${cfg.zero.host}:${toString cfg.zero.port}";
ExecStop = ''
${pkgs.curl}/bin/curl --data "mutation { shutdown { response { message code } } }" \
--header 'Content-Type: application/graphql' \
-X POST \
http://localhost:8080/admin
'';
Restart = "on-failure";
} // securityOptions;
};
};
meta.maintainers = with lib.maintainers; [ happysalada ];
}

@ -1,162 +0,0 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.riak;
in
{
###### interface
options = {
services.riak = {
enable = mkEnableOption "riak";
package = mkOption {
type = types.package;
default = pkgs.riak;
defaultText = literalExpression "pkgs.riak";
description = ''
Riak package to use.
'';
};
nodeName = mkOption {
type = types.str;
default = "riak@127.0.0.1";
description = ''
Name of the Erlang node.
'';
};
distributedCookie = mkOption {
type = types.str;
default = "riak";
description = ''
Cookie for distributed node communication. All nodes in the
same cluster should use the same cookie or they will not be able to
communicate.
'';
};
dataDir = mkOption {
type = types.path;
default = "/var/db/riak";
description = ''
Data directory for Riak.
'';
};
logDir = mkOption {
type = types.path;
default = "/var/log/riak";
description = ''
Log directory for Riak.
'';
};
extraConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional text to be appended to <filename>riak.conf</filename>.
'';
};
extraAdvancedConfig = mkOption {
type = types.lines;
default = "";
description = ''
Additional text to be appended to <filename>advanced.config</filename>.
'';
};
};
};
###### implementation
config = mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
environment.etc."riak/riak.conf".text = ''
nodename = ${cfg.nodeName}
distributed_cookie = ${cfg.distributedCookie}
platform_log_dir = ${cfg.logDir}
platform_etc_dir = /etc/riak
platform_data_dir = ${cfg.dataDir}
${cfg.extraConfig}
'';
environment.etc."riak/advanced.config".text = ''
${cfg.extraAdvancedConfig}
'';
users.users.riak = {
name = "riak";
uid = config.ids.uids.riak;
group = "riak";
description = "Riak server user";
};
users.groups.riak.gid = config.ids.gids.riak;
systemd.services.riak = {
description = "Riak Server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
path = [
pkgs.util-linux # for `logger`
pkgs.bash
];
environment.HOME = "${cfg.dataDir}";
environment.RIAK_DATA_DIR = "${cfg.dataDir}";
environment.RIAK_LOG_DIR = "${cfg.logDir}";
environment.RIAK_ETC_DIR = "/etc/riak";
preStart = ''
if ! test -e ${cfg.logDir}; then
mkdir -m 0755 -p ${cfg.logDir}
chown -R riak ${cfg.logDir}
fi
if ! test -e ${cfg.dataDir}; then
mkdir -m 0700 -p ${cfg.dataDir}
chown -R riak ${cfg.dataDir}
fi
'';
serviceConfig = {
ExecStart = "${cfg.package}/bin/riak console";
ExecStop = "${cfg.package}/bin/riak stop";
StandardInput = "tty";
User = "riak";
Group = "riak";
PermissionsStartOnly = true;
# Give Riak a decent amount of time to clean up.
TimeoutStopSec = 120;
LimitNOFILE = 65536;
};
unitConfig.RequiresMountsFor = [
"${cfg.dataDir}"
"${cfg.logDir}"
"/etc/riak"
];
};
};
}

@ -234,7 +234,7 @@ in {
environment.etc."pipewire/pipewire.conf" = {
source = json.generate "pipewire.conf" configs.pipewire;
};
environment.etc."pipewire/pipewire-pulse.conf" = {
environment.etc."pipewire/pipewire-pulse.conf" = mkIf cfg.pulse.enable {
source = json.generate "pipewire-pulse.conf" configs.pipewire-pulse;
};
@ -260,5 +260,8 @@ in {
# https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/464#note_723554
systemd.services.pipewire.environment."PIPEWIRE_LINK_PASSIVE" = "1";
systemd.user.services.pipewire.environment."PIPEWIRE_LINK_PASSIVE" = "1";
# pipewire-pulse default config expects pactl to be in PATH
systemd.user.services.pipewire-pulse.path = lib.mkIf cfg.pulse.enable [ pkgs.pulseaudio ];
};
}

@ -37,11 +37,19 @@ in
environment.systemPackages = [ cfg.package ];
environment.etc."wireplumber/main.lua.d/80-nixos.lua" = lib.mkIf (!pwUsedForAudio) {
text = ''
text = ''
-- Pipewire is not used for audio, so prevent it from grabbing audio devices
alsa_monitor.enable = function() end
'';
};
environment.etc."wireplumber/main.lua.d/80-systemwide.lua" = lib.mkIf config.services.pipewire.systemWide {
text = ''
-- When running system-wide, these settings need to be disabled (they
-- use functions that aren't available on the system dbus).
alsa_monitor.properties["alsa.reserve"] = false
default_access.properties["enable-flatpak-portal"] = false
'';
};
systemd.packages = [ cfg.package ];
@ -50,5 +58,10 @@ in
systemd.services.wireplumber.wantedBy = [ "pipewire.service" ];
systemd.user.services.wireplumber.wantedBy = [ "pipewire.service" ];
systemd.services.wireplumber.environment = lib.mkIf config.services.pipewire.systemWide {
# Force wireplumber to use system dbus.
DBUS_SESSION_BUS_ADDRESS = "unix:path=/run/dbus/system_bus_socket";
};
};
}

@ -0,0 +1,58 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.hardware.argonone;
in
{
options.services.hardware.argonone = {
enable = lib.mkEnableOption "the driver for Argon One Raspberry Pi case fan and power button";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.argononed;
defaultText = "pkgs.argononed";
description = ''
The package implementing the Argon One driver
'';
};
};
config = lib.mkIf cfg.enable {
hardware.i2c.enable = true;
hardware.deviceTree.overlays = [
{
name = "argononed";
dtboFile = "${cfg.package}/boot/overlays/argonone.dtbo";
}
{
name = "i2c1-okay-overlay";
dtsText = ''
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
fragment@0 {
target = <&i2c1>;
__overlay__ {
status = "okay";
};
};
};
'';
}
];
environment.systemPackages = [ cfg.package ];
systemd.services.argononed = {
description = "Argon One Raspberry Pi case Daemon Service";
wantedBy = [ "multi-user.target" ];
serviceConfig = {
Type = "forking";
ExecStart = "${cfg.package}/bin/argononed";
PIDFile = "/run/argononed.pid";
Restart = "on-failure";
};
};
};
meta.maintainers = with lib.maintainers; [ misterio77 ];
}

@ -369,6 +369,17 @@ in {
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.config.http.server_port ];
# symlink the configuration to /etc/home-assistant
environment.etc = lib.mkMerge [
(lib.mkIf (cfg.config != null && !cfg.configWritable) {
"home-assistant/configuration.yaml".source = configFile;
})
(lib.mkIf (cfg.lovelaceConfig != null && !cfg.lovelaceConfigWritable) {
"home-assistant/ui-lovelace.yaml".source = lovelaceConfigFile;
})
];
systemd.services.home-assistant = {
description = "Home Assistant";
after = [
@ -378,18 +389,22 @@ in {
"mysql.service"
"postgresql.service"
];
reloadTriggers = [
configFile
lovelaceConfigFile
];
preStart = let
copyConfig = if cfg.configWritable then ''
cp --no-preserve=mode ${configFile} "${cfg.configDir}/configuration.yaml"
'' else ''
rm -f "${cfg.configDir}/configuration.yaml"
ln -s ${configFile} "${cfg.configDir}/configuration.yaml"
ln -s /etc/home-assistant/configuration.yaml "${cfg.configDir}/configuration.yaml"
'';
copyLovelaceConfig = if cfg.lovelaceConfigWritable then ''
cp --no-preserve=mode ${lovelaceConfigFile} "${cfg.configDir}/ui-lovelace.yaml"
'' else ''
rm -f "${cfg.configDir}/ui-lovelace.yaml"
ln -s ${lovelaceConfigFile} "${cfg.configDir}/ui-lovelace.yaml"
ln -s /etc/home-assistant/ui-lovelace.yaml "${cfg.configDir}/ui-lovelace.yaml"
'';
in
(optionalString (cfg.config != null) copyConfig) +

@ -193,7 +193,7 @@ let
};
mailOption =
if foldr (n: a: a || n ? mail) false (attrValues cfg.settings)
if foldr (n: a: a || (n.mail or false) != false) false (attrValues cfg.settings)
then "--mail=${pkgs.mailutils}/bin/mail"
else "";
in

@ -0,0 +1,162 @@
{ config, pkgs, lib, ... }:
let
cfg = config.services.schleuder;
settingsFormat = pkgs.formats.yaml { };
postfixMap = entries: lib.concatStringsSep "\n" (lib.mapAttrsToList (name: value: "${name} ${value}") entries);
writePostfixMap = name: entries: pkgs.writeText name (postfixMap entries);
configScript = pkgs.writeScript "schleuder-cfg" ''
#!${pkgs.runtimeShell}
set -exuo pipefail
umask 0077
${pkgs.yq}/bin/yq \
--slurpfile overrides <(${pkgs.yq}/bin/yq . <${lib.escapeShellArg cfg.extraSettingsFile}) \
< ${settingsFormat.generate "schleuder.yml" cfg.settings} \
'. * $overrides[0]' \
> /etc/schleuder/schleuder.yml
chown schleuder: /etc/schleuder/schleuder.yml
'';
in
{
options.services.schleuder = {
enable = lib.mkEnableOption "Schleuder secure remailer";
enablePostfix = lib.mkEnableOption "automatic postfix integration" // { default = true; };
lists = lib.mkOption {
description = ''
List of list addresses that should be handled by Schleuder.
Note that this is only handled by the postfix integration, and
the setup of the lists, their members and their keys has to be
performed separately via schleuder's API, using a tool such as
schleuder-cli.
'';
type = lib.types.listOf lib.types.str;
default = [ ];
example = [ "widget-team@example.com" "security@example.com" ];
};
/* maybe one day....
domains = lib.mkOption {
description = "Domains for which all mail should be handled by Schleuder.";
type = lib.types.listOf lib.types.str;
default = [];
example = ["securelists.example.com"];
};
*/
settings = lib.mkOption {
description = ''
Settings for schleuder.yml.
Check the <link xlink:href="https://0xacab.org/schleuder/schleuder/blob/master/etc/schleuder.yml">example configuration</link> for possible values.
'';
type = lib.types.submodule {
freeformType = settingsFormat.type;
options.keyserver = lib.mkOption {
type = lib.types.str;
description = ''
Key server from which to fetch and update keys.
Note that NixOS uses a different default from upstream, since the upstream default sks-keyservers.net is deprecated.
'';
default = "keys.openpgp.org";
};
};
default = { };
};
extraSettingsFile = lib.mkOption {
description = "YAML file to merge into the schleuder config at runtime. This can be used for secrets such as API keys.";
type = lib.types.nullOr lib.types.path;
default = null;
};
listDefaults = lib.mkOption {
description = ''
Default settings for lists (list-defaults.yml).
Check the <link xlink:href="https://0xacab.org/schleuder/schleuder/-/blob/master/etc/list-defaults.yml">example configuration</link> for possible values.
'';
type = settingsFormat.type;
default = { };
};
};
config = lib.mkIf cfg.enable {
assertions = [
{
assertion = !(cfg.settings.api ? valid_api_keys);
message = ''
services.schleuder.settings.api.valid_api_keys is set. Defining API keys via NixOS config results in them being copied to the world-readable Nix store. Please use the extraSettingsFile option to store API keys in a non-public location.
'';
}
{
assertion = !(lib.any (db: db ? password) (lib.attrValues cfg.settings.database or {}));
message = ''
A password is defined for at least one database in services.schleuder.settings.database. Defining passwords via NixOS config results in them being copied to the world-readable Nix store. Please use the extraSettingsFile option to store database passwords in a non-public location.
'';
}
];
users.users.schleuder.isSystemUser = true;
users.users.schleuder.group = "schleuder";
users.groups.schleuder = {};
environment.systemPackages = [
pkgs.schleuder-cli
];
services.postfix = lib.mkIf cfg.enablePostfix {
extraMasterConf = ''
schleuder unix - n n - - pipe
flags=DRhu user=schleuder argv=/${pkgs.schleuder}/bin/schleuder work ''${recipient}
'';
transport = lib.mkIf (cfg.lists != [ ]) (postfixMap (lib.genAttrs cfg.lists (_: "schleuder:")));
extraConfig = ''
schleuder_destination_recipient_limit = 1
'';
# review: does this make sense?
localRecipients = lib.mkIf (cfg.lists != [ ]) cfg.lists;
};
systemd.services = let commonServiceConfig = {
# We would have liked to use DynamicUser, but since the default
# database is SQLite and lives in StateDirectory, and that same
# database needs to be readable from the postfix service, this
# isn't trivial to do.
User = "schleuder";
StateDirectory = "schleuder";
StateDirectoryMode = "0700";
}; in
{
schleuder-init = {
serviceConfig = commonServiceConfig // {
ExecStartPre = lib.mkIf (cfg.extraSettingsFile != null) [
"+${configScript}"
];
ExecStart = [ "${pkgs.schleuder}/bin/schleuder install" ];
Type = "oneshot";
};
};
schleuder-api-daemon = {
after = [ "local-fs.target" "network.target" "schleuder-init.service" ];
wantedBy = [ "multi-user.target" ];
requires = [ "schleuder-init.service" ];
serviceConfig = commonServiceConfig // {
ExecStart = [ "${pkgs.schleuder}/bin/schleuder-api-daemon" ];
};
};
schleuder-weekly-key-maintenance = {
after = [ "local-fs.target" "network.target" ];
startAt = "weekly";
serviceConfig = commonServiceConfig // {
ExecStart = [
"${pkgs.schleuder}/bin/schleuder refresh_keys"
"${pkgs.schleuder}/bin/schleuder check_keys"
];
};
};
};
environment.etc."schleuder/schleuder.yml" = lib.mkIf (cfg.extraSettingsFile == null) {
source = settingsFormat.generate "schleuder.yml" cfg.settings;
};
environment.etc."schleuder/list-defaults.yml".source = settingsFormat.generate "list-defaults.yml" cfg.listDefaults;
services.schleuder = {
#lists_dir = "/var/lib/schleuder.lists";
settings.filters_dir = lib.mkDefault "/var/lib/schleuder/filters";
settings.keyword_handlers_dir = lib.mkDefault "/var/lib/schleuder/keyword_handlers";
};
};
}

@ -153,6 +153,9 @@ in {
systemd.services.matrix-appservice-irc = {
description = "Matrix-IRC bridge";
before = [ "matrix-synapse.service" ]; # So the registration can be used by Synapse
after = lib.optionals (cfg.settings.database.engine == "postgres") [
"postgresql.service"
];
wantedBy = [ "multi-user.target" ];
preStart = ''

@ -191,12 +191,12 @@ in {
settings = mkOption {
default = {};
description = ''
description = mdDoc ''
The primary synapse configuration. See the
<link xlink:href="https://github.com/matrix-org/synapse/blob/v${cfg.package.version}/docs/sample_config.yaml">sample configuration</link>
[sample configuration](https://github.com/matrix-org/synapse/blob/v${cfg.package.version}/docs/sample_config.yaml)
for possible values.
Secrets should be passed in by using the <literal>extraConfigFiles</literal> option.
Secrets should be passed in by using the `extraConfigFiles` option.
'';
type = with types; submodule {
freeformType = format.type;
@ -230,23 +230,23 @@ in {
registration_shared_secret = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
description = mdDoc ''
If set, allows registration by anyone who also has the shared
secret, even if registration is otherwise disabled.
Secrets should be passed in via <literal>extraConfigFiles</literal>!
Secrets should be passed in via `extraConfigFiles`!
'';
};
macaroon_secret_key = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
description = mdDoc ''
Secret key for authentication tokens. If none is specified,
the registration_shared_secret is used, if one is given; otherwise,
a secret key is derived from the signing key.
Secrets should be passed in via <literal>extraConfigFiles</literal>!
Secrets should be passed in via `extraConfigFiles`!
'';
};
@ -620,10 +620,10 @@ in {
example = literalExpression ''
config.services.coturn.static-auth-secret
'';
description = ''
description = mdDoc ''
The shared secret used to compute passwords for the TURN server.
Secrets should be passed in via <literal>extraConfigFiles</literal>!
Secrets should be passed in via `extraConfigFiles`!
'';
};

@ -2,6 +2,7 @@
let
cfg = config.services.geoipupdate;
inherit (builtins) isAttrs isString isInt isList typeOf hashString;
in
{
imports = [
@ -27,11 +28,30 @@ in
};
settings = lib.mkOption {
example = lib.literalExpression ''
{
AccountID = 200001;
DatabaseDirectory = "/var/lib/GeoIP";
LicenseKey = { _secret = "/run/keys/maxmind_license_key"; };
Proxy = "10.0.0.10:8888";
ProxyUserPassword = { _secret = "/run/keys/proxy_pass"; };
}
'';
description = ''
<productname>geoipupdate</productname> configuration
options. See
<link xlink:href="https://github.com/maxmind/geoipupdate/blob/main/doc/GeoIP.conf.md" />
for a full list of available options.
Settings containing secret data should be set to an
attribute set containing the attribute
<literal>_secret</literal> - a string pointing to a file
containing the value the option should be set to. See the
example to get a better picture of this: in the resulting
<filename>GeoIP.conf</filename> file, the
<literal>ProxyUserPassword</literal> key will be set to the
contents of the
<filename>/run/keys/proxy_pass</filename> file.
'';
type = lib.types.submodule {
freeformType =
@ -65,11 +85,18 @@ in
};
LicenseKey = lib.mkOption {
type = lib.types.path;
type = with lib.types; either path (attrsOf path);
description = ''
A file containing the <productname>MaxMind</productname>
license key.
A file containing the
<productname>MaxMind</productname> license key.
Always handled as a secret whether the value is
wrapped in a <literal>{ _secret = ...; }</literal>
attrset or not (refer to <xref
linkend="opt-services.geoipupdate.settings" /> for
details).
'';
apply = x: if isAttrs x then x else { _secret = x; };
};
DatabaseDirectory = lib.mkOption {
@ -102,6 +129,9 @@ in
systemd.services.geoipupdate-create-db-dir = {
serviceConfig.Type = "oneshot";
script = ''
set -o errexit -o pipefail -o nounset -o errtrace
shopt -s inherit_errexit
mkdir -p ${cfg.settings.DatabaseDirectory}
chmod 0755 ${cfg.settings.DatabaseDirectory}
'';
@ -115,32 +145,41 @@ in
"network-online.target"
"nss-lookup.target"
];
path = [ pkgs.replace-secret ];
wants = [ "network-online.target" ];
startAt = cfg.interval;
serviceConfig = {
ExecStartPre =
let
isSecret = v: isAttrs v && v ? _secret && isString v._secret;
geoipupdateKeyValue = lib.generators.toKeyValue {
mkKeyValue = lib.flip lib.generators.mkKeyValueDefault " " rec {
mkValueString = v: with builtins;
mkValueString = v:
if isInt v then toString v
else if isString v then v
else if true == v then "1"
else if false == v then "0"
else if isList v then lib.concatMapStringsSep " " mkValueString v
else if isSecret v then hashString "sha256" v._secret
else throw "unsupported type ${typeOf v}: ${(lib.generators.toPretty {}) v}";
};
};
secretPaths = lib.catAttrs "_secret" (lib.collect isSecret cfg.settings);
mkSecretReplacement = file: ''
replace-secret ${lib.escapeShellArgs [ (hashString "sha256" file) file "/run/geoipupdate/GeoIP.conf" ]}
'';
secretReplacements = lib.concatMapStrings mkSecretReplacement secretPaths;
geoipupdateConf = pkgs.writeText "geoipupdate.conf" (geoipupdateKeyValue cfg.settings);
script = ''
set -o errexit -o pipefail -o nounset -o errtrace
shopt -s inherit_errexit
chown geoip "${cfg.settings.DatabaseDirectory}"
cp ${geoipupdateConf} /run/geoipupdate/GeoIP.conf
${pkgs.replace-secret}/bin/replace-secret '${cfg.settings.LicenseKey}' \
'${cfg.settings.LicenseKey}' \
/run/geoipupdate/GeoIP.conf
${secretReplacements}
'';
in
"+${pkgs.writeShellScript "start-pre-full-privileges" script}";

@ -13,6 +13,22 @@ let
else
pkgs.postgresql_12;
# Git 2.36.1 seemingly contains a commit-graph related bug which is
# easily triggered through GitLab, so we downgrade it to 2.35.x
# until this issue is solved. See
# https://gitlab.com/gitlab-org/gitlab/-/issues/360783#note_992870101.
gitPackage =
let
version = "2.35.3";
in
pkgs.git.overrideAttrs (oldAttrs: rec {
inherit version;
src = pkgs.fetchurl {
url = "https://www.kernel.org/pub/software/scm/git/git-${version}.tar.xz";
sha256 = "sha256-FenbT5vy7Z//MMtioAxcfAkBAV9asEjNtOiwTd7gD6I=";
};
});
gitlabSocket = "${cfg.statePath}/tmp/sockets/gitlab.socket";
gitalySocket = "${cfg.statePath}/tmp/sockets/gitaly.socket";
pathUrlQuote = url: replaceStrings ["/"] ["%2F"] url;
@ -41,7 +57,7 @@ let
prometheus_listen_addr = "localhost:9236"
[git]
bin_path = "${pkgs.git}/bin/git"
bin_path = "${gitPackage}/bin/git"
[gitaly-ruby]
dir = "${cfg.packages.gitaly.ruby}"
@ -137,7 +153,7 @@ let
};
workhorse.secret_file = "${cfg.statePath}/.gitlab_workhorse_secret";
gitlab_kas.secret_file = "${cfg.statePath}/.gitlab_kas_secret";
git.bin_path = "git";
git.bin_path = "${gitPackage}/bin/git";
monitoring = {
ip_whitelist = [ "127.0.0.0/8" "::1/128" ];
sidekiq_exporter = {
@ -1275,7 +1291,7 @@ in {
});
path = with pkgs; [
postgresqlPackage
git
gitPackage
ruby
openssh
nodejs
@ -1306,7 +1322,7 @@ in {
path = with pkgs; [
openssh
procps # See https://gitlab.com/gitlab-org/gitaly/issues/1562
git
gitPackage
cfg.packages.gitaly.rubyEnv
cfg.packages.gitaly.rubyEnv.wrappedRuby
gzip
@ -1351,7 +1367,7 @@ in {
partOf = [ "gitlab.target" ];
path = with pkgs; [
exiftool
git
gitPackage
gnutar
gzip
openssh
@ -1412,7 +1428,7 @@ in {
environment = gitlabEnv;
path = with pkgs; [
postgresqlPackage
git
gitPackage
openssh
nodejs
procps

@ -47,7 +47,7 @@ in
user-icons = mkOption {
type = types.nullOr (types.enum [ "gravatar" "identicon" ]);
default = null;
description = "User icons for history view";
description = "Enable specific user icons for history view";
};
emoji = mkOption {
@ -68,6 +68,12 @@ in
description = "Disable editing pages";
};
local-time = mkOption {
type = types.bool;
default = false;
description = "Use the browser's local timezone instead of the server's for displaying dates.";
};
branch = mkOption {
type = types.str;
default = "master";
@ -123,6 +129,7 @@ in
${optionalString cfg.emoji "--emoji"} \
${optionalString cfg.h1-title "--h1-title"} \
${optionalString cfg.no-edit "--no-edit"} \
${optionalString cfg.local-time "--local-time"} \
${optionalString (cfg.allowUploads != null) "--allow-uploads ${cfg.allowUploads}"} \
${optionalString (cfg.user-icons != null) "--user-icons ${cfg.user-icons}"} \
${cfg.stateDir}

@ -83,7 +83,7 @@ let
};
in
{
meta.maintainers = with maintainers; [ earvstedt Flakebi ];
meta.maintainers = with maintainers; [ erikarvstedt Flakebi ];
imports = [
(mkRenamedOptionModule [ "services" "paperless-ng" ] [ "services" "paperless" ])

@ -11,6 +11,14 @@ in
services.radarr = {
enable = mkEnableOption "Radarr";
package = mkOption {
description = "Radarr package to use";
default = pkgs.radarr;
defaultText = literalExpression "pkgs.radarr";
example = literalExpression "pkgs.radarr";
type = types.package;
};
dataDir = mkOption {
type = types.str;
default = "/var/lib/radarr/.config/Radarr";
@ -51,7 +59,7 @@ in
Type = "simple";
User = cfg.user;
Group = cfg.group;
ExecStart = "${pkgs.radarr}/bin/Radarr -nobrowser -data='${cfg.dataDir}'";
ExecStart = "${cfg.package}/bin/Radarr -nobrowser -data='${cfg.dataDir}'";
Restart = "on-failure";
};
};

@ -0,0 +1,143 @@
{ lib, pkgs, config, generators, ... }:
with lib;
let
cfg = config.services.grafana-agent;
settingsFormat = pkgs.formats.yaml { };
configFile = settingsFormat.generate "grafana-agent.yaml" cfg.settings;
in
{
meta = {
maintainers = with maintainers; [ flokli zimbatm ];
};
options.services.grafana-agent = {
enable = mkEnableOption "grafana-agent";
package = mkOption {
type = types.package;
default = pkgs.grafana-agent;
defaultText = "pkgs.grafana-agent";
description = "The grafana-agent package to use.";
};
credentials = mkOption {
description = ''
Credentials to load at service startup. Keys that are UPPER_SNAKE will be loaded as env vars. Values are absolute paths to the credentials.
'';
type = types.attrsOf types.str;
default = { };
example = {
logs_remote_write_password = "/run/keys/grafana_agent_logs_remote_write_password";
LOGS_REMOTE_WRITE_URL = "/run/keys/grafana_agent_logs_remote_write_url";
LOGS_REMOTE_WRITE_USERNAME = "/run/keys/grafana_agent_logs_remote_write_username";
metrics_remote_write_password = "/run/keys/grafana_agent_metrics_remote_write_password";
METRICS_REMOTE_WRITE_URL = "/run/keys/grafana_agent_metrics_remote_write_url";
METRICS_REMOTE_WRITE_USERNAME = "/run/keys/grafana_agent_metrics_remote_write_username";
};
};
settings = mkOption {
description = ''
Configuration for <package>grafana-agent</package>.
See https://grafana.com/docs/agent/latest/configuration/
'';
type = types.submodule {
freeformType = settingsFormat.type;
};
default = {
metrics = {
wal_directory = "\${STATE_DIRECTORY}";
global.scrape_interval = "5s";
};
integrations = {
agent.enabled = true;
agent.scrape_integration = true;
node_exporter.enabled = true;
replace_instance_label = true;
};
};
example = {
metrics.global.remote_write = [{
url = "\${METRICS_REMOTE_WRITE_URL}";
basic_auth.username = "\${METRICS_REMOTE_WRITE_USERNAME}";
basic_auth.password_file = "\${CREDENTIALS_DIRECTORY}/metrics_remote_write_password";
}];
logs.configs = [{
name = "default";
scrape_configs = [
{
job_name = "journal";
journal = {
max_age = "12h";
labels.job = "systemd-journal";
};
relabel_configs = [
{
source_labels = [ "__journal__systemd_unit" ];
target_label = "systemd_unit";
}
{
source_labels = [ "__journal__hostname" ];
target_label = "nodename";
}
{
source_labels = [ "__journal_syslog_identifier" ];
target_label = "syslog_identifier";
}
];
}
];
positions.filename = "\${STATE_DIRECTORY}/loki_positions.yaml";
clients = [{
url = "\${LOGS_REMOTE_WRITE_URL}";
basic_auth.username = "\${LOGS_REMOTE_WRITE_USERNAME}";
basic_auth.password_file = "\${CREDENTIALS_DIRECTORY}/logs_remote_write_password";
}];
}];
};
};
};
config = mkIf cfg.enable {
systemd.services.grafana-agent = {
wantedBy = [ "multi-user.target" ];
script = ''
set -euo pipefail
shopt -u nullglob
# Load all credentials into env if they are in UPPER_SNAKE form.
if [[ -n "''${CREDENTIALS_DIRECTORY:-}" ]]; then
for file in "$CREDENTIALS_DIRECTORY"/*; do
key=$(basename "$file")
if [[ $key =~ ^[A-Z0-9_]+$ ]]; then
echo "Environ $key"
export "$key=$(< "$file")"
fi
done
fi
# We can't use Environment=HOSTNAME=%H, as it doesn't include the domain part.
export HOSTNAME=$(< /proc/sys/kernel/hostname)
exec ${cfg.package}/bin/agent -config.expand-env -config.file ${configFile}
'';
serviceConfig = {
Restart = "always";
DynamicUser = true;
RestartSec = 2;
SupplementaryGroups = [
# allow to read the systemd journal for loki log forwarding
"systemd-journal"
];
StateDirectory = "grafana-agent";
LoadCredential = lib.mapAttrsToList (key: value: "${key}:${value}") cfg.credentials;
Type = "simple";
};
};
};
}

@ -3,7 +3,19 @@
let
cfg = config.services.parsedmarc;
opt = options.services.parsedmarc;
ini = pkgs.formats.ini {};
isSecret = v: isAttrs v && v ? _secret && isString v._secret;
ini = pkgs.formats.ini {
mkKeyValue = lib.flip lib.generators.mkKeyValueDefault "=" rec {
mkValueString = v:
if isInt v then toString v
else if isString v then v
else if true == v then "True"
else if false == v then "False"
else if isSecret v then hashString "sha256" v._secret
else throw "unsupported type ${typeOf v}: ${(lib.generators.toPretty {}) v}";
};
};
inherit (builtins) elem isAttrs isString isInt isList typeOf hashString;
in
{
options.services.parsedmarc = {
@ -107,11 +119,35 @@ in
};
settings = lib.mkOption {
example = lib.literalExpression ''
{
imap = {
host = "imap.example.com";
user = "alice@example.com";
password = { _secret = "/run/keys/imap_password" };
watch = true;
};
splunk_hec = {
url = "https://splunkhec.example.com";
token = { _secret = "/run/keys/splunk_token" };
index = "email";
};
}
'';
description = ''
Configuration parameters to set in
<filename>parsedmarc.ini</filename>. For a full list of
available parameters, see
<link xlink:href="https://domainaware.github.io/parsedmarc/#configuration-file" />.
Settings containing secret data should be set to an attribute
set containing the attribute <literal>_secret</literal> - a
string pointing to a file containing the value the option
should be set to. See the example to get a better picture of
this: in the resulting <filename>parsedmarc.ini</filename>
file, the <literal>splunk_hec.token</literal> key will be set
to the contents of the
<filename>/run/keys/splunk_token</filename> file.
'';
type = lib.types.submodule {
@ -170,11 +206,18 @@ in
};
password = lib.mkOption {
type = with lib.types; nullOr path;
type = with lib.types; nullOr (either path (attrsOf path));
default = null;
description = ''
The path to a file containing the IMAP server password.
The IMAP server password.
Always handled as a secret whether the value is
wrapped in a <literal>{ _secret = ...; }</literal>
attrset or not (refer to <xref
linkend="opt-services.parsedmarc.settings" /> for
details).
'';
apply = x: if isAttrs x || x == null then x else { _secret = x; };
};
watch = lib.mkOption {
@ -228,11 +271,18 @@ in
};
password = lib.mkOption {
type = with lib.types; nullOr path;
type = with lib.types; nullOr (either path (attrsOf path));
default = null;
description = ''
The path to a file containing the SMTP server password.
The SMTP server password.
Always handled as a secret whether the value is
wrapped in a <literal>{ _secret = ...; }</literal>
attrset or not (refer to <xref
linkend="opt-services.parsedmarc.settings" /> for
details).
'';
apply = x: if isAttrs x || x == null then x else { _secret = x; };
};
from = lib.mkOption {
@ -274,12 +324,19 @@ in
};
password = lib.mkOption {
type = with lib.types; nullOr path;
type = with lib.types; nullOr (either path (attrsOf path));
default = null;
description = ''
The path to a file containing the password to use when
connecting to Elasticsearch, if required.
The password to use when connecting to Elasticsearch,
if required.
Always handled as a secret whether the value is
wrapped in a <literal>{ _secret = ...; }</literal>
attrset or not (refer to <xref
linkend="opt-services.parsedmarc.settings" /> for
details).
'';
apply = x: if isAttrs x || x == null then x else { _secret = x; };
};
ssl = lib.mkOption {
@ -299,63 +356,6 @@ in
'';
};
};
kafka = {
hosts = lib.mkOption {
default = [];
type = with lib.types; listOf str;
apply = x: if x == [] then null else lib.concatStringsSep "," x;
description = ''
A list of Apache Kafka hosts to publish parsed reports
to.
'';
};
user = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
description = ''
Username to use when connecting to Kafka, if
required.
'';
};
password = lib.mkOption {
type = with lib.types; nullOr path;
default = null;
description = ''
The path to a file containing the password to use when
connecting to Kafka, if required.
'';
};
ssl = lib.mkOption {
type = with lib.types; nullOr bool;
default = null;
description = ''
Whether to use an encrypted SSL/TLS connection.
'';
};
aggregate_topic = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "aggregate";
description = ''
The Kafka topic to publish aggregate reports on.
'';
};
forensic_topic = lib.mkOption {
type = with lib.types; nullOr str;
default = null;
example = "forensic";
description = ''
The Kafka topic to publish forensic reports on.
'';
};
};
};
};
@ -404,21 +404,14 @@ in
enable = cfg.provision.grafana.datasource || cfg.provision.grafana.dashboard;
datasources =
let
pkgVer = lib.getVersion config.services.elasticsearch.package;
esVersion =
if lib.versionOlder pkgVer "7" then
"60"
else if lib.versionOlder pkgVer "8" then
"70"
else
throw "When provisioning parsedmarc grafana datasources: unknown Elasticsearch version.";
esVersion = lib.getVersion config.services.elasticsearch.package;
in
lib.mkIf cfg.provision.grafana.datasource [
{
name = "dmarc-ag";
type = "elasticsearch";
access = "proxy";
url = "localhost:9200";
url = "http://localhost:9200";
jsonData = {
timeField = "date_range";
inherit esVersion;
@ -428,7 +421,7 @@ in
name = "dmarc-fo";
type = "elasticsearch";
access = "proxy";
url = "localhost:9200";
url = "http://localhost:9200";
jsonData = {
timeField = "date_range";
inherit esVersion;
@ -467,12 +460,17 @@ in
# lists, empty attrsets and null. This makes it possible to
# list interesting options in `settings` without them always
# ending up in the resulting config.
filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! builtins.elem v [ null [] {} ])) cfg.settings;
filteredConfig = lib.converge (lib.filterAttrsRecursive (_: v: ! elem v [ null [] {} ])) cfg.settings;
# Extract secrets (attributes set to an attrset with a
# "_secret" key) from the settings and generate the commands
# to run to perform the secret replacements.
secretPaths = lib.catAttrs "_secret" (lib.collect isSecret filteredConfig);
parsedmarcConfig = ini.generate "parsedmarc.ini" filteredConfig;
mkSecretReplacement = file:
lib.optionalString (file != null) ''
replace-secret '${file}' '${file}' /run/parsedmarc/parsedmarc.ini
'';
mkSecretReplacement = file: ''
replace-secret ${lib.escapeShellArgs [ (hashString "sha256" file) file "/run/parsedmarc/parsedmarc.ini" ]}
'';
secretReplacements = lib.concatMapStrings mkSecretReplacement secretPaths;
in
{
wantedBy = [ "multi-user.target" ];
@ -487,10 +485,7 @@ in
umask u=rwx,g=,o=
cp ${parsedmarcConfig} /run/parsedmarc/parsedmarc.ini
chown parsedmarc:parsedmarc /run/parsedmarc/parsedmarc.ini
${mkSecretReplacement cfg.settings.smtp.password}
${mkSecretReplacement cfg.settings.imap.password}
${mkSecretReplacement cfg.settings.elasticsearch.password}
${mkSecretReplacement cfg.settings.kafka.password}
${secretReplacements}
'' + lib.optionalString cfg.provision.localMail.enable ''
openssl rand -hex 64 >/run/parsedmarc/dmarc_user_passwd
replace-secret '@imap-password@' '/run/parsedmarc/dmarc_user_passwd' /run/parsedmarc/parsedmarc.ini

@ -74,11 +74,13 @@ in
};
};
serviceOpts = {
after = mkIf cfg.systemd.enable [ cfg.systemd.unit ];
serviceConfig = {
DynamicUser = false;
# By default, each prometheus exporter only gets AF_INET & AF_INET6,
# but AF_UNIX is needed to read from the `showq`-socket.
RestrictAddressFamilies = [ "AF_UNIX" ];
SupplementaryGroups = mkIf cfg.systemd.enable [ "systemd-journal" ];
ExecStart = ''
${pkgs.prometheus-postfix-exporter}/bin/postfix_exporter \
--web.listen-address ${cfg.listenAddress}:${toString cfg.port} \

@ -257,7 +257,7 @@ in
'' + optionalString cfg.autoMigrate ''
${pkgs.ipfs-migrator}/bin/fs-repo-migrations -to '${cfg.package.repoVersion}' -y
'' + ''
ipfs --offline config profile apply ${profile}
ipfs --offline config profile apply ${profile} >/dev/null
fi
'' + optionalString cfg.autoMount ''
ipfs --offline config Mounts.FuseAllowOther --json true
@ -283,7 +283,7 @@ in
User = cfg.user;
Group = cfg.group;
StateDirectory = "";
ReadWritePaths = [ "" cfg.dataDir ];
ReadWritePaths = optionals (!cfg.autoMount) [ "" cfg.dataDir ];
} // optionalAttrs (cfg.serviceFdlimit != null) { LimitNOFILE = cfg.serviceFdlimit; };
} // optionalAttrs (!cfg.startWhenNeeded) {
wantedBy = [ "default.target" ];

@ -174,6 +174,7 @@ in
serviceConfig = {
DynamicUser = true;
StateDirectory = "bitlbee";
ReadWritePaths = [ cfg.configDir ];
ExecStart = "${bitlbeePkg}/sbin/bitlbee -F -n -c ${bitlbeeConfig}";
};
};

@ -54,10 +54,10 @@ let
hashedPassword = mkOption {
type = uniq (nullOr str);
default = null;
description = ''
description = mdDoc ''
Specifies the hashed password for the MQTT User.
To generate hashed password install <literal>mosquitto</literal>
package and use <literal>mosquitto_passwd</literal>.
To generate hashed password install `mosquitto`
package and use `mosquitto_passwd`.
'';
};
@ -65,11 +65,11 @@ let
type = uniq (nullOr types.path);
example = "/path/to/file";
default = null;
description = ''
description = mdDoc ''
Specifies the path to a file containing the
hashed password for the MQTT user.
To generate hashed password install <literal>mosquitto</literal>
package and use <literal>mosquitto_passwd</literal>.
To generate hashed password install `mosquitto`
package and use `mosquitto_passwd`.
'';
};
@ -155,24 +155,24 @@ let
options = {
plugin = mkOption {
type = path;
description = ''
Plugin path to load, should be a <literal>.so</literal> file.
description = mdDoc ''
Plugin path to load, should be a `.so` file.
'';
};
denySpecialChars = mkOption {
type = bool;
description = ''
Automatically disallow all clients using <literal>#</literal>
or <literal>+</literal> in their name/id.
description = mdDoc ''
Automatically disallow all clients using `#`
or `+` in their name/id.
'';
default = true;
};
options = mkOption {
type = attrsOf optionType;
description = ''
Options for the auth plugin. Each key turns into a <literal>auth_opt_*</literal>
description = mdDoc ''
Options for the auth plugin. Each key turns into a `auth_opt_*`
line in the config.
'';
default = {};
@ -239,8 +239,8 @@ let
address = mkOption {
type = nullOr str;
description = ''
Address to listen on. Listen on <literal>0.0.0.0</literal>/<literal>::</literal>
description = mdDoc ''
Address to listen on. Listen on `0.0.0.0`/`::`
when unset.
'';
default = null;
@ -248,10 +248,10 @@ let
authPlugins = mkOption {
type = listOf authPluginOptions;
description = ''
description = mdDoc ''
Authentication plugin to attach to this listener.
Refer to the <link xlink:href="https://mosquitto.org/man/mosquitto-conf-5.html">
mosquitto.conf documentation</link> for details on authentication plugins.
Refer to the [mosquitto.conf documentation](https://mosquitto.org/man/mosquitto-conf-5.html)
for details on authentication plugins.
'';
default = [];
};
@ -472,10 +472,10 @@ let
includeDirs = mkOption {
type = listOf path;
description = ''
description = mdDoc ''
Directories to be scanned for further config files to include.
Directories will processed in the order given,
<literal>*.conf</literal> files in the directory will be
`*.conf` files in the directory will be
read in case-sensistive alphabetical order.
'';
default = [];

@ -511,8 +511,13 @@ in
dataDir = mkOption {
type = types.path;
description = "Directory where Prosody stores its data";
default = "/var/lib/prosody";
description = ''
The prosody home directory used to store all data. If left as the default value
this directory will automatically be created before the prosody server starts, otherwise
you are responsible for ensuring the directory exists with appropriate ownership
and permissions.
'';
};
disco_items = mkOption {
@ -524,13 +529,29 @@ in
user = mkOption {
type = types.str;
default = "prosody";
description = "User account under which prosody runs.";
description = ''
User account under which prosody runs.
<note><para>
If left as the default value this user will automatically be created
on system activation, otherwise you are responsible for
ensuring the user exists before the prosody service starts.
</para></note>
'';
};
group = mkOption {
type = types.str;
default = "prosody";
description = "Group account under which prosody runs.";
description = ''
Group account under which prosody runs.
<note><para>
If left as the default value this group will automatically be created
on system activation, otherwise you are responsible for
ensuring the group exists before the prosody service starts.
</para></note>
'';
};
allowRegistration = mkOption {
@ -839,9 +860,8 @@ in
users.users.prosody = mkIf (cfg.user == "prosody") {
uid = config.ids.uids.prosody;
description = "Prosody user";
createHome = true;
inherit (cfg) group;
home = "${cfg.dataDir}";
home = cfg.dataDir;
};
users.groups.prosody = mkIf (cfg.group == "prosody") {
@ -854,28 +874,33 @@ in
wants = [ "network-online.target" ];
wantedBy = [ "multi-user.target" ];
restartTriggers = [ config.environment.etc."prosody/prosody.cfg.lua".source ];
serviceConfig = {
User = cfg.user;
Group = cfg.group;
Type = "forking";
RuntimeDirectory = [ "prosody" ];
PIDFile = "/run/prosody/prosody.pid";
ExecStart = "${cfg.package}/bin/prosodyctl start";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
};
serviceConfig = mkMerge [
{
User = cfg.user;
Group = cfg.group;
Type = "forking";
RuntimeDirectory = [ "prosody" ];
PIDFile = "/run/prosody/prosody.pid";
ExecStart = "${cfg.package}/bin/prosodyctl start";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateTmp = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
}
(mkIf (cfg.dataDir == "/var/lib/prosody") {
StateDirectory = "prosody";
})
];
};
};

@ -0,0 +1,84 @@
{ config
, lib
, pkgs
, ...
}:
with lib;
let
cfg = config.services.routedns;
settingsFormat = pkgs.formats.toml { };
in
{
options.services.routedns = {
enable = mkEnableOption "RouteDNS - DNS stub resolver, proxy and router";
settings = mkOption {
type = settingsFormat.type;
example = literalExpression ''
{
resolvers.cloudflare-dot = {
address = "1.1.1.1:853";
protocol = "dot";
};
groups.cloudflare-cached = {
type = "cache";
resolvers = ["cloudflare-dot"];
};
listeners.local-udp = {
address = "127.0.0.1:53";
protocol = "udp";
resolver = "cloudflare-cached";
};
listeners.local-tcp = {
address = "127.0.0.1:53";
protocol = "tcp";
resolver = "cloudflare-cached";
};
}
'';
description = ''
Configuration for RouteDNS, see <link xlink:href="https://github.com/folbricht/routedns/blob/master/doc/configuration.md"/>
for more information.
'';
};
configFile = mkOption {
default = settingsFormat.generate "routedns.toml" cfg.settings;
defaultText = "A RouteDNS configuration file automatically generated by values from services.routedns.*";
type = types.path;
example = literalExpression ''"''${pkgs.routedns}/cmd/routedns/example-config/use-case-1.toml"'';
description = "Path to RouteDNS TOML configuration file.";
};
package = mkOption {
default = pkgs.routedns;
defaultText = literalExpression "pkgs.routedns";
type = types.package;
description = "RouteDNS package to use.";
};
};
config = mkIf cfg.enable {
systemd.services.routedns = {
description = "RouteDNS - DNS stub resolver, proxy and router";
after = [ "network.target" ]; # in case a bootstrap resolver is used, this might fail a few times until the respective server is actually reachable
wantedBy = [ "multi-user.target" ];
wants = [ "network.target" ];
startLimitIntervalSec = 30;
startLimitBurst = 5;
serviceConfig = {
Restart = "on-failure";
RestartSec = "5s";
LimitNPROC = 512;
LimitNOFILE = 1048576;
DynamicUser = true;
AmbientCapabilities = "CAP_NET_BIND_SERVICE";
NoNewPrivileges = true;
ExecStart = "${getBin cfg.package}/bin/routedns -l 4 ${cfg.configFile}";
};
};
};
meta.maintainers = with maintainers; [ jsimonetti ];
}

@ -72,39 +72,39 @@ in {
cert = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Path to the <literal>cert.pem</literal> file, which will be copied into Syncthing's
<link linkend="opt-services.syncthing.configDir">configDir</link>.
description = mdDoc ''
Path to the `cert.pem` file, which will be copied into Syncthing's
[configDir](#opt-services.syncthing.configDir).
'';
};
key = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Path to the <literal>key.pem</literal> file, which will be copied into Syncthing's
<link linkend="opt-services.syncthing.configDir">configDir</link>.
description = mdDoc ''
Path to the `key.pem` file, which will be copied into Syncthing's
[configDir](#opt-services.syncthing.configDir).
'';
};
overrideDevices = mkOption {
type = types.bool;
default = true;
description = ''
description = mdDoc ''
Whether to delete the devices which are not configured via the
<link linkend="opt-services.syncthing.devices">devices</link> option.
If set to <literal>false</literal>, devices added via the web
[devices](#opt-services.syncthing.devices) option.
If set to `false`, devices added via the web
interface will persist and will have to be deleted manually.
'';
};
devices = mkOption {
default = {};
description = ''
description = mdDoc ''
Peers/devices which Syncthing should communicate with.
Note that you can still add devices manually, but those changes
will be reverted on restart if <link linkend="opt-services.syncthing.overrideDevices">overrideDevices</link>
will be reverted on restart if [overrideDevices](#opt-services.syncthing.overrideDevices)
is enabled.
'';
example = {
@ -135,27 +135,27 @@ in {
id = mkOption {
type = types.str;
description = ''
The device ID. See <link xlink:href="https://docs.syncthing.net/dev/device-ids.html"/>.
description = mdDoc ''
The device ID. See <https://docs.syncthing.net/dev/device-ids.html>.
'';
};
introducer = mkOption {
type = types.bool;
default = false;
description = ''
description = mdDoc ''
Whether the device should act as an introducer and be allowed
to add folders on this computer.
See <link xlink:href="https://docs.syncthing.net/users/introducer.html"/>.
See <https://docs.syncthing.net/users/introducer.html>.
'';
};
autoAcceptFolders = mkOption {
type = types.bool;
default = false;
description = ''
description = mdDoc ''
Automatically create or share folders that this device advertises at the default path.
See <link xlink:href="https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format"/>.
See <https://docs.syncthing.net/users/config.html?highlight=autoaccept#config-file-format>.
'';
};
@ -166,21 +166,21 @@ in {
overrideFolders = mkOption {
type = types.bool;
default = true;
description = ''
description = mdDoc ''
Whether to delete the folders which are not configured via the
<link linkend="opt-services.syncthing.folders">folders</link> option.
If set to <literal>false</literal>, folders added via the web
[folders](#opt-services.syncthing.folders) option.
If set to `false`, folders added via the web
interface will persist and will have to be deleted manually.
'';
};
folders = mkOption {
default = {};
description = ''
description = mdDoc ''
Folders which should be shared by Syncthing.
Note that you can still add devices manually, but those changes
will be reverted on restart if <link linkend="opt-services.syncthing.overrideDevices">overrideDevices</link>
Note that you can still add folders manually, but those changes
will be reverted on restart if [overrideFolders](#opt-services.syncthing.overrideFolders)
is enabled.
'';
example = literalExpression ''
@ -231,18 +231,18 @@ in {
devices = mkOption {
type = types.listOf types.str;
default = [];
description = ''
description = mdDoc ''
The devices this folder should be shared with. Each device must
be defined in the <link linkend="opt-services.syncthing.devices">devices</link> option.
be defined in the [devices](#opt-services.syncthing.devices) option.
'';
};
versioning = mkOption {
default = null;
description = ''
description = mdDoc ''
How to keep changed/deleted files with Syncthing.
There are 4 different types of versioning with different parameters.
See <link xlink:href="https://docs.syncthing.net/users/versioning.html"/>.
See <https://docs.syncthing.net/users/versioning.html>.
'';
example = literalExpression ''
[
@ -284,17 +284,17 @@ in {
options = {
type = mkOption {
type = enum [ "external" "simple" "staggered" "trashcan" ];
description = ''
description = mdDoc ''
The type of versioning.
See <link xlink:href="https://docs.syncthing.net/users/versioning.html"/>.
See <https://docs.syncthing.net/users/versioning.html>.
'';
};
params = mkOption {
type = attrsOf (either str path);
description = ''
description = mdDoc ''
The parameters for versioning. Structure depends on
<link linkend="opt-services.syncthing.folders._name_.versioning.type">versioning.type</link>.
See <link xlink:href="https://docs.syncthing.net/users/versioning.html"/>.
[versioning.type](#opt-services.syncthing.folders._name_.versioning.type).
See <https://docs.syncthing.net/users/versioning.html>.
'';
};
};
@ -345,9 +345,9 @@ in {
ignoreDelete = mkOption {
type = types.bool;
default = false;
description = ''
description = mdDoc ''
Whether to skip deleting files that are deleted by peers.
See <link xlink:href="https://docs.syncthing.net/advanced/folder-ignoredelete.html"/>.
See <https://docs.syncthing.net/advanced/folder-ignoredelete.html>.
'';
};
};
@ -357,9 +357,9 @@ in {
extraOptions = mkOption {
type = types.addCheck (pkgs.formats.json {}).type isAttrs;
default = {};
description = ''
description = mdDoc ''
Extra configuration options for Syncthing.
See <link xlink:href="https://docs.syncthing.net/users/config.html"/>.
See <https://docs.syncthing.net/users/config.html>.
'';
example = {
options.localAnnounceEnabled = false;
@ -387,9 +387,9 @@ in {
type = types.str;
default = defaultUser;
example = "yourUser";
description = ''
description = mdDoc ''
The user to run Syncthing as.
By default, a user named <literal>${defaultUser}</literal> will be created.
By default, a user named `${defaultUser}` will be created.
'';
};
@ -397,9 +397,9 @@ in {
type = types.str;
default = defaultGroup;
example = "yourGroup";
description = ''
description = mdDoc ''
The group to run Syncthing under.
By default, a group named <literal>${defaultGroup}</literal> will be created.
By default, a group named `${defaultGroup}` will be created.
'';
};
@ -407,11 +407,11 @@ in {
type = with types; nullOr str;
default = null;
example = "socks5://address.com:1234";
description = ''
description = mdDoc ''
Overwrites the all_proxy environment variable for the Syncthing process to
the given value. This is normally used to let Syncthing connect
through a SOCKS5 proxy server.
See <link xlink:href="https://docs.syncthing.net/users/proxying.html"/>.
See <https://docs.syncthing.net/users/proxying.html>.
'';
};
@ -432,25 +432,13 @@ in {
The path where the settings and keys will exist.
'';
default = cfg.dataDir + optionalString cond "/.config/syncthing";
defaultText = literalDocBook ''
<variablelist>
<varlistentry>
<term><literal>stateVersion >= 19.03</literal></term>
<listitem>
<programlisting>
config.${opt.dataDir} + "/.config/syncthing"
</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>otherwise</term>
<listitem>
<programlisting>
config.${opt.dataDir}
</programlisting>
</listitem>
</varlistentry>
</variablelist>
defaultText = literalMD ''
* if `stateVersion >= 19.03`:
config.${opt.dataDir} + "/.config/syncthing"
* otherwise:
config.${opt.dataDir}
'';
};

@ -6,6 +6,7 @@ let
cfg = config.services.tailscale;
firewallOn = config.networking.firewall.enable;
rpfMode = config.networking.firewall.checkReversePath;
isNetworkd = config.networking.useNetworkd;
rpfIsStrict = rpfMode == true || rpfMode == "strict";
in {
meta.maintainers = with maintainers; [ danderson mbaillie twitchyliquid64 ];
@ -69,5 +70,17 @@ in {
# linux distros.
stopIfChanged = false;
};
networking.dhcpcd.denyInterfaces = [ cfg.interfaceName ];
systemd.network.networks."50-tailscale" = mkIf isNetworkd {
matchConfig = {
Name = cfg.interfaceName;
};
linkConfig = {
Unmanaged = true;
ActivationPolicy = "manual";
};
};
};
}

@ -6,6 +6,9 @@ let
cfg = config.services.trickster;
in
{
imports = [
(mkRenamedOptionModule [ "services" "trickster" "origin" ] [ "services" "trickster" "origin-url" ])
];
options = {
services.trickster = {
@ -58,11 +61,19 @@ in
'';
};
origin = mkOption {
origin-type = mkOption {
type = types.enum [ "prometheus" "influxdb" ];
default = "prometheus";
description = ''
Type of origin (prometheus, influxdb)
'';
};
origin-url = mkOption {
type = types.str;
default = "http://prometheus:9090";
description = ''
URL to the Prometheus Origin. Enter it like you would in grafana, e.g., http://prometheus:9090 (default http://prometheus:9090).
URL to the Origin. Enter it like you would in grafana, e.g., http://prometheus:9090 (default http://prometheus:9090).
'';
};
@ -87,7 +98,7 @@ in
config = mkIf cfg.enable {
systemd.services.trickster = {
description = "Dashboard Accelerator for Prometheus";
description = "Reverse proxy cache and time series dashboard accelerator";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
@ -96,7 +107,8 @@ in
${cfg.package}/bin/trickster \
-log-level ${cfg.log-level} \
-metrics-port ${toString cfg.metrics-port} \
-origin ${cfg.origin} \
-origin-type ${cfg.origin-type} \
-origin-url ${cfg.origin-url} \
-proxy-port ${toString cfg.proxy-port} \
${optionalString (cfg.configFile != null) "-config ${cfg.configFile}"} \
${optionalString (cfg.profiler-port != null) "-profiler-port ${cfg.profiler-port}"} \

@ -62,20 +62,52 @@ in {
default = {};
example = literalExpression ''
{
domain = "https://bw.domain.tld:8443";
signupsAllowed = true;
rocketPort = 8222;
rocketLog = "critical";
DOMAIN = "https://bitwarden.example.com";
SIGNUPS_ALLOWED = false;
# Vaultwarden currently recommends running behind a reverse proxy
# (nginx or similar) for TLS termination, see
# https://github.com/dani-garcia/vaultwarden/wiki/Hardening-Guide#reverse-proxying
# > you should avoid enabling HTTPS via vaultwarden's built-in Rocket TLS support,
# > especially if your instance is publicly accessible.
#
# A suitable NixOS nginx reverse proxy example config might be:
#
# services.nginx.virtualHosts."bitwarden.example.com" = {
# enableACME = true;
# forceSSL = true;
# locations."/" = {
# proxyPass = "http://127.0.0.1:''${toString config.services.vaultwarden.config.ROCKET_PORT}";
# };
# };
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = 8222;
ROCKET_LOG = "critical";
# This example assumes a mailserver running on localhost,
# thus without transport encryption.
# If you use an external mail server, follow:
# https://github.com/dani-garcia/vaultwarden/wiki/SMTP-configuration
SMTP_HOST = "127.0.0.1";
SMTP_PORT = 25;
SMTP_SSL = false;
SMTP_FROM = "admin@bitwarden.example.com";
SMTP_FROM_NAME = "example.com Bitwarden server";
}
'';
description = ''
The configuration of vaultwarden is done through environment variables,
therefore the names are converted from camel case (e.g. disable2FARemember)
to upper case snake case (e.g. DISABLE_2FA_REMEMBER).
therefore it is recommended to use upper snake case (e.g. <envar>DISABLE_2FA_REMEMBER</envar>).
However, camel case (e.g. <literal>disable2FARemember</literal>) is also supported:
The NixOS module will convert it automatically to
upper case snake case (e.g. <envar>DISABLE_2FA_REMEMBER</envar>).
In this conversion digits (0-9) are handled just like upper case characters,
so foo2 would be converted to FOO_2.
Names already in this format remain unchanged, so FOO2 remains FOO2 if passed as such,
even though foo2 would have been converted to FOO_2.
so <literal>foo2</literal> would be converted to <envar>FOO_2</envar>.
Names already in this format remain unchanged, so <literal>FOO2</literal> remains <literal>FOO2</literal> if passed as such,
even though <literal>foo2</literal> would have been converted to <envar>FOO_2</envar>.
This allows working around any potential future conflicting naming conventions.
Based on the attributes passed to this config option an environment file will be generated
@ -83,13 +115,16 @@ in {
The available configuration options can be found in
<link xlink:href="https://github.com/dani-garcia/vaultwarden/blob/${vaultwarden.version}/.env.template">the environment template file</link>.
See <xref linkend="opt-services.vaultwarden.environmentFile" /> for how
to set up access to the Admin UI to invite initial users.
'';
};
environmentFile = mkOption {
type = with types; nullOr path;
default = null;
example = "/root/vaultwarden.env";
example = "/var/lib/vaultwarden.env";
description = ''
Additional environment file as defined in <citerefentry>
<refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum>
@ -100,6 +135,23 @@ in {
Note that this file needs to be available on the host on which
<literal>vaultwarden</literal> is running.
As a concrete example, to make the Admin UI available
(from which new users can be invited initially),
the secret <envar>ADMIN_TOKEN</envar> needs to be defined as described
<link xlink:href="https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page">here</link>.
Setting <literal>environmentFile</literal> to <literal>/var/lib/vaultwarden.env</literal>
and ensuring permissions with e.g.
<literal>chown vaultwarden:vaultwarden /var/lib/vaultwarden.env</literal>
(the <literal>vaultwarden</literal> user will only exist after activating with
<literal>enable = true;</literal> before this), we can set the contents of the file to have
contents such as:
<programlisting>
# Admin secret token, see
# https://github.com/dani-garcia/vaultwarden/wiki/Enabling-admin-page
ADMIN_TOKEN=...copy-paste a unique generated secret token here...
</programlisting>
'';
};

@ -89,7 +89,8 @@ in {
};
datadir = mkOption {
type = types.str;
defaultText = "config.services.nextcloud.home";
default = config.services.nextcloud.home;
defaultText = literalExpression "config.services.nextcloud.home";
description = ''
Data storage path of nextcloud. Will be <xref linkend="opt-services.nextcloud.home" /> by default.
This folder will be populated with a config.php and data folder which contains the state of the instance (excl the database).";
@ -629,8 +630,6 @@ in {
else nextcloud24
);
services.nextcloud.datadir = mkOptionDefault config.services.nextcloud.home;
services.nextcloud.phpPackage =
if versionOlder cfg.package.version "24" then pkgs.php80
# FIXME: Use PHP 8.1 with Nextcloud 24 and higher, once issues like this one are fixed:
@ -650,6 +649,7 @@ in {
{ systemd.timers.nextcloud-cron = {
wantedBy = [ "timers.target" ];
after = [ "nextcloud-setup.service" ];
timerConfig.OnBootSec = "5m";
timerConfig.OnUnitActiveSec = "5m";
timerConfig.Unit = "nextcloud-cron.service";
@ -840,12 +840,14 @@ in {
serviceConfig.User = "nextcloud";
};
nextcloud-cron = {
after = [ "nextcloud-setup.service" ];
environment.NEXTCLOUD_CONFIG_DIR = "${datadir}/config";
serviceConfig.Type = "oneshot";
serviceConfig.User = "nextcloud";
serviceConfig.ExecStart = "${phpPackage}/bin/php -f ${cfg.package}/cron.php";
};
nextcloud-update-plugins = mkIf cfg.autoUpdateApps.enable {
after = [ "nextcloud-setup.service" ];
serviceConfig.Type = "oneshot";
serviceConfig.ExecStart = "${occ}/bin/nextcloud-occ app:update --all";
serviceConfig.User = "nextcloud";
@ -914,7 +916,6 @@ in {
priority = 100;
extraConfig = ''
allow all;
log_not_found off;
access_log off;
'';
};

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

Loading…
Cancel
Save