Merge branch 'master' of https://github.com/NixOS/nixpkgs into tt-rss-2021-06-21

This commit is contained in:
Milo Gertjejansen 2021-07-25 16:02:48 -04:00
commit b0b71138c8
2619 changed files with 68582 additions and 20410 deletions

1
.github/CODEOWNERS vendored
View File

@ -46,7 +46,6 @@
/nixos/default.nix @nbp @infinisil
/nixos/lib/from-env.nix @nbp @infinisil
/nixos/lib/eval-config.nix @nbp @infinisil
/nixos/doc @ryantm
/nixos/doc/manual/configuration/abstractions.xml @nbp
/nixos/doc/manual/configuration/config-file.xml @nbp
/nixos/doc/manual/configuration/config-syntax.xml @nbp

View File

@ -7,33 +7,38 @@ assignees: ''
---
**Describe the bug**
### Describe the bug
A clear and concise description of what the bug is.
**To Reproduce**
### Steps To Reproduce
Steps to reproduce the behavior:
1. ...
2. ...
3. ...
**Expected behavior**
### Expected behavior
A clear and concise description of what you expected to happen.
**Screenshots**
### Screenshots
If applicable, add screenshots to help explain your problem.
**Additional context**
### Additional context
Add any other context about the problem here.
**Notify maintainers**
### Notify maintainers
<!--
Please @ people who are in the `meta.maintainers` list of the offending package or module.
If in doubt, check `git blame` for whoever last touched something.
-->
**Metadata**
### Metadata
Please run `nix-shell -p nix-info --run "nix-info -m"` and paste the result.
```console
[user@system:~]$ nix-shell -p nix-info --run "nix-info -m"
output here
```
Maintainer information:
```yaml
# a list of nixpkgs attributes affected by the problem

View File

@ -3,7 +3,7 @@
- Thanks for your contribution!
- To remove the stale label, just leave a new comment.
- _How to find the right people to ping?_ &rarr; [`git blame`](https://git-scm.com/docs/git-blame) to the rescue! (or GitHub's history and blame buttons.)
- You can always ask for help on [our Discourse Forum](https://discourse.nixos.org/) or on the [#nixos IRC channel](https://webchat.freenode.net/#nixos).
- You can always ask for help on [our Discourse Forum](https://discourse.nixos.org/), [our Matrix room](https://matrix.to/#/#nix:nixos.org), or on the [#nixos IRC channel](https://web.libera.chat/#nixos).
## Suggestions for PRs

View File

@ -15,13 +15,13 @@ jobs:
ref: ${{ github.event.pull_request.head.sha }}
- name: Create backport PRs
# should be kept in sync with `version`
uses: zeebe-io/backport-action@2b994724142df0774855690db56bc6308fb99ffa
uses: zeebe-io/backport-action@v0.0.5
with:
# Config README: https://github.com/zeebe-io/backport-action#backport-action
github_token: ${{ secrets.GITHUB_TOKEN }}
github_workspace: ${{ github.workspace }}
# should be kept in sync with `uses`
version: 2b994724142df0774855690db56bc6308fb99ffa
version: v0.0.5
pull_description: |-
Bot-based backport to `${target_branch}`, triggered by a label in #${pull_number}.

20
.github/workflows/basic-eval.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: Basic evaluation checks
on:
pull_request:
branches:
- master
- release-**
push:
branches:
- master
- release-**
jobs:
tests:
runs-on: ubuntu-latest
# we don't limit this action to only NixOS repo since the checks are cheap and useful developer feedback
steps:
- uses: actions/checkout@v2
- uses: cachix/install-nix-action@v13
# explicit list of supportedSystems is needed until aarch64-darwin becomes part of the trunk jobset
- run: nix-build pkgs/top-level/release.nix -A tarball.nixpkgs-basic-release-checks --arg supportedSystems '[ "aarch64-darwin" "aarch64-linux" "x86_64-linux" "x86_64-darwin" ]'

View File

@ -22,7 +22,7 @@ jobs:
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v9
- uses: cachix/cachix-action@v10
with:
# This cache is for the nixos/nixpkgs manual builds and should not be trusted or used elsewhere.
name: nixpkgs-ci

View File

@ -22,7 +22,7 @@ jobs:
with:
# explicitly enable sandbox
extra_nix_config: sandbox = true
- uses: cachix/cachix-action@v9
- uses: cachix/cachix-action@v10
with:
# This cache is for the nixos/nixpkgs manual builds and should not be trusted or used elsewhere.
name: nixpkgs-ci

21
.github/workflows/no-channel.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: "No channel PR"
on:
pull_request:
branches:
- 'nixos-**'
- 'nixpkgs-**'
jobs:
fail:
name: "This PR is is targeting a channel branch"
runs-on: ubuntu-latest
steps:
- run: |
cat <<EOF
The nixos-* and nixpkgs-* branches are pushed to by the channel
release script and should not be merged into directly.
Please target the equivalent release-* branch or master instead.
EOF
exit 1

View File

@ -41,7 +41,7 @@ weechat.override {
configure = { availablePlugins, ... }: {
init = ''
/set foo bar
/server add freenode chat.freenode.org
/server add libera irc.libera.chat
'';
};
}

View File

@ -18,6 +18,8 @@
Additional commands to be executed for finalizing the derivation with runner script.
- `runScript`
A command that would be executed inside the sandbox and passed all the command line arguments. It defaults to `bash`.
- `profile`
Optional script for `/etc/profile` within the sandbox.
One can create a simple environment using a `shell.nix` like that:

View File

@ -8,7 +8,7 @@
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.8. The attribute `python` refers to
interpreter, which is currently CPython 3.9. 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
the default PyPy interpreter.
@ -839,7 +839,7 @@ sets are
and the aliases
* `pkgs.python2Packages` pointing to `pkgs.python27Packages`
* `pkgs.python3Packages` pointing to `pkgs.python38Packages`
* `pkgs.python3Packages` pointing to `pkgs.python39Packages`
* `pkgs.pythonPackages` pointing to `pkgs.python2Packages`
#### `buildPythonPackage` function {#buildpythonpackage-function}

View File

@ -120,7 +120,7 @@ After that you can install your special grafted `myVim` or `myNeovim` packages.
If one of your favourite plugins isn't packaged, you can package it yourself:
```
```nix
{ config, pkgs, ... }:
let
@ -154,6 +154,33 @@ in
}
```
### Specificities for some plugins
#### Tree sitter
By default `nvim-treesitter` encourages you to download, compile and install
the required tree-sitter grammars at run time with `:TSInstall`. This works
poorly on NixOS. Instead, to install the `nvim-treesitter` plugins with a set
of precompiled grammars, you can use `nvim-treesitter.withPlugins` function:
```nix
(pkgs.neovim.override {
configure = {
packages.myPlugins = with pkgs.vimPlugins; {
start = [
(nvim-treesitter.withPlugins (
plugins: with plugins; [
tree-sitter-nix
tree-sitter-python
]
))
];
};
};
})
```
To enable all grammars packaged in nixpkgs, use `(pkgs.vimPlugins.nvim-treesitter.withPlugins (plugins: pkgs.tree-sitter.allGrammars))`.
## Managing plugins with vim-plug {#managing-plugins-with-vim-plug}
To use [vim-plug](https://github.com/junegunn/vim-plug) to manage your Vim

View File

@ -47,8 +47,26 @@
})
];
})).config;
moduleDeclarationFile =
let
# Even though `modules` is a mandatory argument for `nixosSystem`, it doesn't
# mean that the evaluator always keeps track of its position. If there
# are too many levels of indirection, the position gets lost at some point.
intermediatePos = builtins.unsafeGetAttrPos "modules" args;
in
if intermediatePos == null then null else intermediatePos.file;
# Add the invoking file as error message location for modules
# that don't have their own locations; presumably inline modules.
addModuleDeclarationFile =
m: if moduleDeclarationFile == null then m else {
_file = moduleDeclarationFile;
imports = [ m ];
};
in
modules ++ [
map addModuleDeclarationFile modules ++ [
{
system.nixos.versionSuffix =
".${final.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}.${self.shortRev or "dirty"}";

View File

@ -116,7 +116,7 @@ let
pushDownProperties dischargeProperties filterOverrides
sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride
mkOptionDefault mkDefault mkForce mkVMOverride
mkOrder mkBefore mkAfter mkAliasDefinitions
mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions
mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule doRename;

View File

@ -713,6 +713,8 @@ rec {
mkForce = mkOverride 50;
mkVMOverride = mkOverride 10; # used by nixos-rebuild build-vm
mkFixStrictness = lib.warn "lib.mkFixStrictness has no effect and will be removed. It returns its argument unmodified, so you can just remove any calls." id;
mkOrder = priority: content:
{ _type = "order";
inherit priority content;

View File

@ -28,6 +28,7 @@ let
"aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux"
"armv7l-linux" "i686-linux" "mipsel-linux" "powerpc64-linux"
"powerpc64le-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux"
"m68k-linux" "s390-linux"
# MMIXware
"mmix-mmixware"
@ -39,8 +40,8 @@ let
# none
"aarch64-none" "arm-none" "armv6l-none" "avr-none" "i686-none" "msp430-none"
"or1k-none" "powerpc-none" "riscv32-none" "riscv64-none" "vc4-none"
"x86_64-none"
"or1k-none" "powerpc-none" "riscv32-none" "riscv64-none" "vc4-none" "m68k-none"
"s390-none" "x86_64-none"
# OpenBSD
"i686-openbsd" "x86_64-openbsd"
@ -74,6 +75,8 @@ in {
riscv = filterDoubles predicates.isRiscV;
vc4 = filterDoubles predicates.isVc4;
or1k = filterDoubles predicates.isOr1k;
m68k = filterDoubles predicates.isM68k;
s390 = filterDoubles predicates.isS390;
js = filterDoubles predicates.isJavaScript;
bigEndian = filterDoubles predicates.isBigEndian;

View File

@ -144,6 +144,14 @@ rec {
libc = "newlib";
};
m68k = {
config = "m68k-unknown-linux-gnu";
};
s390 = {
config = "s390-unknown-linux-gnu";
};
arm-embedded = {
config = "arm-none-eabi";
libc = "newlib";

View File

@ -26,6 +26,8 @@ rec {
isAvr = { cpu = { family = "avr"; }; };
isAlpha = { cpu = { family = "alpha"; }; };
isOr1k = { cpu = { family = "or1k"; }; };
isM68k = { cpu = { family = "m68k"; }; };
isS390 = { cpu = { family = "s390"; }; };
isJavaScript = { cpu = cpuTypes.js; };
is32bit = { cpu = { bits = 32; }; };

View File

@ -95,6 +95,8 @@ rec {
mmix = { bits = 64; significantByte = bigEndian; family = "mmix"; };
m68k = { bits = 32; significantByte = bigEndian; family = "m68k"; };
powerpc = { bits = 32; significantByte = bigEndian; family = "power"; };
powerpc64 = { bits = 64; significantByte = bigEndian; family = "power"; };
powerpc64le = { bits = 64; significantByte = littleEndian; family = "power"; };
@ -103,6 +105,8 @@ rec {
riscv32 = { bits = 32; significantByte = littleEndian; family = "riscv"; };
riscv64 = { bits = 64; significantByte = littleEndian; family = "riscv"; };
s390 = { bits = 32; significantByte = bigEndian; family = "s390"; };
sparc = { bits = 32; significantByte = bigEndian; family = "sparc"; };
sparc64 = { bits = 64; significantByte = bigEndian; family = "sparc"; };

View File

@ -28,7 +28,7 @@ with lib.systems.doubles; lib.runTests {
testredox = mseteq redox [ "x86_64-redox" ];
testgnu = mseteq gnu (linux /* ++ kfreebsd ++ ... */);
testillumos = mseteq illumos [ "x86_64-solaris" ];
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" ];
testlinux = mseteq linux [ "aarch64-linux" "armv5tel-linux" "armv6l-linux" "armv7a-linux" "armv7l-linux" "i686-linux" "mipsel-linux" "riscv32-linux" "riscv64-linux" "x86_64-linux" "powerpc64-linux" "powerpc64le-linux" "m68k-linux" "s390-linux" ];
testnetbsd = mseteq netbsd [ "aarch64-netbsd" "armv6l-netbsd" "armv7a-netbsd" "armv7l-netbsd" "i686-netbsd" "mipsel-netbsd" "powerpc-netbsd" "riscv32-netbsd" "riscv64-netbsd" "x86_64-netbsd" ];
testopenbsd = mseteq openbsd [ "i686-openbsd" "x86_64-openbsd" ];
testwindows = mseteq windows [ "i686-cygwin" "x86_64-cygwin" "i686-windows" "x86_64-windows" ];

View File

@ -287,6 +287,13 @@ rec {
merge = mergeEqualOption;
};
nonEmptyStr = mkOptionType {
name = "nonEmptyStr";
description = "non-empty string";
check = x: str.check x && builtins.match "[ \t\n]*" x == null;
inherit (str) merge;
};
strMatching = pattern: mkOptionType {
name = "strMatching ${escapeNixString pattern}";
description = "string matching the pattern ${pattern}";
@ -581,7 +588,17 @@ rec {
in
mkOptionType rec {
name = "enum";
description = "one of ${concatMapStringsSep ", " show values}";
description =
# Length 0 or 1 enums may occur in a design pattern with type merging
# where an "interface" module declares an empty enum and other modules
# provide implementations, each extending the enum with their own
# identifier.
if values == [] then
"impossible (empty enum)"
else if builtins.length values == 1 then
"value ${show (builtins.head values)} (singular enum)"
else
"one of ${concatMapStringsSep ", " show values}";
check = flip elem values;
merge = mergeEqualOption;
functor = (defaultFunctor name) // { payload = values; binOp = a: b: unique (a ++ b); };

View File

@ -680,6 +680,12 @@
githubId = 11699655;
name = "Stanislas Lange";
};
angustrau = {
name = "Angus Trau";
email = "nix@angus.ws";
github = "angustrau";
githubId = 13267947;
};
anhdle14 = {
name = "Le Anh Duc";
email = "anhdle14@icloud.com";
@ -796,6 +802,12 @@
githubId = 13426784;
name = "arcnmx";
};
arcticlimer = {
email = "vinigm.nho@gmail.com";
github = "arcticlimer";
githubId = 59743220;
name = "Vinícius Müller";
};
ardumont = {
email = "eniotna.t@gmail.com";
github = "ardumont";
@ -1048,6 +1060,12 @@
githubId = 135230;
name = "Aycan iRiCAN";
};
arjix = {
email = "arjix@protonmail.com";
github = "arjix";
githubId = 62168569;
name = "arjix";
};
artturin = {
email = "artturin@artturin.com";
github = "artturin";
@ -1512,6 +1530,12 @@
githubId = 1111035;
name = "Break Yang";
};
brecht = {
email = "brecht.savelkoul@alumni.lse.ac.uk";
github = "brechtcs";
githubId = 6107054;
name = "Brecht Savelkoul";
};
brettlyons = {
email = "blyons@fastmail.com";
github = "brettlyons";
@ -2463,6 +2487,12 @@
githubId = 452652;
name = "Kosyrev Serge";
};
DeeUnderscore = {
email = "d.anzorge@gmail.com";
github = "DeeUnderscore";
githubId = 156239;
name = "D Anzorge";
};
delan = {
name = "Delan Azabani";
email = "delan@azabani.com";
@ -2565,6 +2595,12 @@
githubId = 4708206;
name = "Daniel Fox Franke";
};
dgliwka = {
email = "dawid.gliwka@gmail.com";
github = "dgliwka";
githubId = 33262214;
name = "Dawid Gliwka";
};
dgonyeo = {
email = "derek@gonyeo.com";
github = "dgonyeo";
@ -3109,6 +3145,12 @@
githubId = 57923898;
name = "Elyhaka";
};
em0lar = {
email = "nix@em0lar.dev";
github = "em0lar";
githubId = 11006031;
name = "Leo Maroni";
};
emmanuelrosa = {
email = "emmanuel_rosa@aol.com";
github = "emmanuelrosa";
@ -4195,6 +4237,12 @@
githubId = 6430643;
name = "Henry Till";
};
heph2 = {
email = "srht@mrkeebs.eu";
github = "heph2";
githubId = 87579883;
name = "Marco";
};
herberteuler = {
email = "herberteuler@gmail.com";
github = "herberteuler";
@ -4319,6 +4367,12 @@
github = "HolgerPeters";
githubId = 4097049;
};
hqurve = {
email = "hqurve@outlook.com";
github = "hqurve";
githubId = 53281855;
name = "hqurve";
};
hrdinka = {
email = "c.nix@hrdinka.at";
github = "hrdinka";
@ -4643,6 +4697,12 @@
githubId = 6874204;
name = "Jason Carr";
};
j-brn = {
email = "me@bricker.io";
github = "j-brn";
githubId = 40566146;
name = "Jonas Braun";
};
j-keck = {
email = "jhyphenkeck@gmail.com";
github = "j-keck";
@ -4769,6 +4829,12 @@
githubId = 1383440;
name = "Jason Gilliland";
};
jdahm = {
email = "johann.dahm@gmail.com";
github = "jdahm";
githubId = 68032;
name = "Johann Dahm";
};
jdanek = {
email = "jdanek@redhat.com";
github = "jdanekrh";
@ -5466,6 +5532,12 @@
githubId = 25607;
name = "Raimon Grau";
};
kidonng = {
email = "hi@xuann.wang";
github = "kidonng";
githubId = 44045911;
name = "Kid";
};
kierdavis = {
email = "kierdavis@gmail.com";
github = "kierdavis";
@ -5665,6 +5737,12 @@
githubId = 735008;
name = "Louis Taylor";
};
kranzes = {
email = "personal@ilanjoselevich.com";
github = "Kranzes";
githubId = 56614642;
name = "Ilan Joselevich";
};
krav = {
email = "kristoffer@microdisko.no";
github = "krav";
@ -5719,6 +5797,12 @@
githubId = 278013;
name = "Tomasz Kontusz";
};
kurnevsky = {
email = "kurnevsky@gmail.com";
github = "kurnevsky";
githubId = 2943605;
name = "Evgeny Kurnevsky";
};
kuznero = {
email = "roman@kuznero.com";
github = "kuznero";
@ -5846,6 +5930,12 @@
githubId = 1104419;
name = "Lucas Hoffmann";
};
lde = {
email = "lilian.deloche@puck.fr";
github = "lde";
githubId = 1447020;
name = "Lilian Deloche";
};
ldelelis = {
email = "ldelelis@est.frba.utn.edu.ar";
github = "ldelelis";
@ -6586,6 +6676,12 @@
githubId = 1191859;
name = "Maxim Krivchikov";
};
MayNiklas = {
email = "info@niklas-steffen.de";
github = "MayNiklas";
githubId = 44636701;
name = "Niklas Steffen";
};
mazurel = {
email = "mateusz.mazur@yahoo.com";
github = "Mazurel";
@ -7500,6 +7596,12 @@
githubId = 1665818;
name = "Philipp Eder";
};
nickcao = {
name = "Nick Cao";
email = "nickcao@nichi.co";
github = "NickCao";
githubId = 15247171;
};
nickhu = {
email = "me@nickhu.co.uk";
github = "nickhu";
@ -7546,6 +7648,12 @@
githubId = 26231126;
name = "Nils ANDRÉ-CHANG";
};
nils-degroot = {
email = "nils@peeko.nl";
github = "nils-degroot";
githubId = 53556985;
name = "Nils de Groot";
};
ninjatrappeur = {
email = "felix@alternativebit.fr";
github = "ninjatrappeur";
@ -7568,6 +7676,22 @@
githubId = 3159451;
name = "Nicolas Schneider";
};
nkje = {
name = "Niels Kristian Lyshøj Jensen";
email = "n@nk.je";
github = "NKJe";
githubId = 1102306;
keys = [{
longkeyid = "nistp256/0xDE3BADFECD31A89D";
fingerprint = "B956 C6A4 22AF 86A0 8F77 A8CA DE3B ADFE CD31 A89D";
}];
};
nitsky = {
name = "nitsky";
email = "492793+nitsky@users.noreply.github.com";
github = "nitsky";
githubId = 492793;
};
nkpvk = {
email = "niko.pavlinek@gmail.com";
github = "nkpvk";
@ -7842,6 +7966,12 @@
githubId = 757752;
name = "Jonas Heinrich";
};
ony = {
name = "Mykola Orliuk";
email = "virkony@gmail.com";
github = "ony";
githubId = 11265;
};
OPNA2608 = {
email = "christoph.neidahl@gmail.com";
github = "OPNA2608";
@ -9112,6 +9242,12 @@
githubId = 1387224;
name = "Richard Szibele";
};
rsynnest = {
email = "contact@rsynnest.com";
github = "rsynnest";
githubId = 4392850;
name = "Roland Synnestvedt";
};
rtburns-jpl = {
email = "rtburns@jpl.nasa.gov";
github = "rtburns-jpl";
@ -9620,6 +9756,16 @@
githubId = 819413;
name = "Benedict Aas";
};
shreerammodi = {
name = "Shreeram Modi";
email = "shreerammodi10@gmail.com";
github = "Shrimpram";
githubId = 67710369;
keys = [{
longkeyid = "rsa4096/0x163B16EE76ED24CE";
fingerprint = "EA88 EA07 26E9 6CBF 6365 3966 163B 16EE 76ED 24CE";
}];
};
shyim = {
email = "s.sayakci@gmail.com";
github = "shyim";
@ -9666,6 +9812,12 @@
githubId = 11135311;
name = "Simon Chatterjee";
};
simonkampe = {
email = "simon.kampe+nix@gmail.com";
github = "simonkampe";
githubId = 254799;
name = "Simon Kämpe";
};
simonvandel = {
email = "simon.vandel@gmail.com";
github = "simonvandel";
@ -9994,6 +10146,12 @@
githubId = 1829294;
name = "Steve Chávez";
};
stevebob = {
email = "stephen@sherra.tt";
github = "stevebob";
githubId = 417118;
name = "Stephen Sherratt";
};
steveej = {
email = "mail@stefanjunker.de";
github = "steveej";
@ -10610,6 +10768,16 @@
githubId = 9853194;
name = "Philipp Bartsch";
};
toastal = {
email = "toastal+nix@posteo.net";
github = "toastal";
githubId = 561087;
name = "toastal";
keys = [{
longkeyid = "ed25519/5CCE6F1466D47C9E";
fingerprint = "7944 74B7 D236 DAB9 C9EF E7F9 5CCE 6F14 66D4 7C9E";
}];
};
tobim = {
email = "nix@tobim.fastmail.fm";
github = "tobim";
@ -10838,6 +11006,16 @@
githubId = 1607770;
name = "Ulrik Strid";
};
unclechu = {
name = "Viacheslav Lotsmanov";
email = "lotsmanov89@gmail.com";
github = "unclechu";
githubId = 799353;
keys = [{
longkeyid = "rsa4096/0xD276FF7467007335";
fingerprint = "EE59 5E29 BB5B F2B3 5ED2 3F1C D276 FF74 6700 7335";
}];
};
unode = {
email = "alves.rjc@gmail.com";
github = "unode";
@ -10898,12 +11076,6 @@
github = "deviant";
githubId = 68829907;
};
va1entin = {
email = "github@valentinsblog.com";
github = "va1entin";
githubId = 31535155;
name = "Valentin Heidelberger";
};
vaibhavsagar = {
email = "vaibhavsagar@gmail.com";
github = "vaibhavsagar";
@ -11232,6 +11404,12 @@
githubId = 19174984;
name = "Alex Whitt";
};
whonore = {
email = "wolfhonore@gmail.com";
github = "whonore";
githubId = 7121530;
name = "Wolf Honoré";
};
wildsebastian = {
name = "Sebastian Wild";
email = "sebastian@wild-siena.com";
@ -11806,12 +11984,6 @@
githubId = 8686360;
name = "Illia Shestakov";
};
foxit64 = {
email = "o4nsxy05@gmail.com";
github = "foxit64";
githubId = 56247270;
name = "Foxit";
};
masaeedu = {
email = "masaeedu@gmail.com";
github = "masaeedu";

View File

@ -165,6 +165,20 @@ elsif (defined $expr) {
my $hash = $fetch->{hash};
my $name = $fetch->{name};
if ($hash =~ /^([a-z0-9]+)-([A-Za-z0-9+\/=]+)$/) {
$algo = $1;
$hash = `nix hash to-base16 $hash` or die;
chomp $hash;
}
next unless $algo =~ /^[a-z0-9]+$/;
# Convert non-SRI base-64 to base-16.
if ($hash =~ /^[A-Za-z0-9+\/=]+$/) {
$hash = `nix hash to-base16 --type '$algo' $hash` or die;
chomp $hash;
}
if (defined $ENV{DEBUG}) {
print "$url $algo $hash\n";
next;
@ -184,7 +198,7 @@ elsif (defined $expr) {
my $storePath = makeFixedOutputPath(0, $algo, $hash, $name);
print STDERR "mirroring $url ($storePath)...\n";
print STDERR "mirroring $url ($storePath, $algo, $hash)...\n";
if ($dryRun) {
$mirrored++;

View File

@ -12,4 +12,4 @@ dont-distribute-packages:
EOF
echo "Regenerating list of transitive broken packages ..."
echo -e $(nix-instantiate --eval --strict maintainers/scripts/haskell/transitive-broken-packages.nix) | sed 's/\"//' | sort -i >> $config_file
echo -e $(nix-instantiate --eval --strict maintainers/scripts/haskell/transitive-broken-packages.nix) | sed 's/\"//' | LC_ALL=C.UTF-8 sort -i >> $config_file

View File

@ -133,7 +133,6 @@ with lib.maintainers; {
jitsi = {
members = [
mmilata
petabyteboy
ryantm
yuka

View File

@ -1,3 +0,0 @@
Moved to: ./contributing-to-this-manual.xml. Link:
https://nixos.org/manual/nixos/unstable/#chap-contributing

View File

@ -0,0 +1,3 @@
[Moved to ./contributing-to-this-manual.chapter.md](./contributing-to-this-manual.chapter.md). Link:
https://nixos.org/manual/nixos/unstable/#chap-contributing

View File

@ -7,19 +7,36 @@
<itemizedlist spacing="compact">
<listitem>
<para>
Support is planned until the end of April 2022, handing over to
Support is planned until the end of June 2022, handing over to
22.05.
</para>
</listitem>
</itemizedlist>
<section xml:id="sec-release-21.11-highlights">
<title>Highlights</title>
<itemizedlist spacing="compact">
<itemizedlist>
<listitem>
<para>
PHP now defaults to PHP 8.0, updated from 7.4.
</para>
</listitem>
<listitem>
<para>
kOps now defaults to 1.21.0, which uses containerd as the
default runtime.
</para>
</listitem>
<listitem>
<para>
<literal>python3</literal> now defaults to Python 3.9, updated
from Python 3.8.
</para>
</listitem>
<listitem>
<para>
PostgreSQL now defaults to major version 13.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-release-21.11-new-services">
@ -34,6 +51,13 @@
<link xlink:href="options.html#opt-services.brtbk.instances">services.btrbk</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/xrelkd/clipcat/">clipcat</link>,
an X11 clipboard manager written in Rust. Available at
[services.clipcat](options.html#o pt-services.clipcat.enable).
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/maxmind/geoipupdate">geoipupdate</link>,
@ -41,6 +65,13 @@
<link xlink:href="options.html#opt-services.geoipupdate.enable">services.geoipupdate</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://www.isc.org/kea/">Kea</link>, ISCs
2nd generation DHCP and DDNS server suite. Available at
<link xlink:href="options.html#opt-services.kea">services.kea</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://sr.ht">sourcehut</link>, a
@ -65,6 +96,35 @@
be able to access programmers supported by flashrom.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://vikunja.io">vikunja</link>, a to-do
list app. Available as
<link linkend="opt-services.vikunja.enable">services.vikunja</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://www.snapraid.it/">snapraid</link>, a
backup program for disk arrays. Available as
<link linkend="opt-snapraid.enable">snapraid</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/hockeypuck/hockeypuck">Hockeypuck</link>,
a OpenPGP Key Server. Available as
<link linkend="opt-services.hockeypuck.enable">services.hockeypuck</link>.
</para>
</listitem>
<listitem>
<para>
<link xlink:href="https://github.com/buildkite/buildkite-agent-metrics">buildkite-agent-metrics</link>,
a command-line tool for collecting Buildkite agent metrics,
now has a Prometheus exporter available as
<link linkend="opt-services.prometheus.exporters.buildkite-agent.enable">services.prometheus.exporters.buildkite-agent</link>.
</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="sec-release-21.11-incompatibilities">
@ -342,6 +402,13 @@
release instead of the old 2.7.7 version.
</para>
</listitem>
<listitem>
<para>
The <literal>pulseeffects</literal> package updated to
<link xlink:href="https://github.com/wwmm/easyeffects/releases/tag/v6.0.0">version
4.x</link> and renamed to <literal>easyeffects</literal>.
</para>
</listitem>
<listitem>
<para>
The <literal>libwnck</literal> package now defaults to the 3.x
@ -468,6 +535,26 @@
changelog</link>.
</para>
</listitem>
<listitem>
<para>
<literal>icingaweb2</literal> was upgraded to a new release
which requires a manual database upgrade, see
<link xlink:href="https://github.com/Icinga/icingaweb2/releases/tag/v2.9.0">upstream
changelog</link>.
</para>
</listitem>
<listitem>
<para>
The <literal>isabelle</literal> package has been upgraded from
2020 to 2021
</para>
</listitem>
<listitem>
<para>
the <literal>mingw-64</literal> package has been upgraded from
6.0.0 to 9.0.0
</para>
</listitem>
<listitem>
<para>
<literal>tt-rss</literal> was upgraded to the commit on
@ -511,6 +598,118 @@
<literal>rxvt-unicode</literal> explicitly.
</para>
</listitem>
<listitem>
<para>
<literal>python3</literal> now defaults to Python 3.9. Python
3.9 introduces many deprecation warnings, please look at the
<link xlink:href="https://docs.python.org/3/whatsnew/3.9.html">Whats
New In Python 3.9 post</link> for more information.
</para>
</listitem>
<listitem>
<para>
The <literal>claws-mail</literal> package now references the
new GTK+ 3 release branch, major version 4. To use the GTK+ 2
releases, one can install the
<literal>claws-mail-gtk2</literal> package.
</para>
</listitem>
<listitem>
<para>
The wordpress module provides a new interface which allows to
use different webservers with the new option
<link xlink:href="options.html#opt-services.wordpress.webserver"><literal>services.wordpress.webserver</literal></link>.
Currently <literal>httpd</literal> and
<literal>nginx</literal> are supported. The definitions of
wordpress sites should now be set in
<link xlink:href="options.html#opt-services.wordpress.sites"><literal>services.wordpress.sites</literal></link>.
</para>
<para>
Sites definitions that use the old interface are automatically
migrated in the new option. This backward compatibility will
be removed in 22.05.
</para>
</listitem>
<listitem>
<para>
The order of NSS (host) modules has been brought in line with
upstream recommendations:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
The <literal>myhostname</literal> module is placed before
the <literal>resolve</literal> (optional) and
<literal>dns</literal> entries, but after
<literal>file</literal> (to allow overriding via
<literal>/etc/hosts</literal> /
<literal>networking.extraHosts</literal>, and prevent ISPs
with catchall-DNS resolvers from hijacking
<literal>.localhost</literal> domains)
</para>
</listitem>
<listitem>
<para>
The <literal>mymachines</literal> module, which provides
hostname resolution for local containers (registered with
<literal>systemd-machined</literal>) is placed to the
front, to make sure its mappings are preferred over other
resolvers.
</para>
</listitem>
<listitem>
<para>
If systemd-networkd is enabled, the
<literal>resolve</literal> module is placed before
<literal>files</literal> and
<literal>myhostname</literal>, as it provides the same
logic internally, with caching.
</para>
</listitem>
<listitem>
<para>
The <literal>mdns(_minimal)</literal> module has been
updated to the new priorities.
</para>
</listitem>
</itemizedlist>
<para>
If you use your own NSS host modules, make sure to update your
priorities according to these rules:
</para>
<itemizedlist spacing="compact">
<listitem>
<para>
NSS modules which should be queried before
<literal>resolved</literal> DNS resolution should use
mkBefore.
</para>
</listitem>
<listitem>
<para>
NSS modules which should be queried after
<literal>resolved</literal>, <literal>files</literal> and
<literal>myhostname</literal>, but before
<literal>dns</literal> should use the default priority
</para>
</listitem>
<listitem>
<para>
NSS modules which should come after <literal>dns</literal>
should use mkAfter.
</para>
</listitem>
</itemizedlist>
</listitem>
<listitem>
<para>
The
<link xlink:href="options.html#opt-networking.wireless.iwd.enable">networking.wireless.iwd</link>
module has a new
<link xlink:href="options.html#opt-networking.wireless.iwd.settings">networking.wireless.iwd.settings</link>
option.
</para>
</listitem>
</itemizedlist>
</section>
</section>

View File

@ -108,7 +108,23 @@
</arg>
</group> <replaceable>name</replaceable>
</arg>
<sbr />
<arg>
<option>--build-host</option> <replaceable>host</replaceable>
</arg>
<arg>
<option>--target-host</option> <replaceable>host</replaceable>
</arg>
<arg>
<option>--use-remote-sudo</option>
</arg>
<sbr />
<arg>
<option>--show-trace</option>
</arg>

View File

@ -18,12 +18,13 @@
<para>
If you encounter problems, please report them on the
<literal
xlink:href="https://discourse.nixos.org">Discourse</literal> or
on the <link
xlink:href="https://discourse.nixos.org">Discourse</literal>,
the <link
xlink:href="https://matrix.to/#nix:nixos.org">Matrix room</link>,
or on the <link
xlink:href="irc://irc.libera.chat/#nixos">
<literal>#nixos</literal> channel on Libera.Chat</link>, or
consider
<link
<literal>#nixos</literal> channel on Libera.Chat</link>.
Alternatively, consider <link
xlink:href="#chap-contributing">
contributing to this manual</link>. Bugs should be
reported in

View File

@ -2,24 +2,43 @@
In addition to numerous new and upgraded packages, this release has the following highlights:
- Support is planned until the end of April 2022, handing over to 22.05.
- Support is planned until the end of June 2022, handing over to 22.05.
## Highlights {#sec-release-21.11-highlights}
- PHP now defaults to PHP 8.0, updated from 7.4.
- kOps now defaults to 1.21.0, which uses containerd as the default runtime.
- `python3` now defaults to Python 3.9, updated from Python 3.8.
- PostgreSQL now defaults to major version 13.
## New Services {#sec-release-21.11-new-services}
- [btrbk](https://digint.ch/btrbk/index.html), a backup tool for btrfs subvolumes, taking advantage of btrfs specific capabilities to create atomic snapshots and transfer them incrementally to your backup locations. Available as [services.btrbk](options.html#opt-services.brtbk.instances).
- [clipcat](https://github.com/xrelkd/clipcat/), an X11 clipboard manager written in Rust. Available at [services.clipcat](options.html#o
pt-services.clipcat.enable).
- [geoipupdate](https://github.com/maxmind/geoipupdate), a GeoIP database updater from MaxMind. Available as [services.geoipupdate](options.html#opt-services.geoipupdate.enable).
- [Kea](https://www.isc.org/kea/), ISCs 2nd generation DHCP and DDNS server suite. Available at [services.kea](options.html#opt-services.kea).
- [sourcehut](https://sr.ht), a collection of tools useful for software development. Available as [services.sourcehut](options.html#opt-services.sourcehut.enable).
- [ucarp](https://download.pureftpd.org/pub/ucarp/README), an userspace implementation of the Common Address Redundancy Protocol (CARP). Available as [networking.ucarp](options.html#opt-networking.ucarp.enable).
- Users of flashrom should migrate to [programs.flashrom.enable](options.html#opt-programs.flashrom.enable) and add themselves to the `flashrom` group to be able to access programmers supported by flashrom.
- [vikunja](https://vikunja.io), a to-do list app. Available as [services.vikunja](#opt-services.vikunja.enable).
- [snapraid](https://www.snapraid.it/), a backup program for disk arrays.
Available as [snapraid](#opt-snapraid.enable).
- [Hockeypuck](https://github.com/hockeypuck/hockeypuck), a OpenPGP Key Server. Available as [services.hockeypuck](#opt-services.hockeypuck.enable).
- [buildkite-agent-metrics](https://github.com/buildkite/buildkite-agent-metrics), a command-line tool for collecting Buildkite agent metrics, now has a Prometheus exporter available as [services.prometheus.exporters.buildkite-agent](#opt-services.prometheus.exporters.buildkite-agent.enable).
## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
- The `staticjinja` package has been upgraded from 1.0.4 to 3.0.1
@ -84,6 +103,8 @@ In addition to numerous new and upgraded packages, this release has the followin
* The `antlr` package now defaults to the 4.x release instead of the
old 2.7.7 version.
* The `pulseeffects` package updated to [version 4.x](https://github.com/wwmm/easyeffects/releases/tag/v6.0.0) and renamed to `easyeffects`.
* The `libwnck` package now defaults to the 3.x release instead of the
old 2.31.0 version.
@ -115,6 +136,12 @@ In addition to numerous new and upgraded packages, this release has the followin
- `yggdrasil` was upgraded to a new major release with breaking changes, see [upstream changelog](https://github.com/yggdrasil-network/yggdrasil-go/releases/tag/v0.4.0).
- `icingaweb2` was upgraded to a new release which requires a manual database upgrade, see [upstream changelog](https://github.com/Icinga/icingaweb2/releases/tag/v2.9.0).
- The `isabelle` package has been upgraded from 2020 to 2021
- the `mingw-64` package has been upgraded from 6.0.0 to 9.0.0
- `tt-rss` was upgraded to the commit on 2021-06-21, which has breaking changes, see [this thread](https://community.tt-rss.org/t/rip-config-php-hello-classes-config-php/4337) in the tt-rss forums for details.
## Other Notable Changes {#sec-release-21.11-notable-changes}
@ -124,3 +151,37 @@ In addition to numerous new and upgraded packages, this release has the followin
However, if [`services.fail2ban.enable`](options.html#opt-services.fail2ban.enable) is `true`, the `fail2ban` will override the verbosity to `"VERBOSE"`, so that `fail2ban` can observe the failed login attempts from the SSH logs.
- Sway: The terminal emulator `rxvt-unicode` is no longer installed by default via `programs.sway.extraPackages`. The current default configuration uses `alacritty` (and soon `foot`) so this is only an issue when using a customized configuration and not installing `rxvt-unicode` explicitly.
- `python3` now defaults to Python 3.9. Python 3.9 introduces many deprecation warnings, please look at the [What's New In Python 3.9 post](https://docs.python.org/3/whatsnew/3.9.html) for more information.
- The `claws-mail` package now references the new GTK+ 3 release branch, major version 4. To use the GTK+ 2 releases, one can install the `claws-mail-gtk2` package.
- The wordpress module provides a new interface which allows to use different webservers with the new option [`services.wordpress.webserver`](options.html#opt-services.wordpress.webserver). Currently `httpd` and `nginx` are supported. The definitions of wordpress sites should now be set in [`services.wordpress.sites`](options.html#opt-services.wordpress.sites).
Sites definitions that use the old interface are automatically migrated in the new option. This backward compatibility will be removed in 22.05.
- The order of NSS (host) modules has been brought in line with upstream
recommendations:
- The `myhostname` module is placed before the `resolve` (optional) and `dns`
entries, but after `file` (to allow overriding via `/etc/hosts` /
`networking.extraHosts`, and prevent ISPs with catchall-DNS resolvers from
hijacking `.localhost` domains)
- The `mymachines` module, which provides hostname resolution for local
containers (registered with `systemd-machined`) is placed to the front, to
make sure its mappings are preferred over other resolvers.
- If systemd-networkd is enabled, the `resolve` module is placed before
`files` and `myhostname`, as it provides the same logic internally, with
caching.
- The `mdns(_minimal)` module has been updated to the new priorities.
If you use your own NSS host modules, make sure to update your priorities
according to these rules:
- NSS modules which should be queried before `resolved` DNS resolution should
use mkBefore.
- NSS modules which should be queried after `resolved`, `files` and
`myhostname`, but before `dns` should use the default priority
- NSS modules which should come after `dns` should use mkAfter.
- The [networking.wireless.iwd](options.html#opt-networking.wireless.iwd.enable) module has a new [networking.wireless.iwd.settings](options.html#opt-networking.wireless.iwd.settings) option.

View File

@ -292,7 +292,12 @@ class Machine:
net_frontend += "," + args["netFrontendArgs"]
start_command = (
"qemu-kvm -m 384 " + net_backend + " " + net_frontend + " $QEMU_OPTS "
args.get("qemuBinary", "qemu-kvm")
+ " -m 384 "
+ net_backend
+ " "
+ net_frontend
+ " $QEMU_OPTS "
)
if "hda" in args:
@ -494,7 +499,7 @@ class Machine:
output += out
return output
def wait_until_succeeds(self, command: str) -> str:
def wait_until_succeeds(self, command: str, timeout: int = 900) -> str:
"""Wait until a command returns success and return its output.
Throws an exception on timeout.
"""
@ -506,7 +511,7 @@ class Machine:
return status == 0
with self.nested("waiting for success: {}".format(command)):
retry(check_success)
retry(check_success, timeout)
return output
def wait_until_fails(self, command: str) -> str:

View File

@ -124,8 +124,8 @@ with lib;
group = mkBefore [ "files" ];
shadow = mkBefore [ "files" ];
hosts = mkMerge [
(mkBefore [ "files" ])
(mkAfter [ "dns" ])
(mkOrder 998 [ "files" ])
(mkOrder 1499 [ "dns" ])
];
services = mkBefore [ "files" ];
};

View File

@ -127,6 +127,15 @@ let
'';
};
options = mkOption {
default = [ "defaults" ];
example = [ "nofail" ];
type = types.listOf types.nonEmptyStr;
description = ''
Options used to mount the swap.
'';
};
deviceName = mkOption {
type = types.str;
internal = true;
@ -215,7 +224,7 @@ in
fi
''}
${optionalString sw.randomEncryption.enable ''
cryptsetup plainOpen -c ${sw.randomEncryption.cipher} -d ${sw.randomEncryption.source} ${sw.device} ${sw.deviceName}
cryptsetup plainOpen -c ${sw.randomEncryption.cipher} -d ${sw.randomEncryption.source} ${optionalString (sw.discardPolicy != null) "--allow-discards"} ${sw.device} ${sw.deviceName}
mkswap ${sw.realDevice}
''}
'';

View File

@ -9,7 +9,7 @@ with lib;
hardware.sensor.iio = {
enable = mkOption {
description = ''
Enable this option to support IIO sensors.
Enable this option to support IIO sensors with iio-sensor-proxy.
IIO sensors are used for orientation and ambient light
sensors on some mobile devices.

View File

@ -1,6 +1,7 @@
{
x86_64-linux = "/nix/store/d1ppfhjhdwcsb4npfzyifv5z8i00fzsk-nix-2.3.11";
i686-linux = "/nix/store/c6ikndcrzwpfn2sb5b9xb1f17p9b8iga-nix-2.3.11";
aarch64-linux = "/nix/store/fb0lfrn0m8s197d264jzd64vhz9c8zbx-nix-2.3.11";
x86_64-darwin = "/nix/store/qvb86ffv08q3r66qbd6nqifz425lyyhf-nix-2.3.11";
x86_64-linux = "/nix/store/qsgz2hhn6mzlzp53a7pwf9z2pq3l5z6h-nix-2.3.14";
i686-linux = "/nix/store/1yw40bj04lykisw2jilq06lir3k9ga4a-nix-2.3.14";
aarch64-linux = "/nix/store/32yzwmynmjxfrkb6y6l55liaqdrgkj4a-nix-2.3.14";
x86_64-darwin = "/nix/store/06j0vi2d13w4l0p3jsigq7lk4x6gkycj-nix-2.3.14";
aarch64-darwin = "/nix/store/77wi7vpbrghw5rgws25w30bwb8yggnk9-nix-2.3.14";
}

View File

@ -1,11 +1 @@
{lib, stdenv, boost, cmake, pkg-config, nix, ... }:
stdenv.mkDerivation rec {
name = "nixos-option";
src = ./.;
nativeBuildInputs = [ cmake pkg-config ];
buildInputs = [ boost nix ];
meta = with lib; {
license = licenses.lgpl2Plus;
maintainers = with maintainers; [ chkno ];
};
}
{ pkgs, ... }: pkgs.nixos-option

View File

@ -42,7 +42,7 @@ let
nixos-option =
if lib.versionAtLeast (lib.getVersion config.nix.package) "2.4pre"
then null
else pkgs.callPackage ./nixos-option { };
else pkgs.nixos-option;
nixos-version = makeProg {
name = "nixos-version";

View File

@ -229,7 +229,7 @@ in
grafana = 196;
skydns = 197;
# ripple-rest = 198; # unused, removed 2017-08-12
nix-serve = 199;
# nix-serve = 199; # unused, removed 2020-12-12
tvheadend = 200;
uwsgi = 201;
gitit = 202;

View File

@ -388,6 +388,7 @@
./services/hardware/bluetooth.nix
./services/hardware/bolt.nix
./services/hardware/brltty.nix
./services/hardware/ddccontrol.nix
./services/hardware/fancontrol.nix
./services/hardware/freefall.nix
./services/hardware/fwupd.nix
@ -474,6 +475,7 @@
./services/misc/calibre-server.nix
./services/misc/cfdyndns.nix
./services/misc/clipmenu.nix
./services/misc/clipcat.nix
./services/misc/cpuminer-cryptonight.nix
./services/misc/cgminer.nix
./services/misc/confd.nix
@ -726,6 +728,7 @@
./services/networking/iwd.nix
./services/networking/jicofo.nix
./services/networking/jitsi-videobridge.nix
./services/networking/kea.nix
./services/networking/keepalived/default.nix
./services/networking/keybase.nix
./services/networking/kippo.nix
@ -847,6 +850,7 @@
./services/networking/ucarp.nix
./services/networking/unbound.nix
./services/networking/unifi.nix
./services/video/unifi-video.nix
./services/networking/v2ray.nix
./services/networking/vsftpd.nix
./services/networking/wakeonlan.nix
@ -883,6 +887,7 @@
./services/security/fprot.nix
./services/security/haka.nix
./services/security/haveged.nix
./services/security/hockeypuck.nix
./services/security/hologram-server.nix
./services/security/hologram-agent.nix
./services/security/munge.nix
@ -968,6 +973,7 @@
./services/web-apps/trilium.nix
./services/web-apps/selfoss.nix
./services/web-apps/shiori.nix
./services/web-apps/vikunja.nix
./services/web-apps/virtlyst.nix
./services/web-apps/wiki-js.nix
./services/web-apps/whitebophir.nix
@ -1101,6 +1107,7 @@
./tasks/network-interfaces-systemd.nix
./tasks/network-interfaces-scripted.nix
./tasks/scsi-link-power-management.nix
./tasks/snapraid.nix
./tasks/swraid.nix
./tasks/trackpoint.nix
./tasks/powertop.nix

View File

@ -10,5 +10,8 @@ in {
config = mkIf cfg.enable {
security.wrappers.udevil.source = "${lib.getBin pkgs.udevil}/bin/udevil";
systemd.packages = [ pkgs.udevil ];
systemd.services."devmon@".wantedBy = [ "multi-user.target" ];
};
}

View File

@ -10,14 +10,16 @@ in
{
options.programs.xwayland = {
enable = mkEnableOption ''
Xwayland X server allows running X programs on a Wayland compositor.
'';
enable = mkEnableOption "Xwayland (an X server for interfacing X11 apps with the Wayland protocol)";
defaultFontPath = mkOption {
type = types.str;
default = optionalString config.fonts.fontDir.enable
"/run/current-system/sw/share/X11/fonts";
defaultText = literalExample ''
optionalString config.fonts.fontDir.enable
"/run/current-system/sw/share/X11/fonts";
'';
description = ''
Default font path. Setting this option causes Xwayland to be rebuilt.
'';
@ -25,7 +27,15 @@ in
package = mkOption {
type = types.path;
description = "The Xwayland package";
default = pkgs.xwayland.override (oldArgs: {
inherit (cfg) defaultFontPath;
});
defaultText = literalExample ''
pkgs.xwayland.override (oldArgs: {
inherit (config.programs.xwayland) defaultFontPath;
});
'';
description = "The Xwayland package to use.";
};
};
@ -37,9 +47,5 @@ in
environment.systemPackages = [ cfg.package ];
programs.xwayland.package = pkgs.xwayland.override (oldArgs: {
inherit (cfg) defaultFontPath;
});
};
}

View File

@ -53,7 +53,7 @@ in
};
shellAliases = mkOption {
default = {};
default = { };
description = ''
Set of aliases for zsh shell, which overrides <option>environment.shellAliases</option>.
See <option>environment.shellAliases</option> for an option format description.
@ -118,7 +118,9 @@ in
setOptions = mkOption {
type = types.listOf types.str;
default = [
"HIST_IGNORE_DUPS" "SHARE_HISTORY" "HIST_FCNTL_LOCK"
"HIST_IGNORE_DUPS"
"SHARE_HISTORY"
"HIST_FCNTL_LOCK"
];
example = [ "EXTENDED_HISTORY" "RM_STAR_WAIT" ];
description = ''
@ -278,15 +280,29 @@ in
environment.etc.zinputrc.source = ./zinputrc;
environment.systemPackages = [ pkgs.zsh ]
++ optional cfg.enableCompletion pkgs.nix-zsh-completions;
environment.systemPackages =
let
completions =
if lib.versionAtLeast (lib.getVersion config.nix.package) "2.4pre"
then
pkgs.nix-zsh-completions.overrideAttrs
(_: {
postInstall = ''
rm $out/share/zsh/site-functions/_nix
'';
})
else pkgs.nix-zsh-completions;
in
[ pkgs.zsh ]
++ optional cfg.enableCompletion completions;
environment.pathsToLink = optional cfg.enableCompletion "/share/zsh";
#users.defaultUserShell = mkDefault "/run/current-system/sw/bin/zsh";
environment.shells =
[ "/run/current-system/sw/bin/zsh"
[
"/run/current-system/sw/bin/zsh"
"${pkgs.zsh}/bin/zsh"
];

View File

@ -14,15 +14,21 @@ let
requires = [ "postgresql.service" ];
path = [ pkgs.coreutils pkgs.gzip config.services.postgresql.package ];
script = ''
set -e -o pipefail
umask 0077 # ensure backup is only readable by postgres user
if [ -e ${cfg.location}/${db}.sql.gz ]; then
${pkgs.coreutils}/bin/mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
mv ${cfg.location}/${db}.sql.gz ${cfg.location}/${db}.prev.sql.gz
fi
${dumpCmd} | \
${pkgs.gzip}/bin/gzip -c > ${cfg.location}/${db}.sql.gz
gzip -c > ${cfg.location}/${db}.in-progress.sql.gz
mv ${cfg.location}/${db}.in-progress.sql.gz ${cfg.location}/${db}.sql.gz
'';
serviceConfig = {
@ -113,12 +119,12 @@ in {
})
(mkIf (cfg.enable && cfg.backupAll) {
systemd.services.postgresqlBackup =
postgresqlBackupService "all" "${config.services.postgresql.package}/bin/pg_dumpall";
postgresqlBackupService "all" "pg_dumpall";
})
(mkIf (cfg.enable && !cfg.backupAll) {
systemd.services = listToAttrs (map (db:
let
cmd = "${config.services.postgresql.package}/bin/pg_dump ${cfg.pgdumpOptions} ${db}";
cmd = "pg_dump ${cfg.pgdumpOptions} ${db}";
in {
name = "postgresqlBackup-${db}";
value = postgresqlBackupService db cmd;

View File

@ -108,8 +108,8 @@ in {
type = types.attrsOf (types.submodule ({config, options, ...}: {
freeformType = datasetSettingsType;
options = commonOptions // datasetOptions;
config.use_template = mkAliasDefinitions (options.useTemplate or {});
config.process_children_only = mkAliasDefinitions (options.processChildrenOnly or {});
config.use_template = mkAliasDefinitions (mkDefault options.useTemplate or {});
config.process_children_only = mkAliasDefinitions (mkDefault options.processChildrenOnly or {});
}));
default = {};
description = "Datasets to snapshot.";

View File

@ -5,14 +5,15 @@ with lib;
let
cfg = config.services.syncoid;
# Extract pool names of local datasets (ones that don't contain "@") that
# have the specified type (either "source" or "target")
getPools = type: unique (map (d: head (builtins.match "([^/]+).*" d)) (
# Filter local datasets
filter (d: !hasInfix "@" d)
# Get datasets of the specified type
(catAttrs type (attrValues cfg.commands))
));
# Extract the pool name of a local dataset (any dataset not containing "@")
localPoolName = d: optionals (d != null) (
let m = builtins.match "([^/@]+)[^@]*" d; in
optionals (m != null) m);
# Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
escapeUnitName = name:
lib.concatMapStrings (s: if lib.isList s then "-" else s)
(builtins.split "[^a-zA-Z0-9_.\\-]+" name);
in {
# Interface
@ -77,6 +78,14 @@ in {
'';
};
service = mkOption {
type = types.attrs;
default = {};
description = ''
Systemd configuration common to all syncoid services.
'';
};
commands = mkOption {
type = types.attrsOf (types.submodule ({ name, ... }: {
options = {
@ -99,13 +108,7 @@ in {
'';
};
recursive = mkOption {
type = types.bool;
default = false;
description = ''
Whether to also transfer child datasets.
'';
};
recursive = mkEnableOption ''the transfer of child datasets'';
sshKey = mkOption {
type = types.nullOr types.path;
@ -145,6 +148,14 @@ in {
'';
};
service = mkOption {
type = types.attrs;
default = {};
description = ''
Systemd configuration specific to this syncoid service.
'';
};
extraArgs = mkOption {
type = types.listOf types.str;
default = [];
@ -170,11 +181,15 @@ in {
# Implementation
config = mkIf cfg.enable {
users = {
users = {
users = mkIf (cfg.user == "syncoid") {
syncoid = {
group = cfg.group;
isSystemUser = true;
# For syncoid to be able to create /var/lib/syncoid/.ssh/
# and to use custom ssh_config or known_hosts.
home = "/var/lib/syncoid";
createHome = false;
};
};
groups = mkIf (cfg.group == "syncoid") {
@ -182,35 +197,99 @@ in {
};
};
systemd.services.syncoid = {
description = "Syncoid ZFS synchronization service";
script = concatMapStringsSep "\n" (c: lib.escapeShellArgs
([ "${pkgs.sanoid}/bin/syncoid" ]
++ (optionals c.useCommonArgs cfg.commonArgs)
++ (optional c.recursive "-r")
++ (optionals (c.sshKey != null) [ "--sshkey" c.sshKey ])
++ c.extraArgs
++ [ "--sendoptions" c.sendOptions
"--recvoptions" c.recvOptions
"--no-privilege-elevation"
c.source c.target
])) (attrValues cfg.commands);
after = [ "zfs.target" ];
serviceConfig = {
ExecStartPre = let
allowCmd = permissions: pool: lib.escapeShellArgs [
"+/run/booted-system/sw/bin/zfs" "allow"
cfg.user (concatStringsSep "," permissions) pool
];
in
(map (allowCmd [ "hold" "send" "snapshot" "destroy" ]) (getPools "source")) ++
(map (allowCmd [ "create" "mount" "receive" "rollback" ]) (getPools "target"));
User = cfg.user;
Group = cfg.group;
};
startAt = cfg.interval;
};
systemd.services = mapAttrs' (name: c:
nameValuePair "syncoid-${escapeUnitName name}" (mkMerge [
{ description = "Syncoid ZFS synchronization from ${c.source} to ${c.target}";
after = [ "zfs.target" ];
startAt = cfg.interval;
# syncoid may need zpool to get feature@extensible_dataset
path = [ "/run/booted-system/sw/bin/" ];
serviceConfig = {
ExecStartPre =
map (pool: lib.escapeShellArgs [
"+/run/booted-system/sw/bin/zfs" "allow"
cfg.user "bookmark,hold,send,snapshot,destroy" pool
# Permissions snapshot and destroy are in case --no-sync-snap is not used
]) (localPoolName c.source) ++
map (pool: lib.escapeShellArgs [
"+/run/booted-system/sw/bin/zfs" "allow"
cfg.user "create,mount,receive,rollback" pool
]) (localPoolName c.target);
ExecStart = lib.escapeShellArgs ([ "${pkgs.sanoid}/bin/syncoid" ]
++ optionals c.useCommonArgs cfg.commonArgs
++ optional c.recursive "-r"
++ optionals (c.sshKey != null) [ "--sshkey" c.sshKey ]
++ c.extraArgs
++ [ "--sendoptions" c.sendOptions
"--recvoptions" c.recvOptions
"--no-privilege-elevation"
c.source c.target
]);
User = cfg.user;
Group = cfg.group;
StateDirectory = [ "syncoid" ];
StateDirectoryMode = "700";
# Prevent SSH control sockets of different syncoid services from interfering
PrivateTmp = true;
# Permissive access to /proc because syncoid
# calls ps(1) to detect ongoing `zfs receive`.
ProcSubset = "all";
ProtectProc = "default";
# The following options are only for optimizing:
# systemd-analyze security | grep syncoid-'*'
AmbientCapabilities = "";
CapabilityBoundingSet = "";
DeviceAllow = ["/dev/zfs"];
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateMounts = true;
PrivateNetwork = mkDefault false;
PrivateUsers = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RootDirectory = "/run/syncoid/${escapeUnitName name}";
RootDirectoryStartOnly = true;
BindPaths = [ "/dev/zfs" ];
BindReadOnlyPaths = [ builtins.storeDir "/etc" "/run" "/bin/sh" ];
# Avoid useless mounting of RootDirectory= in the own RootDirectory= of ExecStart='s mount namespace.
InaccessiblePaths = ["-+/run/syncoid/${escapeUnitName name}"];
MountAPIVFS = true;
# Create RootDirectory= in the host's mount namespace.
RuntimeDirectory = [ "syncoid/${escapeUnitName name}" ];
RuntimeDirectoryMode = "700";
SystemCallFilter = [
"@system-service"
# Groups in @system-service which do not contain a syscall listed by:
# perf stat -x, 2>perf.log -e 'syscalls:sys_enter_*' syncoid …
# awk >perf.syscalls -F "," '$1 > 0 {sub("syscalls:sys_enter_","",$3); print $3}' perf.log
# systemd-analyze syscall-filter | grep -v -e '#' | sed -e ':loop; /^[^ ]/N; s/\n //; t loop' | grep $(printf ' -e \\<%s\\>' $(cat perf.syscalls)) | cut -f 1 -d ' '
"~@aio" "~@chown" "~@keyring" "~@memlock" "~@privileged"
"~@resources" "~@setuid" "~@sync" "~@timer"
];
SystemCallArchitectures = "native";
# This is for BindPaths= and BindReadOnlyPaths=
# to allow traversal of directories they create in RootDirectory=.
UMask = "0066";
};
}
cfg.service
c.service
])) cfg.commands;
};
meta.maintainers = with maintainers; [ lopsided98 ];
meta.maintainers = with maintainers; [ julm lopsided98 ];
}

View File

@ -35,10 +35,20 @@ in
token = mkOption {
type = types.str;
description = "The k3s token to use when connecting to the server. This option only makes sense for an agent.";
description = ''
The k3s token to use when connecting to the server. This option only makes sense for an agent.
WARNING: This option will expose store your token unencrypted world-readable in the nix store.
If this is undesired use the tokenFile option instead.
'';
default = "";
};
tokenFile = mkOption {
type = types.nullOr types.path;
description = "File path containing k3s token to use when connecting to the server. This option only makes sense for an agent.";
default = null;
};
docker = mkOption {
type = types.bool;
default = false;
@ -57,6 +67,12 @@ in
default = false;
description = "Only run the server. This option only makes sense for a server.";
};
configPath = mkOption {
type = types.nullOr types.path;
default = null;
description = "File path containing the k3s YAML config. This is useful when the config is generated (for example on boot).";
};
};
# implementation
@ -64,12 +80,12 @@ in
config = mkIf cfg.enable {
assertions = [
{
assertion = cfg.role == "agent" -> cfg.serverAddr != "";
message = "serverAddr should be set if role is 'agent'";
assertion = cfg.role == "agent" -> (cfg.configPath != null || cfg.serverAddr != "");
message = "serverAddr or configPath (with 'server' key) should be set if role is 'agent'";
}
{
assertion = cfg.role == "agent" -> cfg.token != "";
message = "token should be set if role is 'agent'";
assertion = cfg.role == "agent" -> cfg.configPath != null || cfg.tokenFile != null || cfg.token != "";
message = "token or tokenFile or configPath (with 'token' or 'token-file' keys) should be set if role is 'agent'";
}
];
@ -105,7 +121,10 @@ in
"${cfg.package}/bin/k3s ${cfg.role}"
] ++ (optional cfg.docker "--docker")
++ (optional cfg.disableAgent "--disable-agent")
++ (optional (cfg.role == "agent") "--server ${cfg.serverAddr} --token ${cfg.token}")
++ (optional (cfg.serverAddr != "") "--server ${cfg.serverAddr}")
++ (optional (cfg.token != "") "--token ${cfg.token}")
++ (optional (cfg.tokenFile != null) "--token-file ${cfg.tokenFile}")
++ (optional (cfg.configPath != null) "--config ${cfg.configPath}")
++ [ cfg.extraFlags ]
);
};

View File

@ -105,7 +105,7 @@ let
pkgs.stdenv.mkDerivation {
name = "hercules-ci-check-system-nix-src";
inherit (config.nix.package) src patches;
configurePhase = ":";
dontConfigure = true;
buildPhase = ''
echo "Checking in-memory pathInfoCache expiry"
if ! grep 'PathInfoCacheValue' src/libstore/store-api.hh >/dev/null; then

View File

@ -293,7 +293,8 @@ in
# Note: when changing the default, make it conditional on
# system.stateVersion to maintain compatibility with existing
# systems!
mkDefault (if versionAtLeast config.system.stateVersion "20.03" then pkgs.postgresql_11
mkDefault (if versionAtLeast config.system.stateVersion "21.11" then pkgs.postgresql_13
else if versionAtLeast config.system.stateVersion "20.03" then pkgs.postgresql_11
else if versionAtLeast config.system.stateVersion "17.09" then pkgs.postgresql_9_6
else throw "postgresql_9_5 was removed, please upgrade your postgresql version.");

View File

@ -0,0 +1,197 @@
{
"bluez5.features.device": [
{
"name": "Air 1 Plus",
"no-features": [
"hw-volume-mic"
]
},
{
"name": "AirPods",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl"
]
},
{
"name": "AirPods Pro",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl"
]
},
{
"name": "AXLOIE Goin",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl"
]
},
{
"name": "JBL Endurance RUN BT",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl",
"sbc-xq"
]
},
{
"name": "JBL LIVE650BTNC"
},
{
"name": "Soundcore Life P2-L",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl"
]
},
{
"name": "Urbanista Stockholm Plus",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl"
]
},
{
"address": "~^94:16:25:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^9c:64:8b:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^a0:e9:db:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^0c:a6:94:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^00:14:02:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^44:5e:f3:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^d4:9c:28:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^00:18:6b:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^b8:ad:3e:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^a0:e9:db:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^00:24:1c:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^00:11:b1:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^a4:15:66:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^00:14:f1:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^00:26:7e:",
"no-features": [
"hw-volume"
]
},
{
"address": "~^90:03:b7:",
"no-features": [
"hw-volume"
]
}
],
"bluez5.features.adapter": [
{
"bus-type": "usb",
"vendor-id": "usb:0bda"
},
{
"bus-type": "usb",
"no-features": [
"msbc-alt1-rtl"
]
},
{
"no-features": [
"msbc-alt1-rtl"
]
}
],
"bluez5.features.kernel": [
{
"sysname": "Linux",
"release": "~^[0-4]\\.",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl"
]
},
{
"sysname": "Linux",
"release": "~^5\\.[1-7]\\.",
"no-features": [
"msbc-alt1",
"msbc-alt1-rtl"
]
},
{
"sysname": "Linux",
"release": "~^5\\.(8|9|10)\\.",
"no-features": [
"msbc-alt1"
]
},
{
"no-features": []
}
]
}

View File

@ -7,7 +7,7 @@
},
"context.modules": [
{
"name": "libpipewire-module-rtkit",
"name": "libpipewire-module-rt",
"args": {},
"flags": [
"ifexists",

View File

@ -15,6 +15,7 @@ let
defaults = {
alsa-monitor = (builtins.fromJSON (builtins.readFile ./alsa-monitor.conf.json));
bluez-monitor = (builtins.fromJSON (builtins.readFile ./bluez-monitor.conf.json));
bluez-hardware = (builtins.fromJSON (builtins.readFile ./bluez-hardware.conf.json));
media-session = (builtins.fromJSON (builtins.readFile ./media-session.conf.json));
v4l2-monitor = (builtins.fromJSON (builtins.readFile ./v4l2-monitor.conf.json));
};
@ -22,6 +23,7 @@ let
configs = {
alsa-monitor = recursiveUpdate defaults.alsa-monitor cfg.config.alsa-monitor;
bluez-monitor = recursiveUpdate defaults.bluez-monitor cfg.config.bluez-monitor;
bluez-hardware = defaults.bluez-hardware;
media-session = recursiveUpdate defaults.media-session cfg.config.media-session;
v4l2-monitor = recursiveUpdate defaults.v4l2-monitor cfg.config.v4l2-monitor;
};
@ -120,6 +122,10 @@ in {
mkIf config.services.pipewire.pulse.enable {
source = json.generate "bluez-monitor.conf" configs.bluez-monitor;
};
environment.etc."pipewire/media-session.d/bluez-hardware.conf" =
mkIf config.services.pipewire.pulse.enable {
source = json.generate "bluez-hardware.conf" configs.bluez-hardware;
};
environment.etc."pipewire/media-session.d/with-jack" =
mkIf config.services.pipewire.jack.enable {

View File

@ -0,0 +1,36 @@
{ config
, lib
, pkgs
, ...
}:
let
cfg = config.services.ddccontrol;
in
{
###### interface
options = {
services.ddccontrol = {
enable = lib.mkEnableOption "ddccontrol for controlling displays";
};
};
###### implementation
config = lib.mkIf cfg.enable {
# Give users access to the "gddccontrol" tool
environment.systemPackages = [
pkgs.ddccontrol
];
services.dbus.packages = [
pkgs.ddccontrol
];
systemd.packages = [
pkgs.ddccontrol
];
};
}

View File

@ -54,8 +54,7 @@ stdenv.mkDerivation {
${addAllNetDev netDevices}
'';
installPhase = ":";
dontInstall = true;
dontStrip = true;
dontPatchELF = true;

View File

@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.clipcat;
in {
options.services.clipcat= {
enable = mkEnableOption "Clipcat clipboard daemon";
package = mkOption {
type = types.package;
default = pkgs.clipcat;
defaultText = "pkgs.clipcat";
description = "clipcat derivation to use.";
};
};
config = mkIf cfg.enable {
systemd.user.services.clipcat = {
enable = true;
description = "clipcat daemon";
wantedBy = [ "graphical-session.target" ];
after = [ "graphical-session.target" ];
serviceConfig.ExecStart = "${cfg.package}/bin/clipcatd --no-daemon";
};
environment.systemPackages = [ cfg.package ];
};
}

View File

@ -911,7 +911,7 @@ in {
}
{
assertion = versionAtLeast postgresqlPackage.version "12.0.0";
message = "PostgreSQL >=12 is required to run GitLab 14.";
message = "PostgreSQL >=12 is required to run GitLab 14. Follow the instructions in the manual section for upgrading PostgreSQL here: https://nixos.org/manual/nixos/stable/index.html#module-services-postgres-upgrading";
}
];

View File

@ -313,6 +313,7 @@ in {
"w800rf32"
"xbee"
"zha"
"zwave"
];
in {
ExecStart = "${package}/bin/hass --runner --config '${cfg.configDir}'";

View File

@ -2,8 +2,13 @@
with lib;
let
cfg = config.services.klipper;
package = pkgs.klipper;
format = pkgs.formats.ini { mkKeyValue = generators.mkKeyValueDefault {} ":"; };
format = pkgs.formats.ini {
# https://github.com/NixOS/nixpkgs/pull/121613#issuecomment-885241996
listToValue = l:
if builtins.length l == 1 then generators.mkValueStringDefault {} (head l)
else lib.concatMapStrings (s: "\n ${generators.mkValueStringDefault {} s}") l;
mkKeyValue = generators.mkKeyValueDefault {} ":";
};
in
{
##### interface
@ -11,12 +16,51 @@ in
services.klipper = {
enable = mkEnableOption "Klipper, the 3D printer firmware";
package = mkOption {
type = types.package;
default = pkgs.klipper;
description = "The Klipper package.";
};
inputTTY = mkOption {
type = types.path;
default = "/run/klipper/tty";
description = "Path of the virtual printer symlink to create.";
};
apiSocket = mkOption {
type = types.nullOr types.path;
default = null;
example = "/run/klipper/api";
description = "Path of the API socket to create.";
};
octoprintIntegration = mkOption {
type = types.bool;
default = false;
description = "Allows Octoprint to control Klipper.";
};
user = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
User account under which Klipper runs.
If null is specified (default), a temporary user will be created by systemd.
'';
};
group = mkOption {
type = types.nullOr types.str;
default = null;
description = ''
Group account under which Klipper runs.
If null is specified (default), a temporary user will be created by systemd.
'';
};
settings = mkOption {
type = format.type;
default = { };
@ -30,26 +74,40 @@ in
##### implementation
config = mkIf cfg.enable {
assertions = [{
assertion = cfg.octoprintIntegration -> config.services.octoprint.enable;
message = "Option klipper.octoprintIntegration requires Octoprint to be enabled on this system. Please enable services.octoprint to use it.";
}];
assertions = [
{
assertion = cfg.octoprintIntegration -> config.services.octoprint.enable;
message = "Option klipper.octoprintIntegration requires Octoprint to be enabled on this system. Please enable services.octoprint to use it.";
}
{
assertion = cfg.user != null -> cfg.group != null;
message = "Option klipper.group is not set when a user is specified.";
}
];
environment.etc."klipper.cfg".source = format.generate "klipper.cfg" cfg.settings;
systemd.services.klipper = {
services.klipper = mkIf cfg.octoprintIntegration {
user = config.services.octoprint.user;
group = config.services.octoprint.group;
};
systemd.services.klipper = let
klippyArgs = "--input-tty=${cfg.inputTTY}"
+ optionalString (cfg.apiSocket != null) " --api-server=${cfg.apiSocket}";
in {
description = "Klipper 3D Printer Firmware";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
ExecStart = "${package}/lib/klipper/klippy.py --input-tty=/run/klipper/tty /etc/klipper.cfg";
ExecStart = "${cfg.package}/lib/klipper/klippy.py ${klippyArgs} /etc/klipper.cfg";
RuntimeDirectory = "klipper";
SupplementaryGroups = [ "dialout" ];
WorkingDirectory = "${package}/lib";
} // (if cfg.octoprintIntegration then {
Group = config.services.octoprint.group;
User = config.services.octoprint.user;
WorkingDirectory = "${cfg.package}/lib";
} // (if cfg.user != null then {
Group = cfg.group;
User = cfg.user;
} else {
DynamicUser = true;
User = "klipper";

View File

@ -323,15 +323,13 @@ let
HTTP username
'';
};
password = mkOption {
type = types.str;
description = ''
HTTP password
'';
};
password = mkOpt types.str "HTTP password";
password_file = mkOpt types.str "HTTP password file";
};
}) ''
Optional http login credentials for metrics scraping.
Sets the `Authorization` header on every scrape request with the
configured username and password.
password and password_file are mutually exclusive.
'';
bearer_token = mkOpt types.str ''

View File

@ -27,6 +27,7 @@ let
"bird"
"bitcoin"
"blackbox"
"buildkite-agent"
"collectd"
"dnsmasq"
"domain"
@ -180,7 +181,7 @@ let
serviceConfig.PrivateTmp = mkDefault true;
serviceConfig.WorkingDirectory = mkDefault /tmp;
serviceConfig.DynamicUser = mkDefault enableDynamicUser;
serviceConfig.User = conf.user;
serviceConfig.User = mkDefault conf.user;
serviceConfig.Group = conf.group;
} serviceOpts ]);
};

View File

@ -0,0 +1,64 @@
{ config, lib, pkgs, options }:
with lib;
let
cfg = config.services.prometheus.exporters.buildkite-agent;
in
{
port = 9876;
extraOpts = {
tokenPath = mkOption {
type = types.nullOr types.path;
apply = final: if final == null then null else toString final;
description = ''
The token from your Buildkite "Agents" page.
A run-time path to the token file, which is supposed to be provisioned
outside of Nix store.
'';
};
interval = mkOption {
type = types.str;
default = "30s";
example = "1min";
description = ''
How often to update metrics.
'';
};
endpoint = mkOption {
type = types.str;
default = "https://agent.buildkite.com/v3";
description = ''
The Buildkite Agent API endpoint.
'';
};
queues = mkOption {
type = with types; nullOr (listOf str);
default = null;
example = literalExample ''[ "my-queue1" "my-queue2" ]'';
description = ''
Which specific queues to process.
'';
};
};
serviceOpts = {
script =
let
queues = concatStringsSep " " (map (q: "-queue ${q}") cfg.queues);
in
''
export BUILDKITE_AGENT_TOKEN="$(cat ${toString cfg.tokenPath})"
exec ${pkgs.buildkite-agent-metrics}/bin/buildkite-agent-metrics \
-backend prometheus \
-interval ${cfg.interval} \
-endpoint ${cfg.endpoint} \
${optionalString (cfg.queues != null) queues} \
-prometheus-addr "${cfg.listenAddress}:${toString cfg.port}" ${concatStringsSep " " cfg.extraFlags}
'';
serviceConfig = {
DynamicUser = false;
RuntimeDirectory = "buildkite-agent-metrics";
};
};
}

View File

@ -26,6 +26,7 @@ in {
};
serviceOpts = {
serviceConfig = {
User = "kea";
ExecStart = ''
${pkgs.prometheus-kea-exporter}/bin/kea-exporter \
--address ${cfg.listenAddress} \

View File

@ -25,10 +25,9 @@ in {
default = [];
example = "/run/keys/telegraf.env";
description = ''
File to load as environment file. Environment variables
from this file will be interpolated into the config file
using envsubst with this syntax:
<literal>$ENVIRONMENT ''${VARIABLE}</literal>
File to load as environment file. Environment variables from this file
will be interpolated into the config file using envsubst with this
syntax: <literal>$ENVIRONMENT</literal> or <literal>''${VARIABLE}</literal>.
This is useful to avoid putting secrets into the nix store.
'';
};
@ -73,6 +72,7 @@ in {
ExecReload="${pkgs.coreutils}/bin/kill -HUP $MAINPID";
RuntimeDirectory = "telegraf";
User = "telegraf";
Group = "telegraf";
Restart = "on-failure";
# for ping probes
AmbientCapabilities = [ "CAP_NET_RAW" ];
@ -81,7 +81,10 @@ in {
users.users.telegraf = {
uid = config.ids.uids.telegraf;
group = "telegraf";
description = "telegraf daemon user";
};
users.groups.telegraf = {};
};
}

View File

@ -240,8 +240,8 @@ in
system.nssModules = optional cfg.nssmdns pkgs.nssmdns;
system.nssDatabases.hosts = optionals cfg.nssmdns (mkMerge [
(mkOrder 900 [ "mdns_minimal [NOTFOUND=return]" ]) # must be before resolve
(mkOrder 1501 [ "mdns" ]) # 1501 to ensure it's after dns
(mkBefore [ "mdns_minimal [NOTFOUND=return]" ]) # before resolve
(mkAfter [ "mdns" ]) # after dns
]);
environment.systemPackages = [ pkgs.avahi ];

View File

@ -6,6 +6,8 @@ let
cfg = config.services.bind;
bindPkg = config.services.bind.package;
bindUser = "named";
bindZoneCoerce = list: builtins.listToAttrs (lib.forEach list (zone: { name = zone.name; value = zone; }));
@ -59,7 +61,7 @@ let
blackhole { badnetworks; };
forward first;
forwarders { ${concatMapStrings (entry: " ${entry}; ") cfg.forwarders} };
directory "/run/named";
directory "${cfg.directory}";
pid-file "/run/named/named.pid";
${cfg.extraOptions}
};
@ -104,6 +106,14 @@ in
enable = mkEnableOption "BIND domain name server";
package = mkOption {
type = types.package;
default = pkgs.bind;
defaultText = "pkgs.bind";
description = "The BIND package to use.";
};
cacheNetworks = mkOption {
default = [ "127.0.0.0/24" ];
type = types.listOf types.str;
@ -156,6 +166,12 @@ in
";
};
directory = mkOption {
type = types.str;
default = "/run/named";
description = "Working directory of BIND.";
};
zones = mkOption {
default = [ ];
type = with types; coercedTo (listOf attrs) bindZoneCoerce (attrsOf (types.submodule bindZoneOptions));
@ -225,17 +241,20 @@ in
preStart = ''
mkdir -m 0755 -p /etc/bind
if ! [ -f "/etc/bind/rndc.key" ]; then
${pkgs.bind.out}/sbin/rndc-confgen -c /etc/bind/rndc.key -u ${bindUser} -a -A hmac-sha256 2>/dev/null
${bindPkg.out}/sbin/rndc-confgen -c /etc/bind/rndc.key -u ${bindUser} -a -A hmac-sha256 2>/dev/null
fi
${pkgs.coreutils}/bin/mkdir -p /run/named
chown ${bindUser} /run/named
${pkgs.coreutils}/bin/mkdir -p ${cfg.directory}
chown ${bindUser} ${cfg.directory}
'';
serviceConfig = {
ExecStart = "${pkgs.bind.out}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f";
ExecReload = "${pkgs.bind.out}/sbin/rndc -k '/etc/bind/rndc.key' reload";
ExecStop = "${pkgs.bind.out}/sbin/rndc -k '/etc/bind/rndc.key' stop";
ExecStart = "${bindPkg.out}/sbin/named -u ${bindUser} ${optionalString cfg.ipv4Only "-4"} -c ${cfg.configFile} -f";
ExecReload = "${bindPkg.out}/sbin/rndc -k '/etc/bind/rndc.key' reload";
ExecStop = "${bindPkg.out}/sbin/rndc -k '/etc/bind/rndc.key' stop";
};
unitConfig.Documentation = "man:named(8)";

View File

@ -37,7 +37,7 @@ in {
}
'';
description = ''
Configuration for CoreRAD, see <link xlink:href="https://github.com/mdlayher/corerad/blob/master/internal/config/default.toml"/>
Configuration for CoreRAD, see <link xlink:href="https://github.com/mdlayher/corerad/blob/main/internal/config/reference.toml"/>
for supported values. Ignored if configFile is set.
'';
};

View File

@ -18,6 +18,7 @@ let
${lib.optionalString (cfg.zone != "") "zone=${cfg.zone}"}
ssl=${boolToStr cfg.ssl}
wildcard=YES
ipv6=${boolToStr cfg.ipv6}
quiet=${boolToStr cfg.quiet}
verbose=${boolToStr cfg.verbose}
${cfg.extraConfig}
@ -116,7 +117,15 @@ with lib;
default = true;
type = bool;
description = ''
Whether to use to use SSL/TLS to connect to dynamic DNS provider.
Whether to use SSL/TLS to connect to dynamic DNS provider.
'';
};
ipv6 = mkOption {
default = false;
type = bool;
description = ''
Whether to use IPv6.
'';
};

View File

@ -4,8 +4,31 @@ with lib;
let
cfg = config.networking.wireless.iwd;
ini = pkgs.formats.ini { };
configFile = ini.generate "main.conf" cfg.settings;
in {
options.networking.wireless.iwd.enable = mkEnableOption "iwd";
options.networking.wireless.iwd = {
enable = mkEnableOption "iwd";
settings = mkOption {
type = ini.type;
default = { };
example = {
Settings.AutoConnect = true;
Network = {
EnableIPv6 = true;
RoutePriorityOffset = 300;
};
};
description = ''
Options passed to iwd.
See <link xlink:href="https://iwd.wiki.kernel.org/networkconfigurationsettings">here</link> for supported options.
'';
};
};
config = mkIf cfg.enable {
assertions = [{
@ -15,6 +38,8 @@ in {
'';
}];
environment.etc."iwd/main.conf".source = configFile;
# for iwctl
environment.systemPackages = [ pkgs.iwd ];
@ -27,7 +52,10 @@ in {
linkConfig.NamePolicy = "keep kernel";
};
systemd.services.iwd.wantedBy = [ "multi-user.target" ];
systemd.services.iwd = {
wantedBy = [ "multi-user.target" ];
restartTriggers = [ configFile ];
};
};
meta.maintainers = with lib.maintainers; [ mic92 dtzWill ];

View File

@ -0,0 +1,361 @@
{ config
, lib
, pkgs
, ...
}:
with lib;
let
cfg = config.services.kea;
format = pkgs.formats.json {};
ctrlAgentConfig = format.generate "kea-ctrl-agent.conf" {
Control-agent = cfg.ctrl-agent.settings;
};
dhcp4Config = format.generate "kea-dhcp4.conf" {
Dhcp4 = cfg.dhcp4.settings;
};
dhcp6Config = format.generate "kea-dhcp6.conf" {
Dhcp6 = cfg.dhcp6.settings;
};
dhcpDdnsConfig = format.generate "kea-dhcp-ddns.conf" {
DhcpDdns = cfg.dhcp-ddns.settings;
};
package = pkgs.kea;
in
{
options.services.kea = with types; {
ctrl-agent = mkOption {
description = ''
Kea Control Agent configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea Control Agent";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
description = ''
Kea Control Agent configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/agent.html"/>.
'';
};
};
};
};
dhcp4 = mkOption {
description = ''
DHCP4 Server configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea DHCP4 server";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
example = {
valid-lifetime = 4000;
renew-timer = 1000;
rebind-timer = 2000;
interfaces-config = {
interfaces = [
"eth0"
];
};
lease-database = {
type = "memfile";
persist = true;
name = "/var/lib/kea/dhcp4.leases";
};
subnet4 = [ {
subnet = "192.0.2.0/24";
pools = [ {
pool = "192.0.2.100 - 192.0.2.240";
} ];
} ];
};
description = ''
Kea DHCP4 configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp4-srv.html"/>.
'';
};
};
};
};
dhcp6 = mkOption {
description = ''
DHCP6 Server configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea DHCP6 server";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
example = {
valid-lifetime = 4000;
renew-timer = 1000;
rebind-timer = 2000;
preferred-lifetime = 3000;
interfaces-config = {
interfaces = [
"eth0"
];
};
lease-database = {
type = "memfile";
persist = true;
name = "/var/lib/kea/dhcp6.leases";
};
subnet6 = [ {
subnet = "2001:db8:1::/64";
pools = [ {
pool = "2001:db8:1::1-2001:db8:1::ffff";
} ];
} ];
};
description = ''
Kea DHCP6 configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp6-srv.html"/>.
'';
};
};
};
};
dhcp-ddns = mkOption {
description = ''
Kea DHCP-DDNS configuration
'';
default = {};
type = submodule {
options = {
enable = mkEnableOption "Kea DDNS server";
extraArgs = mkOption {
type = listOf str;
default = [];
description = ''
List of additonal arguments to pass to the daemon.
'';
};
settings = mkOption {
type = format.type;
default = null;
example = {
ip-address = "127.0.0.1";
port = 53001;
dns-server-timeout = 100;
ncr-protocol = "UDP";
ncr-format = "JSON";
tsig-keys = [ ];
forward-ddns = {
ddns-domains = [ ];
};
reverse-ddns = {
ddns-domains = [ ];
};
};
description = ''
Kea DHCP-DDNS configuration as an attribute set, see <link xlink:href="https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html"/>.
'';
};
};
};
};
};
config = let
commonServiceConfig = {
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
DynamicUser = true;
User = "kea";
ConfigurationDirectory = "kea";
RuntimeDirectory = "kea";
StateDirectory = "kea";
UMask = "0077";
};
in mkIf (cfg.ctrl-agent.enable || cfg.dhcp4.enable || cfg.dhcp6.enable || cfg.dhcp-ddns.enable) (mkMerge [
{
environment.systemPackages = [ package ];
}
(mkIf cfg.ctrl-agent.enable {
environment.etc."kea/ctrl-agent.conf".source = ctrlAgentConfig;
systemd.services.kea-ctrl-agent = {
description = "Kea Control Agent";
documentation = [
"man:kea-ctrl-agent(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/agent.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"kea-dhcp4-server.service"
"kea-dhcp6-server.service"
"kea-dhcp-ddns-server.service"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-ctrl-agent -c /etc/kea/ctrl-agent.conf ${lib.escapeShellArgs cfg.dhcp4.extraArgs}";
KillMode = "process";
Restart = "on-failure";
} // commonServiceConfig;
};
})
(mkIf cfg.dhcp4.enable {
environment.etc."kea/dhcp4-server.conf".source = dhcp4Config;
systemd.services.kea-dhcp4-server = {
description = "Kea DHCP4 Server";
documentation = [
"man:kea-dhcp4(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp4-srv.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"multi-user.target"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-dhcp4 -c /etc/kea/dhcp4-server.conf ${lib.escapeShellArgs cfg.dhcp4.extraArgs}";
# Kea does not request capabilities by itself
AmbientCapabilities = [
"CAP_NET_BIND_SERVICE"
"CAP_NET_RAW"
];
CapabilityBoundingSet = [
"CAP_NET_BIND_SERVICE"
"CAP_NET_RAW"
];
} // commonServiceConfig;
};
})
(mkIf cfg.dhcp6.enable {
environment.etc."kea/dhcp6-server.conf".source = dhcp6Config;
systemd.services.kea-dhcp6-server = {
description = "Kea DHCP6 Server";
documentation = [
"man:kea-dhcp6(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/dhcp6-srv.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"multi-user.target"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-dhcp6 -c /etc/kea/dhcp6-server.conf ${lib.escapeShellArgs cfg.dhcp6.extraArgs}";
# Kea does not request capabilities by itself
AmbientCapabilities = [
"CAP_NET_BIND_SERVICE"
];
CapabilityBoundingSet = [
"CAP_NET_BIND_SERVICE"
];
} // commonServiceConfig;
};
})
(mkIf cfg.dhcp-ddns.enable {
environment.etc."kea/dhcp-ddns.conf".source = dhcpDdnsConfig;
systemd.services.kea-dhcp-ddns-server = {
description = "Kea DHCP-DDNS Server";
documentation = [
"man:kea-dhcp-ddns(8)"
"https://kea.readthedocs.io/en/kea-${package.version}/arm/ddns.html"
];
after = [
"network-online.target"
"time-sync.target"
];
wantedBy = [
"multi-user.target"
];
environment = {
KEA_PIDFILE_DIR = "/run/kea";
};
serviceConfig = {
ExecStart = "${package}/bin/kea-dhcp-ddns -c /etc/kea/dhcp-ddns.conf ${lib.escapeShellArgs cfg.dhcp-ddns.extraArgs}";
AmbientCapabilites = [
"CAP_NET_BIND_SERVICE"
];
CapabilityBoundingSet = [
"CAP_NET_BIND_SERVICE"
];
} // commonServiceConfig;
};
})
]);
meta.maintainers = with maintainers; [ hexa ];
}

View File

@ -38,8 +38,8 @@ in
# Use services.matterbridge.configPath instead.
[irc]
[irc.freenode]
Server="irc.freenode.net:6667"
[irc.libera]
Server="irc.libera.chat:6667"
Nick="matterbot"
[mattermost]
@ -55,7 +55,7 @@ in
name="gateway1"
enable=true
[[gateway.inout]]
account="irc.freenode"
account="irc.libera"
channel="#testing"
[[gateway.inout]]

View File

@ -69,13 +69,9 @@ in
ExecStart = "${pkgs.nix-serve}/bin/nix-serve " +
"--listen ${cfg.bindAddress}:${toString cfg.port} ${cfg.extraParams}";
User = "nix-serve";
Group = "nogroup";
Group = "nix-serve";
DynamicUser = true;
};
};
users.users.nix-serve = {
description = "Nix-serve user";
uid = config.ids.uids.nix-serve;
};
};
}

View File

@ -82,13 +82,21 @@ in
LD_PRELOAD = "${pkgs.libredirect}/lib/libredirect.so";
NIX_REDIRECTS = "/var/run=/run/pppd";
};
serviceConfig = {
serviceConfig = let
capabilities = [
"CAP_BPF"
"CAP_SYS_TTY_CONFIG"
"CAP_NET_ADMIN"
"CAP_NET_RAW"
];
in
{
ExecStart = "${getBin cfg.package}/sbin/pppd call ${peerCfg.name} nodetach nolog";
Restart = "always";
RestartSec = 5;
AmbientCapabilities = "CAP_SYS_TTY_CONFIG CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN";
CapabilityBoundingSet = "CAP_SYS_TTY_CONFIG CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_ADMIN";
AmbientCapabilities = capabilities;
CapabilityBoundingSet = capabilities;
KeyringMode = "private";
LockPersonality = true;
MemoryDenyWriteExecute = true;
@ -103,7 +111,17 @@ in
ProtectKernelTunables = false;
ProtectSystem = "strict";
RemoveIPC = true;
RestrictAddressFamilies = "AF_PACKET AF_UNIX AF_PPPOX AF_ATMPVC AF_ATMSVC AF_INET AF_INET6 AF_IPX";
RestrictAddressFamilies = [
"AF_ATMPVC"
"AF_ATMSVC"
"AF_INET"
"AF_INET6"
"AF_IPX"
"AF_NETLINK"
"AF_PACKET"
"AF_PPPOX"
"AF_UNIX"
];
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;

View File

@ -54,6 +54,7 @@ in {
systemd.packages = [ pkgs.smartdns ];
systemd.services.smartdns.wantedBy = [ "multi-user.target" ];
systemd.services.smartdns.restartTriggers = [ confFile ];
environment.etc."smartdns/smartdns.conf".source = confFile;
environment.etc."default/smartdns".source =
"${pkgs.smartdns}/etc/default/smartdns";

View File

@ -21,7 +21,15 @@ let
))
else throw (traceSeq v "services.unbound.settings: unexpected type");
confFile = pkgs.writeText "unbound.conf" (concatStringsSep "\n" ((mapAttrsToList (toConf "") cfg.settings) ++ [""]));
confNoServer = concatStringsSep "\n" ((mapAttrsToList (toConf "") (builtins.removeAttrs cfg.settings [ "server" ])) ++ [""]);
confServer = concatStringsSep "\n" (mapAttrsToList (toConf " ") (builtins.removeAttrs cfg.settings.server [ "define-tag" ]));
confFile = pkgs.writeText "unbound.conf" ''
server:
${optionalString (cfg.settings.server.define-tag != "") (toOption " " "define-tag" cfg.settings.server.define-tag)}
${confServer}
${confNoServer}
'';
rootTrustAnchorFile = "${cfg.stateDir}/root.key";
@ -170,6 +178,7 @@ in {
# prevent race conditions on system startup when interfaces are not yet
# configured
ip-freebind = mkDefault true;
define-tag = mkDefault "";
};
remote-control = {
control-enable = mkDefault false;

View File

@ -133,8 +133,8 @@ in
Nick = "paul";
AltNick = "paul1";
LoadModule = [ "chansaver" "controlpanel" ];
Network.freenode = {
Server = "chat.freenode.net +6697";
Network.libera = {
Server = "irc.libera.chat +6697";
LoadModule = [ "simple_away" ];
Chan = {
"#nixos" = { Detached = false; };

View File

@ -11,7 +11,7 @@ let
server = mkOption {
type = types.str;
example = "chat.freenode.net";
example = "irc.libera.chat";
description = ''
IRC server address.
'';
@ -150,8 +150,8 @@ in
'';
example = literalExample ''
{
"freenode" = {
server = "chat.freenode.net";
"libera" = {
server = "irc.libera.chat";
port = 6697;
useSSL = true;
modules = [ "simple_away" ];

View File

@ -0,0 +1,104 @@
{ config, lib, pkgs, ... }:
let
cfg = config.services.hockeypuck;
settingsFormat = pkgs.formats.toml { };
in {
meta.maintainers = with lib.maintainers; [ etu ];
options.services.hockeypuck = {
enable = lib.mkEnableOption "Hockeypuck OpenPGP Key Server";
port = lib.mkOption {
default = 11371;
type = lib.types.port;
description = "HKP port to listen on.";
};
settings = lib.mkOption {
type = settingsFormat.type;
default = { };
example = lib.literalExample ''
{
hockeypuck = {
loglevel = "INFO";
logfile = "/var/log/hockeypuck/hockeypuck.log";
indexTemplate = "''${pkgs.hockeypuck-web}/share/templates/index.html.tmpl";
vindexTemplate = "''${pkgs.hockeypuck-web}/share/templates/index.html.tmpl";
statsTemplate = "''${pkgs.hockeypuck-web}/share/templates/stats.html.tmpl";
webroot = "''${pkgs.hockeypuck-web}/share/webroot";
hkp.bind = ":''${toString cfg.port}";
openpgp.db = {
driver = "postgres-jsonb";
dsn = "database=hockeypuck host=/var/run/postgresql sslmode=disable";
};
};
}
'';
description = ''
Configuration file for hockeypuck, here you can override
certain settings (<literal>loglevel</literal> and
<literal>openpgp.db.dsn</literal>) by just setting those values.
For other settings you need to use lib.mkForce to override them.
This service doesn't provision or enable postgres on your
system, it rather assumes that you enable postgres and create
the database yourself.
Example:
<literal>
services.postgresql = {
enable = true;
ensureDatabases = [ "hockeypuck" ];
ensureUsers = [{
name = "hockeypuck";
ensurePermissions."DATABASE hockeypuck" = "ALL PRIVILEGES";
}];
};
</literal>
'';
};
};
config = lib.mkIf cfg.enable {
services.hockeypuck.settings.hockeypuck = {
loglevel = lib.mkDefault "INFO";
logfile = "/var/log/hockeypuck/hockeypuck.log";
indexTemplate = "${pkgs.hockeypuck-web}/share/templates/index.html.tmpl";
vindexTemplate = "${pkgs.hockeypuck-web}/share/templates/index.html.tmpl";
statsTemplate = "${pkgs.hockeypuck-web}/share/templates/stats.html.tmpl";
webroot = "${pkgs.hockeypuck-web}/share/webroot";
hkp.bind = ":${toString cfg.port}";
openpgp.db = {
driver = "postgres-jsonb";
dsn = lib.mkDefault "database=hockeypuck host=/var/run/postgresql sslmode=disable";
};
};
users.users.hockeypuck = {
isSystemUser = true;
description = "Hockeypuck user";
};
systemd.services.hockeypuck = {
description = "Hockeypuck OpenPGP Key Server";
after = [ "network.target" "postgresql.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
WorkingDirectory = "/var/lib/hockeypuck";
User = "hockeypuck";
ExecStart = "${pkgs.hockeypuck}/bin/hockeypuck -config ${settingsFormat.generate "config.toml" cfg.settings}";
Restart = "always";
RestartSec = "5s";
LogsDirectory = "hockeypuck";
LogsDirectoryMode = "0755";
StateDirectory = "hockeypuck";
};
};
};
}

View File

@ -26,12 +26,12 @@ let
if value != null then [ (nameValuePair (nameToEnvVar name) (if isBool value then boolToString value else toString value)) ] else []
) cfg.config));
in { DATA_FOLDER = "/var/lib/bitwarden_rs"; } // optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") {
WEB_VAULT_FOLDER = "${pkgs.vaultwarden-vault}/share/vaultwarden/vault";
WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault";
} // configEnv;
configFile = pkgs.writeText "vaultwarden.env" (concatStrings (mapAttrsToList (name: value: "${name}=${value}\n") configEnv));
vaultwarden = pkgs.vaultwarden.override { inherit (cfg) dbBackend; };
vaultwarden = cfg.package.override { inherit (cfg) dbBackend; };
in {
imports = [
@ -102,6 +102,20 @@ in {
<literal>vaultwarden</literal> is running.
'';
};
package = mkOption {
type = package;
default = pkgs.vaultwarden;
defaultText = "pkgs.vaultwarden";
description = "Vaultwarden package to use.";
};
webVaultPackage = mkOption {
type = package;
default = pkgs.vaultwarden-vault;
defaultText = "pkgs.vaultwarden-vault";
description = "Web vault package to use.";
};
};
config = mkIf cfg.enable {

View File

@ -6,7 +6,7 @@ let
cfg = config.services.getty;
baseArgs = [
"--login-program" "${pkgs.shadow}/bin/login"
"--login-program" "${cfg.loginProgram}"
] ++ optionals (cfg.autologinUser != null) [
"--autologin" cfg.autologinUser
] ++ optionals (cfg.loginOptions != null) [
@ -39,6 +39,14 @@ in
'';
};
loginProgram = mkOption {
type = types.path;
default = "${pkgs.shadow}/bin/login";
description = ''
Path to the login binary executed by agetty.
'';
};
loginOptions = mkOption {
type = types.nullOr types.str;
default = null;

View File

@ -0,0 +1,265 @@
{ config, lib, pkgs, utils, ... }:
with lib;
let
cfg = config.services.unifi-video;
mainClass = "com.ubnt.airvision.Main";
cmd = ''
${pkgs.jsvc}/bin/jsvc \
-cwd ${stateDir} \
-debug \
-verbose:class \
-nodetach \
-user unifi-video \
-home ${cfg.jrePackage}/lib/openjdk \
-cp ${pkgs.commonsDaemon}/share/java/commons-daemon-1.2.4.jar:${stateDir}/lib/airvision.jar \
-pidfile ${cfg.pidFile} \
-procname unifi-video \
-Djava.security.egd=file:/dev/./urandom \
-Xmx${cfg.maximumJavaHeapSize}M \
-Xss512K \
-XX:+UseG1GC \
-XX:+UseStringDeduplication \
-XX:MaxMetaspaceSize=768M \
-Djava.library.path=${stateDir}/lib \
-Djava.awt.headless=true \
-Djavax.net.ssl.trustStore=${stateDir}/etc/ufv-truststore \
-Dfile.encoding=UTF-8 \
-Dav.tempdir=/var/cache/unifi-video
'';
mongoConf = pkgs.writeTextFile {
name = "mongo.conf";
executable = false;
text = ''
# for documentation of all options, see http://docs.mongodb.org/manual/reference/configuration-options/
storage:
dbPath: ${cfg.dataDir}/db
journal:
enabled: true
syncPeriodSecs: 60
systemLog:
destination: file
logAppend: true
path: ${stateDir}/logs/mongod.log
net:
port: 7441
bindIp: 127.0.0.1
http:
enabled: false
operationProfiling:
slowOpThresholdMs: 500
mode: off
'';
};
mongoWtConf = pkgs.writeTextFile {
name = "mongowt.conf";
executable = false;
text = ''
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
storage:
dbPath: ${cfg.dataDir}/db-wt
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
systemLog:
destination: file
logAppend: true
path: logs/mongod.log
net:
port: 7441
bindIp: 127.0.0.1
operationProfiling:
slowOpThresholdMs: 500
mode: off
'';
};
stateDir = "/var/lib/unifi-video";
in
{
options.services.unifi-video = {
enable = mkOption {
type = types.bool;
default = false;
description = ''
Whether or not to enable the unifi-video service.
'';
};
jrePackage = mkOption {
type = types.package;
default = pkgs.jre8;
defaultText = "pkgs.jre8";
description = ''
The JRE package to use. Check the release notes to ensure it is supported.
'';
};
unifiVideoPackage = mkOption {
type = types.package;
default = pkgs.unifi-video;
defaultText = "pkgs.unifi-video";
description = ''
The unifi-video package to use.
'';
};
mongodbPackage = mkOption {
type = types.package;
default = pkgs.mongodb-4_0;
defaultText = "pkgs.mongodb";
description = ''
The mongodb package to use.
'';
};
logDir = mkOption {
type = types.str;
default = "${stateDir}/logs";
description = ''
Where to store the logs.
'';
};
dataDir = mkOption {
type = types.str;
default = "${stateDir}/data";
description = ''
Where to store the database and other data.
'';
};
openPorts = mkOption {
type = types.bool;
default = true;
description = ''
Whether or not to open the required ports on the firewall.
'';
};
maximumJavaHeapSize = mkOption {
type = types.nullOr types.int;
default = 1024;
example = 4096;
description = ''
Set the maximimum heap size for the JVM in MB.
'';
};
pidFile = mkOption {
type = types.path;
default = "${cfg.dataDir}/unifi-video.pid";
description = "Location of unifi-video pid file.";
};
};
config = mkIf cfg.enable {
users = {
users.unifi-video = {
description = "UniFi Video controller daemon user";
home = stateDir;
group = "unifi-video";
isSystemUser = true;
};
groups.unifi-video = {};
};
networking.firewall = mkIf cfg.openPorts {
# https://help.ui.com/hc/en-us/articles/217875218-UniFi-Video-Ports-Used
allowedTCPPorts = [
7080 # HTTP portal
7443 # HTTPS portal
7445 # Video over HTTP (mobile app)
7446 # Video over HTTPS (mobile app)
7447 # RTSP via the controller
7442 # Camera management from cameras to NVR over WAN
];
allowedUDPPorts = [
6666 # Inbound camera streams sent over WAN
];
};
systemd.tmpfiles.rules = [
"d '${stateDir}' 0700 unifi-video unifi-video - -"
"d '/var/cache/unifi-video' 0700 unifi-video unifi-video - -"
"d '${stateDir}/logs' 0700 unifi-video unifi-video - -"
"C '${stateDir}/etc' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc"
"C '${stateDir}/webapps' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/webapps"
"C '${stateDir}/email' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/email"
"C '${stateDir}/fw' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/fw"
"C '${stateDir}/lib' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/lib"
"d '${stateDir}/data' 0700 unifi-video unifi-video - -"
"d '${stateDir}/data/db' 0700 unifi-video unifi-video - -"
"C '${stateDir}/data/system.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/etc/system.properties"
"d '${stateDir}/bin' 0700 unifi-video unifi-video - -"
"f '${stateDir}/bin/evostreamms' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/evostreamms"
"f '${stateDir}/bin/libavcodec.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavcodec.so.54"
"f '${stateDir}/bin/libavformat.so.54' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavformat.so.54"
"f '${stateDir}/bin/libavutil.so.52' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/libavutil.so.52"
"f '${stateDir}/bin/ubnt.avtool' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.avtool"
"f '${stateDir}/bin/ubnt.updater' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/bin/ubnt.updater"
"C '${stateDir}/bin/mongo' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongo"
"C '${stateDir}/bin/mongod' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongod"
"C '${stateDir}/bin/mongoperf' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongoperf"
"C '${stateDir}/bin/mongos' 0700 unifi-video unifi-video - ${cfg.mongodbPackage}/bin/mongos"
"d '${stateDir}/conf' 0700 unifi-video unifi-video - -"
"C '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/evostream"
"Z '${stateDir}/conf/evostream' 0700 unifi-video unifi-video - -"
"L+ '${stateDir}/conf/mongodv3.0+.conf' 0700 unifi-video unifi-video - ${mongoConf}"
"L+ '${stateDir}/conf/mongodv3.6+.conf' 0700 unifi-video unifi-video - ${mongoConf}"
"L+ '${stateDir}/conf/mongod-wt.conf' 0700 unifi-video unifi-video - ${mongoWtConf}"
"L+ '${stateDir}/conf/catalina.policy' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.policy"
"L+ '${stateDir}/conf/catalina.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/catalina.properties"
"L+ '${stateDir}/conf/context.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/context.xml"
"L+ '${stateDir}/conf/logging.properties' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/logging.properties"
"L+ '${stateDir}/conf/server.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/server.xml"
"L+ '${stateDir}/conf/tomcat-users.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/tomcat-users.xml"
"L+ '${stateDir}/conf/web.xml' 0700 unifi-video unifi-video - ${pkgs.unifi-video}/lib/unifi-video/conf/web.xml"
];
systemd.services.unifi-video = {
description = "UniFi Video NVR daemon";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ] ;
unitConfig.RequiresMountsFor = stateDir;
# Make sure package upgrades trigger a service restart
restartTriggers = [ cfg.unifiVideoPackage cfg.mongodbPackage ];
path = with pkgs; [ gawk coreutils busybox which jre8 lsb-release libcap util-linux ];
serviceConfig = {
Type = "simple";
ExecStart = "${(removeSuffix "\n" cmd)} ${mainClass} start";
ExecStop = "${(removeSuffix "\n" cmd)} stop ${mainClass} stop";
Restart = "on-failure";
UMask = "0077";
User = "unifi-video";
WorkingDirectory = "${stateDir}";
};
};
};
meta = {
maintainers = with lib.maintainers; [ rsynnest ];
};
}

View File

@ -475,21 +475,16 @@ in
plugins = lib.mkOption {
type = lib.types.listOf lib.types.package;
default = [];
example = ''
[
(pkgs.fetchFromGitHub {
owner = "discourse";
repo = "discourse-spoiler-alert";
rev = "e200cfa571d252cab63f3d30d619b370986e4cee";
sha256 = "0ya69ix5g77wz4c9x9gmng6l25ghb5xxlx3icr6jam16q14dzc33";
})
example = lib.literalExample ''
with config.services.discourse.package.plugins; [
discourse-canned-replies
discourse-github
];
'';
description = ''
<productname>Discourse</productname> plugins to install as a
list of derivations. As long as a plugin supports the
standard install method, packaging it should only require
fetching its source with an appropriate fetcher.
Plugins to install as part of
<productname>Discourse</productname>, expressed as a list of
derivations.
'';
};

View File

@ -262,9 +262,31 @@ services.discourse = {
<para>
You can install <productname>Discourse</productname> plugins
using the <xref linkend="opt-services.discourse.plugins" />
option. As long as a plugin supports the standard install
method, packaging it should only require fetching its source
with an appropriate fetcher.
option. Pre-packaged plugins are provided in
<literal>&lt;your_discourse_package_here&gt;.plugins</literal>. If
you want the full suite of plugins provided through
<literal>nixpkgs</literal>, you can also set the <xref
linkend="opt-services.discourse.package" /> option to
<literal>pkgs.discourseAllPlugins</literal>.
</para>
<para>
Plugins can be built with the
<literal>&lt;your_discourse_package_here&gt;.mkDiscoursePlugin</literal>
function. Normally, it should suffice to provide a
<literal>name</literal> and <literal>src</literal> attribute. If
the plugin has Ruby dependencies, however, they need to be
packaged in accordance with the <link
xlink:href="https://nixos.org/manual/nixpkgs/stable/#developing-with-ruby">Developing
with Ruby</link> section of the Nixpkgs manual and the
appropriate gem options set in <literal>bundlerEnvArgs</literal>
(normally <literal>gemdir</literal> is sufficient). A plugin's
Ruby dependencies are listed in its
<filename>plugin.rb</filename> file as function calls to
<literal>gem</literal>. To construct the corresponding
<filename>Gemfile</filename>, run <command>bundle
init</command>, then add the <literal>gem</literal> lines to it
verbatim.
</para>
<para>
@ -280,7 +302,10 @@ services.discourse = {
<para>
For example, to add the <link
xlink:href="https://github.com/discourse/discourse-spoiler-alert">discourse-spoiler-alert</link>
plugin and disable it by default:
and <link
xlink:href="https://github.com/discourse/discourse-solved">discourse-solved</link>
plugins, and disable <literal>discourse-spoiler-alert</literal>
by default:
<programlisting>
services.discourse = {
@ -301,13 +326,9 @@ services.discourse = {
<link linkend="opt-services.discourse.mail.outgoing.passwordFile">passwordFile</link> = "/path/to/smtp_password_file";
};
<link linkend="opt-services.discourse.mail.incoming.enable">mail.incoming.enable</link> = true;
<link linkend="opt-services.discourse.mail.incoming.enable">plugins</link> = [
(pkgs.fetchFromGitHub {
owner = "discourse";
repo = "discourse-spoiler-alert";
rev = "e200cfa571d252cab63f3d30d619b370986e4cee";
sha256 = "0ya69ix5g77wz4c9x9gmng6l25ghb5xxlx3icr6jam16q14dzc33";
})
<link linkend="opt-services.discourse.mail.incoming.enable">plugins</link> = with config.services.discourse.package.plugins; [
discourse-spoiler-alert
discourse-solved
];
<link linkend="opt-services.discourse.siteSettings">siteSettings</link> = {
plugins = {

View File

@ -23,6 +23,16 @@ in {
'';
};
libraryPaths = mkOption {
type = attrsOf package;
default = { };
description = ''
Libraries to add to the Icingaweb2 library path.
The name of the attribute is the name of the library, the value
is the package to add.
'';
};
virtualHost = mkOption {
type = nullOr str;
default = "icingaweb2";
@ -167,6 +177,9 @@ in {
services.phpfpm.pools = mkIf (cfg.pool == "${poolName}") {
${poolName} = {
user = "icingaweb2";
phpEnv = {
ICINGAWEB_LIBDIR = toString (pkgs.linkFarm "icingaweb2-libdir" (mapAttrsToList (name: path: { inherit name path; }) cfg.libraryPaths));
};
phpPackage = pkgs.php.withExtensions ({ enabled, all }: [ all.imagick ] ++ enabled);
phpOptions = ''
date.timezone = "${cfg.timezone}"
@ -184,6 +197,11 @@ in {
};
};
services.icingaweb2.libraryPaths = {
ipl = pkgs.icingaweb2-ipl;
thirdparty = pkgs.icingaweb2-thirdparty;
};
systemd.services."phpfpm-${poolName}".serviceConfig.ReadWritePaths = [ "/etc/icingaweb2" ];
services.nginx = {

View File

@ -92,7 +92,7 @@ in {
package = mkOption {
type = types.package;
description = "Which package to use for the Nextcloud instance.";
relatedPackages = [ "nextcloud19" "nextcloud20" "nextcloud21" ];
relatedPackages = [ "nextcloud20" "nextcloud21" "nextcloud22" ];
};
maxUploadSize = mkOption {
@ -385,7 +385,7 @@ in {
];
warnings = let
latest = 21;
latest = 22;
upgradeWarning = major: nixos:
''
A legacy Nextcloud install (from before NixOS ${nixos}) may be installed.
@ -403,9 +403,9 @@ in {
Using config.services.nextcloud.poolConfig is deprecated and will become unsupported in a future release.
Please migrate your configuration to config.services.nextcloud.poolSettings.
'')
++ (optional (versionOlder cfg.package.version "19") (upgradeWarning 18 "20.09"))
++ (optional (versionOlder cfg.package.version "20") (upgradeWarning 19 "21.05"))
++ (optional (versionOlder cfg.package.version "21") (upgradeWarning 20 "21.05"));
++ (optional (versionOlder cfg.package.version "21") (upgradeWarning 20 "21.05"))
++ (optional (versionOlder cfg.package.version "22") (upgradeWarning 21 "21.11"));
services.nextcloud.package = with pkgs;
mkDefault (
@ -415,13 +415,13 @@ in {
nextcloud defined in an overlay, please set `services.nextcloud.package` to
`pkgs.nextcloud`.
''
else if versionOlder stateVersion "20.09" then nextcloud18
# 21.03 will not be an official release - it was instead 21.05.
# This versionOlder statement remains set to 21.03 for backwards compatibility.
# See https://github.com/NixOS/nixpkgs/pull/108899 and
# https://github.com/NixOS/rfcs/blob/master/rfcs/0080-nixos-release-schedule.md.
else if versionOlder stateVersion "21.03" then nextcloud19
else nextcloud21
else if versionOlder stateVersion "21.11" then nextcloud21
else nextcloud22
);
}
@ -616,9 +616,7 @@ in {
services.nginx.enable = mkDefault true;
services.nginx.virtualHosts.${cfg.hostName} = let
major = toInt (versions.major cfg.package.version);
in {
services.nginx.virtualHosts.${cfg.hostName} = {
root = cfg.package;
locations = {
"= /robots.txt" = {
@ -701,7 +699,6 @@ in {
};
extraConfig = ''
index index.php index.html /index.php$request_uri;
expires 1m;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;

View File

@ -11,7 +11,7 @@
desktop client is packaged at <literal>pkgs.nextcloud-client</literal>.
</para>
<para>
The current default by NixOS is <package>nextcloud21</package> which is also the latest
The current default by NixOS is <package>nextcloud22</package> which is also the latest
major version available.
</para>
<section xml:id="module-services-nextcloud-basic-usage">

View File

@ -7,10 +7,15 @@ let
# FIXME consider using LoadCredential as soon as it actually works.
envSecrets = ''
export ADMIN_USER_PWD="$(<${cfg.adminUser.passwordFile})"
export SECRET_KEY_BASE="$(<${cfg.server.secretKeybaseFile})"
ADMIN_USER_PWD="$(<${cfg.adminUser.passwordFile})"
export ADMIN_USER_PWD # separate export to make `set -e` work
SECRET_KEY_BASE="$(<${cfg.server.secretKeybaseFile})"
export SECRET_KEY_BASE # separate export to make `set -e` work
${optionalString (cfg.mail.smtp.passwordFile != null) ''
export SMTP_USER_PWD="$(<${cfg.mail.smtp.passwordFile})"
SMTP_USER_PWD="$(<${cfg.mail.smtp.passwordFile})"
export SMTP_USER_PWD # separate export to make `set -e` work
''}
'';
in {
@ -102,6 +107,11 @@ in {
type = types.str;
description = ''
Public URL where plausible is available.
Note that <literal>/path</literal> components are currently ignored:
<link xlink:href="https://github.com/plausible/analytics/issues/1182">
https://github.com/plausible/analytics/issues/1182
</link>.
'';
};
};
@ -228,6 +238,7 @@ in {
WorkingDirectory = "/var/lib/plausible";
StateDirectory = "plausible";
ExecStartPre = "@${pkgs.writeShellScript "plausible-setup" ''
set -eu -o pipefail
${envSecrets}
${pkgs.plausible}/createdb.sh
${pkgs.plausible}/migrate.sh
@ -238,6 +249,7 @@ in {
''}
''} plausible-setup";
ExecStart = "@${pkgs.writeShellScript "plausible" ''
set -eu -o pipefail
${envSecrets}
plausible start
''} plausible";

View File

@ -0,0 +1,145 @@
{ pkgs, lib, config, ... }:
with lib;
let
cfg = config.services.vikunja;
format = pkgs.formats.yaml {};
configFile = format.generate "config.yaml" cfg.settings;
useMysql = cfg.database.type == "mysql";
usePostgresql = cfg.database.type == "postgres";
in {
options.services.vikunja = with lib; {
enable = mkEnableOption "vikunja service";
package-api = mkOption {
default = pkgs.vikunja-api;
type = types.package;
defaultText = "pkgs.vikunja-api";
description = "vikunja-api derivation to use.";
};
package-frontend = mkOption {
default = pkgs.vikunja-frontend;
type = types.package;
defaultText = "pkgs.vikunja-frontend";
description = "vikunja-frontend derivation to use.";
};
environmentFiles = mkOption {
type = types.listOf types.path;
default = [ ];
description = ''
List of environment files set in the vikunja systemd service.
For example passwords should be set in one of these files.
'';
};
setupNginx = mkOption {
type = types.bool;
default = config.services.nginx.enable;
defaultText = "config.services.nginx.enable";
description = ''
Whether to setup NGINX.
Further nginx configuration can be done by changing
<option>services.nginx.virtualHosts.&lt;frontendHostname&gt;</option>.
This does not enable TLS or ACME by default. To enable this, set the
<option>services.nginx.virtualHosts.&lt;frontendHostname&gt;.enableACME</option> to
<literal>true</literal> and if appropriate do the same for
<option>services.nginx.virtualHosts.&lt;frontendHostname&gt;.forceSSL</option>.
'';
};
frontendScheme = mkOption {
type = types.enum [ "http" "https" ];
description = ''
Whether the site is available via http or https.
This does not configure https or ACME in nginx!
'';
};
frontendHostname = mkOption {
type = types.str;
description = "The Hostname under which the frontend is running.";
};
settings = mkOption {
type = format.type;
default = {};
description = ''
Vikunja configuration. Refer to
<link xlink:href="https://vikunja.io/docs/config-options/"/>
for details on supported values.
'';
};
database = {
type = mkOption {
type = types.enum [ "sqlite" "mysql" "postgres" ];
example = "postgres";
default = "sqlite";
description = "Database engine to use.";
};
host = mkOption {
type = types.str;
default = "localhost";
description = "Database host address. Can also be a socket.";
};
user = mkOption {
type = types.str;
default = "vikunja";
description = "Database user.";
};
database = mkOption {
type = types.str;
default = "vikunja";
description = "Database name.";
};
path = mkOption {
type = types.str;
default = "/var/lib/vikunja/vikunja.db";
description = "Path to the sqlite3 database file.";
};
};
};
config = lib.mkIf cfg.enable {
services.vikunja.settings = {
database = {
inherit (cfg.database) type host user database path;
};
service = {
frontendurl = "${cfg.frontendScheme}://${cfg.frontendHostname}/";
};
files = {
basepath = "/var/lib/vikunja/files";
};
};
systemd.services.vikunja-api = {
description = "vikunja-api";
after = [ "network.target" ] ++ lib.optional usePostgresql "postgresql.service" ++ lib.optional useMysql "mysql.service";
wantedBy = [ "multi-user.target" ];
path = [ cfg.package-api ];
restartTriggers = [ configFile ];
serviceConfig = {
Type = "simple";
DynamicUser = true;
StateDirectory = "vikunja";
ExecStart = "${cfg.package-api}/bin/vikunja";
Restart = "always";
EnvironmentFile = cfg.environmentFiles;
};
};
services.nginx.virtualHosts."${cfg.frontendHostname}" = mkIf cfg.setupNginx {
locations = {
"/" = {
root = cfg.package-frontend;
tryFiles = "try_files $uri $uri/ /";
};
"~* ^/(api|dav|\\.well-known)/" = {
proxyPass = "http://localhost:3456";
extraConfig = ''
client_max_body_size 20M;
'';
};
};
};
environment.etc."vikunja/config.yaml".source = configFile;
};
}

View File

@ -3,13 +3,18 @@
let
inherit (lib) mkDefault mkEnableOption mkForce mkIf mkMerge mkOption types;
inherit (lib) any attrValues concatMapStringsSep flatten literalExample;
inherit (lib) mapAttrs mapAttrs' mapAttrsToList nameValuePair optional optionalAttrs optionalString;
inherit (lib) filterAttrs mapAttrs mapAttrs' mapAttrsToList nameValuePair optional optionalAttrs optionalString;
eachSite = config.services.wordpress;
cfg = migrateOldAttrs config.services.wordpress;
eachSite = cfg.sites;
user = "wordpress";
group = config.services.httpd.group;
webserver = config.services.${cfg.webserver};
stateDir = hostName: "/var/lib/wordpress/${hostName}";
# Migrate config.services.wordpress.<hostName> to config.services.wordpress.sites.<hostName>
oldSites = filterAttrs (o: _: o != "sites" && o != "webserver");
migrateOldAttrs = cfg: cfg // { sites = cfg.sites // oldSites cfg; };
pkg = hostName: cfg: pkgs.stdenv.mkDerivation rec {
pname = "wordpress-${hostName}";
version = src.version;
@ -261,21 +266,48 @@ in
# interface
options = {
services.wordpress = mkOption {
type = types.attrsOf (types.submodule siteOpts);
type = types.submodule {
# Used to support old interface
freeformType = types.attrsOf (types.submodule siteOpts);
# New interface
options.sites = mkOption {
type = types.attrsOf (types.submodule siteOpts);
default = {};
description = "Specification of one or more WordPress sites to serve";
};
options.webserver = mkOption {
type = types.enum [ "httpd" "nginx" ];
default = "httpd";
description = ''
Whether to use apache2 or nginx for virtual host management.
Further nginx configuration can be done by adapting <literal>services.nginx.virtualHosts.&lt;name&gt;</literal>.
See <xref linkend="opt-services.nginx.virtualHosts"/> for further information.
Further apache2 configuration can be done by adapting <literal>services.httpd.virtualHosts.&lt;name&gt;</literal>.
See <xref linkend="opt-services.httpd.virtualHosts"/> for further information.
'';
};
};
default = {};
description = "Specification of one or more WordPress sites to serve via Apache.";
description = "Wordpress configuration";
};
};
# implementation
config = mkIf (eachSite != {}) {
config = mkIf (eachSite != {}) (mkMerge [{
assertions = mapAttrsToList (hostName: cfg:
{ assertion = cfg.database.createLocally -> cfg.database.user == user;
message = "services.wordpress.${hostName}.database.user must be ${user} if the database is to be automatically provisioned";
message = ''services.wordpress.sites."${hostName}".database.user must be ${user} if the database is to be automatically provisioned'';
}
) eachSite;
warnings = mapAttrsToList (hostName: _: ''services.wordpress."${hostName}" is deprecated use services.wordpress.sites."${hostName}"'') (oldSites cfg);
services.mysql = mkIf (any (v: v.database.createLocally) (attrValues eachSite)) {
enable = true;
package = mkDefault pkgs.mariadb;
@ -289,14 +321,18 @@ in
services.phpfpm.pools = mapAttrs' (hostName: cfg: (
nameValuePair "wordpress-${hostName}" {
inherit user group;
inherit user;
group = webserver.group;
settings = {
"listen.owner" = config.services.httpd.user;
"listen.group" = config.services.httpd.group;
"listen.owner" = webserver.user;
"listen.group" = webserver.group;
} // cfg.poolConfig;
}
)) eachSite;
}
(mkIf (cfg.webserver == "httpd") {
services.httpd = {
enable = true;
extraModules = [ "proxy_fcgi" ];
@ -332,11 +368,13 @@ in
'';
} ]) eachSite;
};
})
{
systemd.tmpfiles.rules = flatten (mapAttrsToList (hostName: cfg: [
"d '${stateDir hostName}' 0750 ${user} ${group} - -"
"d '${cfg.uploadsDir}' 0750 ${user} ${group} - -"
"Z '${cfg.uploadsDir}' 0750 ${user} ${group} - -"
"d '${stateDir hostName}' 0750 ${user} ${webserver.group} - -"
"d '${cfg.uploadsDir}' 0750 ${user} ${webserver.group} - -"
"Z '${cfg.uploadsDir}' 0750 ${user} ${webserver.group} - -"
]) eachSite);
systemd.services = mkMerge [
@ -350,7 +388,7 @@ in
serviceConfig = {
Type = "oneshot";
User = user;
Group = group;
Group = webserver.group;
};
})) eachSite)
@ -360,9 +398,65 @@ in
];
users.users.${user} = {
group = group;
group = webserver.group;
isSystemUser = true;
};
}
};
(mkIf (cfg.webserver == "nginx") {
services.nginx = {
enable = true;
virtualHosts = mapAttrs (hostName: cfg: {
serverName = mkDefault hostName;
root = "${pkg hostName cfg}/share/wordpress";
extraConfig = ''
index index.php;
'';
locations = {
"/" = {
priority = 200;
extraConfig = ''
try_files $uri $uri/ /index.php$is_args$args;
'';
};
"~ \\.php$" = {
priority = 500;
extraConfig = ''
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:${config.services.phpfpm.pools."wordpress-${hostName}".socket};
fastcgi_index index.php;
include "${config.services.nginx.package}/conf/fastcgi.conf";
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
'';
};
"~ /\\." = {
priority = 800;
extraConfig = "deny all;";
};
"~* /(?:uploads|files)/.*\\.php$" = {
priority = 900;
extraConfig = "deny all;";
};
"~* \\.(js|css|png|jpg|jpeg|gif|ico)$" = {
priority = 1000;
extraConfig = ''
expires max;
log_not_found off;
'';
};
};
}) eachSite;
};
})
]);
}

View File

@ -140,7 +140,8 @@ in
# add resolve to nss hosts database if enabled and nscd enabled
# system.nssModules is configured in nixos/modules/system/boot/systemd.nix
system.nssDatabases.hosts = optional config.services.nscd.enable "resolve [!UNAVAIL=return]";
# added with order 501 to allow modules to go before with mkBefore
system.nssDatabases.hosts = (mkOrder 501 ["resolve [!UNAVAIL=return]"]);
systemd.additionalUpstreamSystemUnits = [
"systemd-resolved.service"

View File

@ -755,7 +755,7 @@ in
default = [];
example = [ "d /tmp 1777 root root 10d" ];
description = ''
Rules for creating and cleaning up temporary files
Rules for creation, deletion and cleaning of volatile and temporary files
automatically. See
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the exact format.
@ -925,9 +925,8 @@ in
system.nssModules = [ systemd.out ];
system.nssDatabases = {
hosts = (mkMerge [
[ "mymachines" ]
(mkOrder 1600 [ "myhostname" ] # 1600 to ensure it's always the last
)
(mkOrder 400 ["mymachines"]) # 400 to ensure it comes before resolve (which is mkBefore'd)
(mkOrder 999 ["myhostname"]) # after files (which is 998), but before regular nss modules
]);
passwd = (mkMerge [
(mkAfter [ "systemd" ])

View File

@ -255,7 +255,7 @@ in
# https://wiki.archlinux.org/index.php/fstab#Filepath_spaces
escape = string: builtins.replaceStrings [ " " "\t" ] [ "\\040" "\\011" ] string;
swapOptions = sw: concatStringsSep "," (
[ "defaults" ]
sw.options
++ optional (sw.priority != null) "pri=${toString sw.priority}"
++ optional (sw.discardPolicy != null) "discard${optionalString (sw.discardPolicy != "both") "=${toString sw.discardPolicy}"}"
);
@ -324,28 +324,33 @@ in
in listToAttrs (map formatDevice (filter (fs: fs.autoFormat) fileSystems)) // {
# Mount /sys/fs/pstore for evacuating panic logs and crashdumps from persistent storage onto the disk using systemd-pstore.
# This cannot be done with the other special filesystems because the pstore module (which creates the mount point) is not loaded then.
# Since the pstore filesystem is usually empty right after mounting because the backend isn't registered yet, and a path unit cannot detect files inside of it, the same service waits for that to happen. systemd's restart mechanism can't be used here because the first failure also fails all dependent units.
"mount-pstore" = {
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.util-linux}/bin/mount -t pstore -o nosuid,noexec,nodev pstore /sys/fs/pstore";
ExecStartPost = pkgs.writeShellScript "wait-for-pstore.sh" ''
# skip on kernels without the pstore module
ExecCondition = "${pkgs.kmod}/bin/modprobe -b pstore";
ExecStart = pkgs.writeShellScript "mount-pstore.sh" ''
set -eu
TRIES=0
while [ $TRIES -lt 20 ] && [ "$(cat /sys/module/pstore/parameters/backend)" = "(null)" ]; do
sleep 0.1
TRIES=$((TRIES+1))
# if the pstore module is builtin it will have mounted the persistent store automatically. it may also be already mounted for other reasons.
${pkgs.util-linux}/bin/mountpoint -q /sys/fs/pstore || ${pkgs.util-linux}/bin/mount -t pstore -o nosuid,noexec,nodev pstore /sys/fs/pstore
# wait up to five seconds (arbitrary, happened within one in testing) for the backend to be registered and the files to appear. a systemd path unit cannot detect this happening; and succeeding after a restart would not start dependent units.
TRIES=50
while [ "$(cat /sys/module/pstore/parameters/backend)" = "(null)" ]; do
if (( $TRIES )); then
sleep 0.1
TRIES=$((TRIES-1))
else
echo "Persistent Storage backend was not registered in time." >&2
exit 1
fi
done
'';
RemainAfterExit = true;
};
unitConfig = {
ConditionPathIsMountPoint = "!/sys/fs/pstore";
ConditionVirtualization = "!container";
DefaultDependencies = false; # needed to prevent a cycle
};
after = [ "modprobe@pstore.service" ];
requires = [ "modprobe@pstore.service" ];
before = [ "systemd-pstore.service" ];
wantedBy = [ "systemd-pstore.service" ];
};

View File

@ -0,0 +1,230 @@
{ config, lib, pkgs, ... }:
with lib;
let cfg = config.snapraid;
in
{
options.snapraid = with types; {
enable = mkEnableOption "SnapRAID";
dataDisks = mkOption {
default = { };
example = {
d1 = "/mnt/disk1/";
d2 = "/mnt/disk2/";
d3 = "/mnt/disk3/";
};
description = "SnapRAID data disks.";
type = attrsOf str;
};
parityFiles = mkOption {
default = [ ];
example = [
"/mnt/diskp/snapraid.parity"
"/mnt/diskq/snapraid.2-parity"
"/mnt/diskr/snapraid.3-parity"
"/mnt/disks/snapraid.4-parity"
"/mnt/diskt/snapraid.5-parity"
"/mnt/disku/snapraid.6-parity"
];
description = "SnapRAID parity files.";
type = listOf str;
};
contentFiles = mkOption {
default = [ ];
example = [
"/var/snapraid.content"
"/mnt/disk1/snapraid.content"
"/mnt/disk2/snapraid.content"
];
description = "SnapRAID content list files.";
type = listOf str;
};
exclude = mkOption {
default = [ ];
example = [ "*.unrecoverable" "/tmp/" "/lost+found/" ];
description = "SnapRAID exclude directives.";
type = listOf str;
};
touchBeforeSync = mkOption {
default = true;
example = false;
description =
"Whether <command>snapraid touch</command> should be run before <command>snapraid sync</command>.";
type = bool;
};
sync.interval = mkOption {
default = "01:00";
example = "daily";
description = "How often to run <command>snapraid sync</command>.";
type = str;
};
scrub = {
interval = mkOption {
default = "Mon *-*-* 02:00:00";
example = "weekly";
description = "How often to run <command>snapraid scrub</command>.";
type = str;
};
plan = mkOption {
default = 8;
example = 5;
description =
"Percent of the array that should be checked by <command>snapraid scrub</command>.";
type = int;
};
olderThan = mkOption {
default = 10;
example = 20;
description =
"Number of days since data was last scrubbed before it can be scrubbed again.";
type = int;
};
};
extraConfig = mkOption {
default = "";
example = ''
nohidden
blocksize 256
hashsize 16
autosave 500
pool /pool
'';
description = "Extra config options for SnapRAID.";
type = lines;
};
};
config =
let
nParity = builtins.length cfg.parityFiles;
mkPrepend = pre: s: pre + s;
in
mkIf cfg.enable {
assertions = [
{
assertion = nParity <= 6;
message = "You can have no more than six SnapRAID parity files.";
}
{
assertion = builtins.length cfg.contentFiles >= nParity + 1;
message =
"There must be at least one SnapRAID content file for each SnapRAID parity file plus one.";
}
];
environment = {
systemPackages = with pkgs; [ snapraid ];
etc."snapraid.conf" = {
text = with cfg;
let
prependData = mkPrepend "data ";
prependContent = mkPrepend "content ";
prependExclude = mkPrepend "exclude ";
in
concatStringsSep "\n"
(map prependData
((mapAttrsToList (name: value: name + " " + value)) dataDisks)
++ zipListsWith (a: b: a + b)
([ "parity " ] ++ map (i: toString i + "-parity ") (range 2 6))
parityFiles ++ map prependContent contentFiles
++ map prependExclude exclude) + "\n" + extraConfig;
};
};
systemd.services = with cfg; {
snapraid-scrub = {
description = "Scrub the SnapRAID array";
startAt = scrub.interval;
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.snapraid}/bin/snapraid scrub -p ${
toString scrub.plan
} -o ${toString scrub.olderThan}";
Nice = 19;
IOSchedulingPriority = 7;
CPUSchedulingPolicy = "batch";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = "none";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
SystemCallErrorNumber = "EPERM";
CapabilityBoundingSet = "CAP_DAC_OVERRIDE";
ProtectSystem = "strict";
ProtectHome = "read-only";
ReadWritePaths =
# scrub requires access to directories containing content files
# to remove them if they are stale
let
contentDirs = map dirOf contentFiles;
in
unique (
attrValues dataDisks ++ contentDirs
);
};
unitConfig.After = "snapraid-sync.service";
};
snapraid-sync = {
description = "Synchronize the state of the SnapRAID array";
startAt = sync.interval;
serviceConfig = {
Type = "oneshot";
ExecStart = "${pkgs.snapraid}/bin/snapraid sync";
Nice = 19;
IOSchedulingPriority = 7;
CPUSchedulingPolicy = "batch";
LockPersonality = true;
MemoryDenyWriteExecute = true;
NoNewPrivileges = true;
PrivateDevices = true;
PrivateTmp = true;
ProtectClock = true;
ProtectControlGroups = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = "none";
RestrictNamespaces = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
SystemCallArchitectures = "native";
SystemCallFilter = "@system-service";
SystemCallErrorNumber = "EPERM";
CapabilityBoundingSet = "CAP_DAC_OVERRIDE";
ProtectSystem = "strict";
ProtectHome = "read-only";
ReadWritePaths =
# sync requires access to directories containing content files
# to remove them if they are stale
let
contentDirs = map dirOf contentFiles;
in
unique (
attrValues dataDisks ++ parityFiles ++ contentDirs
);
} // optionalAttrs touchBeforeSync {
ExecStartPre = "${pkgs.snapraid}/bin/snapraid touch";
};
};
};
};
}

View File

@ -6,6 +6,9 @@ let
crioPackage = (pkgs.cri-o.override { inherit (cfg) extraPackages; });
format = pkgs.formats.toml { };
cfgFile = format.generate "00-default.conf" cfg.settings;
in
{
imports = [
@ -13,7 +16,7 @@ in
];
meta = {
maintainers = lib.teams.podman.members;
maintainers = teams.podman.members;
};
options.virtualisation.cri-o = {
@ -55,7 +58,7 @@ in
extraPackages = mkOption {
type = with types; listOf package;
default = [ ];
example = lib.literalExample ''
example = literalExample ''
[
pkgs.gvisor
]
@ -65,7 +68,7 @@ in
'';
};
package = lib.mkOption {
package = mkOption {
type = types.package;
default = crioPackage;
internal = true;
@ -80,6 +83,15 @@ in
description = "Override the network_dir option.";
internal = true;
};
settings = mkOption {
type = format.type;
default = { };
description = ''
Configuration for cri-o, see
<link xlink:href="https://github.com/cri-o/cri-o/blob/master/docs/crio.conf.5.md"/>.
'';
};
};
config = mkIf cfg.enable {
@ -87,36 +99,38 @@ in
environment.etc."crictl.yaml".source = utils.copyFile "${pkgs.cri-o-unwrapped.src}/crictl.yaml";
environment.etc."crio/crio.conf.d/00-default.conf".text = ''
[crio]
storage_driver = "${cfg.storageDriver}"
virtualisation.cri-o.settings.crio = {
storage_driver = cfg.storageDriver;
[crio.image]
${optionalString (cfg.pauseImage != null) ''pause_image = "${cfg.pauseImage}"''}
${optionalString (cfg.pauseCommand != null) ''pause_command = "${cfg.pauseCommand}"''}
image = {
pause_image = mkIf (cfg.pauseImage != null) cfg.pauseImage;
pause_command = mkIf (cfg.pauseCommand != null) cfg.pauseCommand;
};
[crio.network]
plugin_dirs = ["${pkgs.cni-plugins}/bin/"]
${optionalString (cfg.networkDir != null) ''network_dir = "${cfg.networkDir}"''}
network = {
plugin_dirs = [ "${pkgs.cni-plugins}/bin" ];
network_dir = mkIf (cfg.networkDir != null) cfg.networkDir;
};
[crio.runtime]
cgroup_manager = "systemd"
log_level = "${cfg.logLevel}"
pinns_path = "${cfg.package}/bin/pinns"
hooks_dir = [
${lib.optionalString config.virtualisation.containers.ociSeccompBpfHook.enable
''"${config.boot.kernelPackages.oci-seccomp-bpf-hook}",''}
]
runtime = {
cgroup_manager = "systemd";
log_level = cfg.logLevel;
manage_ns_lifecycle = true;
pinns_path = "${cfg.package}/bin/pinns";
hooks_dir =
optional (config.virtualisation.containers.ociSeccompBpfHook.enable)
config.boot.kernelPackages.oci-seccomp-bpf-hook;
${optionalString (cfg.runtime != null) ''
default_runtime = "${cfg.runtime}"
[crio.runtime.runtimes]
[crio.runtime.runtimes.${cfg.runtime}]
''}
'';
default_runtime = mkIf (cfg.runtime != null) cfg.runtime;
runtimes = mkIf (cfg.runtime != null) {
"${cfg.runtime}" = { };
};
};
};
environment.etc."cni/net.d/10-crio-bridge.conf".source = utils.copyFile "${pkgs.cri-o-unwrapped.src}/contrib/cni/10-crio-bridge.conf";
environment.etc."cni/net.d/99-loopback.conf".source = utils.copyFile "${pkgs.cri-o-unwrapped.src}/contrib/cni/99-loopback.conf";
environment.etc."crio/crio.conf.d/00-default.conf".source = cfgFile;
# Enable common /etc/containers configuration
virtualisation.containers.enable = true;
@ -139,6 +153,7 @@ in
TimeoutStartSec = "0";
Restart = "on-abnormal";
};
restartTriggers = [ cfgFile ];
};
};
}

View File

@ -31,6 +31,30 @@ let
example = literalExample "pkgs.dockerTools.buildDockerImage {...};";
};
login = {
username = mkOption {
type = with types; nullOr str;
default = null;
description = "Username for login.";
};
passwordFile = mkOption {
type = with types; nullOr str;
default = null;
description = "Path to file containing password.";
example = "/etc/nixos/dockerhub-password.txt";
};
registry = mkOption {
type = with types; nullOr str;
default = null;
description = "Registry where to login to.";
example = "https://docker.pkg.github.com";
};
};
cmd = mkOption {
type = with types; listOf str;
default = [];
@ -220,6 +244,8 @@ let
};
};
isValidLogin = login: login.username != null && login.passwordFile != null && login.registry != null;
mkService = name: container: let
dependsOn = map (x: "${cfg.backend}-${x}.service") container.dependsOn;
in {
@ -235,6 +261,13 @@ let
preStart = ''
${cfg.backend} rm -f ${name} || true
${optionalString (isValidLogin container.login) ''
cat ${container.login.passwordFile} | \
${cfg.backend} login \
${container.login.registry} \
--username ${container.login.username} \
--password-stdin
''}
${optionalString (container.imageFile != null) ''
${cfg.backend} load -i ${container.imageFile}
''}

View File

@ -56,5 +56,7 @@ in
${open-vm-tools}/bin/vmware-user-suid-wrapper
'';
};
services.udev.packages = [ open-vm-tools ];
};
}

View File

@ -2,6 +2,7 @@ import ./make-test-python.nix ({ pkgs, ... }:
let
hello-world = pkgs.writeText "hello-world" ''
{-# OPTIONS --guardedness #-}
open import IO
open import Level
@ -35,10 +36,6 @@ in
machine.succeed("touch TestEmpty.agda")
machine.succeed("agda TestEmpty.agda")
# Minimal script that actually uses the standard library
machine.succeed('echo "import IO" > TestIO.agda')
machine.succeed("agda -l standard-library -i . TestIO.agda")
# Hello world
machine.succeed(
"cp ${hello-world} HelloWorld.agda"

View File

@ -43,7 +43,7 @@ in
bitcoind = handleTest ./bitcoind.nix {};
bittorrent = handleTest ./bittorrent.nix {};
blockbook-frontend = handleTest ./blockbook-frontend.nix {};
boot = handleTestOn ["x86_64-linux"] ./boot.nix {}; # syslinux is unsupported on aarch64
boot = handleTestOn ["x86_64-linux" "aarch64-linux"] ./boot.nix {};
boot-stage1 = handleTest ./boot-stage1.nix {};
borgbackup = handleTest ./borgbackup.nix {};
botamusique = handleTest ./botamusique.nix {};
@ -174,6 +174,7 @@ in
hitch = handleTest ./hitch {};
hledger-web = handleTest ./hledger-web.nix {};
hocker-fetchdocker = handleTest ./hocker-fetchdocker {};
hockeypuck = handleTest ./hockeypuck.nix { };
home-assistant = handleTest ./home-assistant.nix {};
hostname = handleTest ./hostname.nix {};
hound = handleTest ./hound.nix {};
@ -203,6 +204,7 @@ in
k3s = handleTest ./k3s.nix {};
kafka = handleTest ./kafka.nix {};
kbd-setfont-decompress = handleTest ./kbd-setfont-decompress.nix {};
kea = handleTest ./kea.nix {};
keepalived = handleTest ./keepalived.nix {};
keepassxc = handleTest ./keepassxc.nix {};
kerberos = handleTest ./kerberos/default.nix {};
@ -295,6 +297,7 @@ in
nginx-sandbox = handleTestOn ["x86_64-linux"] ./nginx-sandbox.nix {};
nginx-sso = handleTest ./nginx-sso.nix {};
nginx-variants = handleTest ./nginx-variants.nix {};
nix-serve = handleTest ./nix-ssh-serve.nix {};
nix-ssh-serve = handleTest ./nix-ssh-serve.nix {};
nixos-generate-config = handleTest ./nixos-generate-config.nix {};
nomad = handleTest ./nomad.nix {};
@ -421,6 +424,7 @@ in
taskserver = handleTest ./taskserver.nix {};
telegraf = handleTest ./telegraf.nix {};
tiddlywiki = handleTest ./tiddlywiki.nix {};
tigervnc = handleTest ./tigervnc.nix {};
timezone = handleTest ./timezone.nix {};
tinc = handleTest ./tinc {};
tinydns = handleTest ./tinydns.nix {};
@ -436,6 +440,7 @@ in
txredisapi = handleTest ./txredisapi.nix {};
tuptime = handleTest ./tuptime.nix {};
turbovnc-headless-server = handleTest ./turbovnc-headless-server.nix {};
tuxguitar = handleTest ./tuxguitar.nix {};
ucarp = handleTest ./ucarp.nix {};
ucg = handleTest ./ucg.nix {};
udisks2 = handleTest ./udisks2.nix {};
@ -450,6 +455,7 @@ in
vaultwarden = handleTest ./vaultwarden.nix {};
vector = handleTest ./vector.nix {};
victoriametrics = handleTest ./victoriametrics.nix {};
vikunja = handleTest ./vikunja.nix {};
virtualbox = handleTestOn ["x86_64-linux"] ./virtualbox.nix {};
vscodium = handleTest ./vscodium.nix {};
wasabibackend = handleTest ./wasabibackend.nix {};

View File

@ -4,6 +4,7 @@
}:
with import ../lib/testing-python.nix { inherit system pkgs; };
with import ../lib/qemu-flags.nix { inherit pkgs; };
with pkgs.lib;
let
@ -21,7 +22,10 @@ let
makeBootTest = name: extraConfig:
let
machineConfig = pythonDict ({ qemuFlags = "-m 768"; } // extraConfig);
machineConfig = pythonDict ({
qemuBinary = qemuBinary pkgs.qemu_test;
qemuFlags = "-m 768";
} // extraConfig);
in
makeTest {
inherit iso;
@ -61,6 +65,7 @@ let
];
};
machineConfig = pythonDict ({
qemuBinary = qemuBinary pkgs.qemu_test;
qemuFlags = "-boot order=n -m 2000";
netBackendArgs = "tftp=${ipxeBootDir},bootfile=netboot.ipxe";
} // extraConfig);
@ -75,8 +80,27 @@ let
machine.shutdown()
'';
};
uefiBinary = {
x86_64-linux = "${pkgs.OVMF.fd}/FV/OVMF.fd";
aarch64-linux = "${pkgs.OVMF.fd}/FV/QEMU_EFI.fd";
}.${pkgs.stdenv.hostPlatform.system};
in {
uefiCdrom = makeBootTest "uefi-cdrom" {
cdrom = "${iso}/iso/${iso.isoName}";
bios = uefiBinary;
};
uefiUsb = makeBootTest "uefi-usb" {
usb = "${iso}/iso/${iso.isoName}";
bios = uefiBinary;
};
uefiNetboot = makeNetbootTest "uefi" {
bios = uefiBinary;
# Custom ROM is needed for EFI PXE boot. I failed to understand exactly why, because QEMU should still use iPXE for EFI.
netFrontendArgs = "romfile=${pkgs.ipxe}/ipxe.efirom";
};
} // optionalAttrs (pkgs.stdenv.hostPlatform.system == "x86_64-linux") {
biosCdrom = makeBootTest "bios-cdrom" {
cdrom = "${iso}/iso/${iso.isoName}";
};
@ -85,21 +109,5 @@ in {
usb = "${iso}/iso/${iso.isoName}";
};
uefiCdrom = makeBootTest "uefi-cdrom" {
cdrom = "${iso}/iso/${iso.isoName}";
bios = "${pkgs.OVMF.fd}/FV/OVMF.fd";
};
uefiUsb = makeBootTest "uefi-usb" {
usb = "${iso}/iso/${iso.isoName}";
bios = "${pkgs.OVMF.fd}/FV/OVMF.fd";
};
biosNetboot = makeNetbootTest "bios" {};
uefiNetboot = makeNetbootTest "uefi" {
bios = "${pkgs.OVMF.fd}/FV/OVMF.fd";
# Custom ROM is needed for EFI PXE boot. I failed to understand exactly why, because QEMU should still use iPXE for EFI.
netFrontendArgs = "romfile=${pkgs.ipxe}/ipxe.efirom";
};
}

View File

@ -30,7 +30,10 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
machine.imports = [ ./common/user-account.nix ./common/x11.nix ];
machine.virtualisation.memorySize = 2047;
machine.test-support.displayManager.auto.user = user;
machine.environment.systemPackages = [ chromiumPkg ];
machine.environment = {
systemPackages = [ chromiumPkg ];
variables."XAUTHORITY" = "/home/alice/.Xauthority";
};
startupHTML = pkgs.writeText "chromium-startup.html" ''
<!DOCTYPE html>
@ -63,17 +66,28 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
return "su - ${user} -c " + shlex.quote(cmd)
def get_browser_binary():
"""Returns the name of the browser binary."""
def launch_browser():
"""Launches the web browser with the correct options."""
# Determine the name of the binary:
pname = "${getName chromiumPkg.name}"
if pname.find("chromium") != -1:
return "chromium" # Same name for all channels and ungoogled-chromium
if pname == "google-chrome":
return "google-chrome-stable"
if pname == "google-chrome-dev":
return "google-chrome-unstable"
# For google-chrome-beta and as fallback:
return pname
binary = "chromium" # Same name for all channels and ungoogled-chromium
elif pname == "google-chrome":
binary = "google-chrome-stable"
elif pname == "google-chrome-dev":
binary = "google-chrome-unstable"
else: # For google-chrome-beta and as fallback:
binary = pname
# Add optional CLI options:
options = []
# Launch the process:
options.append("file://${startupHTML}")
machine.succeed(ru(f'ulimit -c unlimited; {binary} {shlex.join(options)} & disown'))
if binary.startswith("google-chrome"):
# Need to click away the first window:
machine.wait_for_text("Make Google Chrome the default browser")
machine.screenshot("google_chrome_default_browser_prompt")
machine.send_key("ret")
def create_new_win():
@ -124,24 +138,32 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
@contextmanager
def test_new_win(description):
def test_new_win(description, url, window_name):
create_new_win()
machine.wait_for_window("New Tab")
machine.send_chars(f"{url}\n")
machine.wait_for_window(window_name)
machine.screenshot(description)
machine.succeed(
ru(
"${xdo "copy-all" ''
key --delay 1000 Ctrl+a Ctrl+c
''}"
)
)
clipboard = machine.succeed(
ru("${pkgs.xclip}/bin/xclip -o")
)
print(f"{description} window content:\n{clipboard}")
with machine.nested(description):
yield
yield clipboard
# Close the newly created window:
machine.send_key("ctrl-w")
machine.wait_for_x()
url = "file://${startupHTML}"
machine.succeed(ru(f'ulimit -c unlimited; "{get_browser_binary()}" "{url}" & disown'))
if get_browser_binary().startswith("google-chrome"):
# Need to click away the first window:
machine.wait_for_text("Make Google Chrome the default browser")
machine.screenshot("google_chrome_default_browser_prompt")
machine.send_key("ret")
launch_browser()
machine.wait_for_text("startup done")
machine.wait_until_succeeds(
@ -164,49 +186,7 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
machine.screenshot("startup_done")
with test_new_win("check sandbox"):
machine.succeed(
ru(
"${xdo "type-url" ''
search --sync --onlyvisible --name "New Tab"
windowfocus --sync
type --delay 1000 "chrome://sandbox"
''}"
)
)
machine.succeed(
ru(
"${xdo "submit-url" ''
search --sync --onlyvisible --name "New Tab"
windowfocus --sync
key --delay 1000 Return
''}"
)
)
machine.screenshot("sandbox_info")
machine.succeed(
ru(
"${xdo "find-window" ''
search --sync --onlyvisible --name "Sandbox Status"
windowfocus --sync
''}"
)
)
machine.succeed(
ru(
"${xdo "copy-sandbox-info" ''
key --delay 1000 Ctrl+a Ctrl+c
''}"
)
)
clipboard = machine.succeed(
ru("${pkgs.xclip}/bin/xclip -o")
)
with test_new_win("sandbox_info", "chrome://sandbox", "Sandbox Status") as clipboard:
filters = [
"layer 1 sandbox.*namespace",
"pid namespaces.*yes",
@ -253,6 +233,22 @@ mapAttrs (channel: chromiumPkg: makeTest rec {
machine.screenshot("after_copy_from_chromium")
with test_new_win("gpu_info", "chrome://gpu", "chrome://gpu"):
# To check the text rendering (catches regressions like #131074):
machine.wait_for_text("Graphics Feature Status")
with test_new_win("version_info", "chrome://version", "About Version") as clipboard:
filters = [
r"${chromiumPkg.version} \(Official Build",
]
if not all(
re.search(filter, clipboard) for filter in filters
):
assert False, "Version info not correct."
machine.shutdown()
'';
}) channelMap

View File

@ -40,7 +40,7 @@ import ./make-test-python.nix ({ pkgs, ... }: {
assert task_name == "Test Task"
machine.succeed("curl -sSfI http://localhost/api/tasks 2>&1 | grep '401 Unauthorized'")
machine.succeed("curl -sSI http://localhost/api/tasks 2>&1 | grep '401 Unauthorized'")
machine.shutdown()
'';

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